diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2014-03-30 22:08:13 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2014-03-30 22:08:13 +0000 |
| commit | e89cc6cbd6be19a70fb12d7c357a728f42f325ee (patch) | |
| tree | 7d843e6d22d5e22cd753c2da443d9ecdcb65b62b /src | |
| parent | clang-format bspline lpe files (diff) | |
| parent | Added "Gtk::" scope to "manage" function calls. (diff) | |
| download | inkscape-e89cc6cbd6be19a70fb12d7c357a728f42f325ee.tar.gz inkscape-e89cc6cbd6be19a70fb12d7c357a728f42f325ee.zip | |
update to trunk
(bzr r11950.1.317)
Diffstat (limited to 'src')
73 files changed, 2574 insertions, 1992 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c34bd2e62..e1e0afa79 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -369,7 +369,6 @@ set(inkscape_SRC message.h mod360-test.h mod360.h - modifier-fns.h number-opt-number.h object-edit.h object-hierarchy.h diff --git a/src/Makefile_insert b/src/Makefile_insert index 5ff44b253..8872b045d 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -94,7 +94,6 @@ ink_common_sources += \ message.h \ message-stack.cpp message-stack.h \ mod360.cpp mod360.h \ - modifier-fns.h \ object-edit.cpp object-edit.h \ object-hierarchy.cpp object-hierarchy.h \ object-snapper.cpp object-snapper.h \ diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index 858312f5b..312a8d655 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -141,7 +141,7 @@ attach_all(Gtk::Table &table, Gtk::Widget const *const arr[], unsigned size, int Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); #endif } else { - Gtk::HBox *space = manage (new Gtk::HBox); + Gtk::HBox *space = Gtk::manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); #if WITH_GTKMM_3_0 space->set_halign(Gtk::ALIGN_CENTER); diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index 3c4ad9b00..4b1dbd1ed 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -469,7 +469,7 @@ static inline void attach_all(Gtk::Table &table, Gtk::Widget const *const arr[], Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); #endif } else { - Gtk::HBox *space = manage (new Gtk::HBox); + Gtk::HBox *space = Gtk::manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); #if WITH_GTKMM_3_0 space->set_halign(Gtk::ALIGN_CENTER); diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index 8a0d7ee26..ee4c1bc8c 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -803,7 +803,7 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui m.unSetup(); if (s.getSnapped()) { p = s.getPoint(); - sp_knot_moveto (knot, p); + knot->moveto(p); } } else if (state & GDK_CONTROL_MASK) { IntermSnapResults isr; @@ -888,7 +888,7 @@ static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, gui } //p = isr.points.front().getPoint(); p = bsp.getPoint(); - sp_knot_moveto (knot, p); + knot->moveto(p); } drag->keep_selection = (bool) g_list_find(drag->selected, dragger); @@ -989,8 +989,6 @@ static void gr_midpoint_limits(GrDragger *dragger, SPObject *server, Geom::Point *high_lim = dragger->point - (highest_dragger->point - *end); } - - /** * Called when a midpoint knot is dragged. */ @@ -1046,7 +1044,7 @@ static void gr_knot_moved_midpoint_handler(SPKnot */*knot*/, Geom::Point const & } } drg->point += this_move; - sp_knot_moveto (drgknot, drg->point); + drgknot->moveto(drg->point); drg->fireDraggables (false); drg->updateDependencies(false); } @@ -1388,7 +1386,7 @@ GrDragger::updateHandles ( Geom::Point pc_old, MeshNodeOperation op ) GrDragger *handle = drag->getDraggerFor( item, POINT_MG_HANDLE, i, fill_or_stroke ); SPKnot *knot = handle->knot; Geom::Point pk = getGradientCoords( item, POINT_MG_HANDLE, i, fill_or_stroke ); - sp_knot_moveto( knot, pk ); + knot->moveto(pk); } @@ -1397,7 +1395,7 @@ GrDragger::updateHandles ( Geom::Point pc_old, MeshNodeOperation op ) GrDragger *handle = drag->getDraggerFor( item, POINT_MG_TENSOR, i, fill_or_stroke ); SPKnot *knot = handle->knot; Geom::Point pk = getGradientCoords( item, POINT_MG_TENSOR, i, fill_or_stroke ); - sp_knot_moveto( knot, pk ); + knot->moveto(pk); } @@ -1483,7 +1481,7 @@ void GrDragger::moveThisToDraggable(SPItem *item, GrPointType point_type, gint p this->point = getGradientCoords(dr_first->item, dr_first->point_type, dr_first->point_i, dr_first->fill_or_stroke); this->point_original = this->point; - sp_knot_moveto(this->knot, this->point); + this->knot->moveto(this->point); for (GSList const* i = draggables; i != NULL; i = i->next) { GrDraggable *da = (GrDraggable *) i->data; @@ -1593,15 +1591,15 @@ GrDragger::GrDragger(GrDrag *parent, Geom::Point p, GrDraggable *draggable) this->parent = parent; // create the knot - this->knot = sp_knot_new (parent->desktop, NULL); + this->knot = new SPKnot(parent->desktop, NULL); this->knot->setMode(SP_KNOT_MODE_XOR); this->knot->setFill(GR_KNOT_COLOR_NORMAL, GR_KNOT_COLOR_MOUSEOVER, GR_KNOT_COLOR_MOUSEOVER); this->knot->setStroke(0x0000007f, 0x0000007f, 0x0000007f); - sp_knot_update_ctrl(this->knot); + this->knot->updateCtrl(); // move knot to the given point - sp_knot_set_position (this->knot, p, SP_KNOT_STATE_NORMAL); - sp_knot_show (this->knot); + this->knot->setPosition(p, SP_KNOT_STATE_NORMAL); + this->knot->show(); // connect knot's signals if ( (draggable) // it can be NULL if a node in unsnapped (eg. focus point unsnapped from center) @@ -1610,18 +1608,21 @@ GrDragger::GrDragger(GrDrag *parent, Geom::Point p, GrDraggable *draggable) || (draggable->point_type == POINT_RG_MID1) || (draggable->point_type == POINT_RG_MID2) ) ) { - this->handler_id = g_signal_connect (G_OBJECT (this->knot), "moved", G_CALLBACK (gr_knot_moved_midpoint_handler), this); + this->_moved_connection = this->knot->moved_signal.connect(sigc::bind(sigc::ptr_fun(gr_knot_moved_midpoint_handler), this)); } else { - this->handler_id = g_signal_connect (G_OBJECT (this->knot), "moved", G_CALLBACK (gr_knot_moved_handler), this); + this->_moved_connection = this->knot->moved_signal.connect(sigc::bind(sigc::ptr_fun(gr_knot_moved_handler), this)); } - g_signal_connect (G_OBJECT (this->knot), "clicked", G_CALLBACK (gr_knot_clicked_handler), this); - g_signal_connect (G_OBJECT (this->knot), "doubleclicked", G_CALLBACK (gr_knot_doubleclicked_handler), this); - g_signal_connect (G_OBJECT (this->knot), "grabbed", G_CALLBACK (gr_knot_grabbed_handler), this); - g_signal_connect (G_OBJECT (this->knot), "ungrabbed", G_CALLBACK (gr_knot_ungrabbed_handler), this); + + this->_clicked_connection = this->knot->click_signal.connect(sigc::bind(sigc::ptr_fun(gr_knot_clicked_handler), this)); + this->_doubleclicked_connection = this->knot->doubleclicked_signal.connect(sigc::bind(sigc::ptr_fun(gr_knot_doubleclicked_handler), this)); + this->_grabbed_connection = this->knot->grabbed_signal.connect(sigc::bind(sigc::ptr_fun(gr_knot_grabbed_handler), this)); + this->_ungrabbed_connection = this->knot->ungrabbed_signal.connect(sigc::bind(sigc::ptr_fun(gr_knot_ungrabbed_handler), this)); // add the initial draggable - if (draggable) + if (draggable) { this->addDraggable (draggable); + } + updateKnotShape(); } @@ -1634,19 +1635,20 @@ GrDragger::~GrDragger() //this->parent->setDeselected(this); // disconnect signals - g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (gr_knot_moved_handler), this); - g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (gr_knot_clicked_handler), this); - g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (gr_knot_doubleclicked_handler), this); - g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (gr_knot_grabbed_handler), this); - g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (gr_knot_ungrabbed_handler), this); + this->_moved_connection.disconnect(); + this->_clicked_connection.disconnect(); + this->_doubleclicked_connection.disconnect(); + this->_grabbed_connection.disconnect(); + this->_ungrabbed_connection.disconnect(); /* unref should call destroy */ - g_object_unref (G_OBJECT (this->knot)); + knot_unref(this->knot); // delete all draggables for (GSList const* i = this->draggables; i != NULL; i = i->next) { delete ((GrDraggable *) i->data); } + g_slist_free (this->draggables); this->draggables = NULL; } @@ -2043,7 +2045,7 @@ void GrDrag::addDraggersMesh(SPMeshGradient *mg, SPItem *item, Inkscape::PaintTa void GrDrag::grabKnot(GrDragger *dragger, gint x, gint y, guint32 etime) { if (dragger) { - sp_knot_start_dragging (dragger->knot, dragger->point, x, y, etime); + dragger->knot->startDragging(dragger->point, x, y, etime); } } @@ -2055,7 +2057,7 @@ void GrDrag::grabKnot(SPItem *item, GrPointType point_type, gint point_i, Inksca { GrDragger *dragger = getDraggerFor(item, point_type, point_i, fill_or_stroke); if (dragger) { - sp_knot_start_dragging (dragger->knot, dragger->point, x, y, etime); + dragger->knot->startDragging(dragger->point, x, y, etime); } } @@ -2358,7 +2360,7 @@ void GrDrag::selected_move(double x, double y, bool write_repr, bool scale_radia Geom::Point p_old = d->point; d->point += Geom::Point (x, y); d->point_original = d->point; - sp_knot_moveto (d->knot, d->point); + d->knot->moveto(d->point); d->fireDraggables (write_repr, scale_radial); d->updateHandles( p_old, MG_NODE_NO_SCALE ); @@ -2394,7 +2396,7 @@ void GrDrag::selected_move(double x, double y, bool write_repr, bool scale_radia GrDragger *drg = (GrDragger*) i->data; SPKnot *drgknot = drg->knot; drg->point += displacement; - sp_knot_moveto (drgknot, drg->point); + drgknot->moveto(drg->point); drg->fireDraggables (true); drg->updateDependencies(true); did = true; diff --git a/src/gradient-drag.h b/src/gradient-drag.h index 4ed13b9f7..964ea8093 100644 --- a/src/gradient-drag.h +++ b/src/gradient-drag.h @@ -28,7 +28,7 @@ #include "sp-gradient.h" // TODO refactor enums to external .h file #include "sp-mesh-array.h" -struct SPKnot; +class SPKnot; class SPDesktop; class SPCSSAttr; @@ -86,9 +86,6 @@ struct GrDragger { // position of the knot before it began to drag; updated when released Geom::Point point_original; - /** Connection to \a knot's "moved" signal, for blocking it (unused?). */ - guint handler_id; - GSList *draggables; void addDraggable(GrDraggable *draggable); @@ -117,6 +114,13 @@ struct GrDragger { bool isA(SPItem *item, GrPointType point_type, gint point_i, Inkscape::PaintTarget fill_or_stroke); void fireDraggables(bool write_repr, bool scale_radial = false, bool merging_focus = false); + +private: + sigc::connection _moved_connection; + sigc::connection _clicked_connection; + sigc::connection _doubleclicked_connection; + sigc::connection _grabbed_connection; + sigc::connection _ungrabbed_connection; }; /** diff --git a/src/interface.cpp b/src/interface.cpp index 6eb1b6a5a..1cbeb44a3 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -1524,7 +1524,7 @@ ContextMenu::~ContextMenu(void) Gtk::SeparatorMenuItem* ContextMenu::AddSeparator(void) { - Gtk::SeparatorMenuItem* sep = manage(new Gtk::SeparatorMenuItem()); + Gtk::SeparatorMenuItem* sep = Gtk::manage(new Gtk::SeparatorMenuItem()); sep->show(); append(*sep); return sep; @@ -1556,7 +1556,7 @@ void ContextMenu::AppendItemFromVerb(Inkscape::Verb *verb)//, SPDesktop *view)// return; } - Gtk::ImageMenuItem *item = manage(new Gtk::ImageMenuItem(action->name, true)); + Gtk::ImageMenuItem *item = Gtk::manage(new Gtk::ImageMenuItem(action->name, true)); sp_shortcut_add_accelerator(GTK_WIDGET(item->gobj()), sp_shortcut_get_primary(verb)); @@ -1638,7 +1638,7 @@ void ContextMenu::MakeItemMenu (void) Gtk::MenuItem* mi; /* Item dialog */ - mi = manage(new Gtk::MenuItem(_("_Object Properties..."),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("_Object Properties..."),1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ItemProperties)); mi->show(); append(*mi);//insert(*mi,positionOfLastDialog++); @@ -1647,7 +1647,7 @@ void ContextMenu::MakeItemMenu (void) /* Select item */ if (Inkscape::Verb::getbyid( "org.inkscape.followlink" )) { - mi = manage(new Gtk::MenuItem(_("_Select This"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("_Select This"), 1)); if (_desktop->selection->includes(_item)) { mi->set_sensitive(FALSE); } else { @@ -1658,9 +1658,9 @@ void ContextMenu::MakeItemMenu (void) } - mi = manage(new Gtk::MenuItem(_("Select Same"))); + mi = Gtk::manage(new Gtk::MenuItem(_("Select Same"))); mi->show(); - Gtk::Menu *select_same_submenu = manage(new Gtk::Menu()); + Gtk::Menu *select_same_submenu = Gtk::manage(new Gtk::Menu()); if (_desktop->selection->isEmpty()) { mi->set_sensitive(FALSE); } @@ -1668,42 +1668,42 @@ void ContextMenu::MakeItemMenu (void) append(*mi); /* Select same fill and stroke */ - mi = manage(new Gtk::MenuItem(_("Fill and Stroke"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Fill and Stroke"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameFillStroke)); mi->set_sensitive(!SP_IS_ANCHOR(_item)); mi->show(); select_same_submenu->append(*mi); /* Select same fill color */ - mi = manage(new Gtk::MenuItem(_("Fill Color"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Fill Color"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameFillColor)); mi->set_sensitive(!SP_IS_ANCHOR(_item)); mi->show(); select_same_submenu->append(*mi); /* Select same stroke color */ - mi = manage(new Gtk::MenuItem(_("Stroke Color"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Stroke Color"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameStrokeColor)); mi->set_sensitive(!SP_IS_ANCHOR(_item)); mi->show(); select_same_submenu->append(*mi); /* Select same stroke style */ - mi = manage(new Gtk::MenuItem(_("Stroke Style"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Stroke Style"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameStrokeStyle)); mi->set_sensitive(!SP_IS_ANCHOR(_item)); mi->show(); select_same_submenu->append(*mi); /* Select same stroke style */ - mi = manage(new Gtk::MenuItem(_("Object type"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Object type"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SelectSameObjectType)); mi->set_sensitive(!SP_IS_ANCHOR(_item)); mi->show(); select_same_submenu->append(*mi); /* Move to layer */ - mi = manage(new Gtk::MenuItem(_("_Move to layer ..."),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("_Move to layer ..."), 1)); if (_desktop->selection->isEmpty()) { mi->set_sensitive(FALSE); } else { @@ -1713,7 +1713,7 @@ void ContextMenu::MakeItemMenu (void) append(*mi); /* Create link */ - mi = manage(new Gtk::MenuItem(_("Create _Link"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Create _Link"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ItemCreateLink)); mi->set_sensitive(!SP_IS_ANCHOR(_item)); mi->show(); @@ -1736,7 +1736,7 @@ void ContextMenu::MakeItemMenu (void) } } /* Set mask */ - mi = manage(new Gtk::MenuItem(_("Set Mask"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Set Mask"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SetMask)); if (ClipRefOK || MaskRefOK) { mi->set_sensitive(FALSE); @@ -1747,7 +1747,7 @@ void ContextMenu::MakeItemMenu (void) append(*mi); /* Release mask */ - mi = manage(new Gtk::MenuItem(_("Release Mask"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Release Mask"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ReleaseMask)); if (MaskRefOK) { mi->set_sensitive(TRUE); @@ -1758,7 +1758,7 @@ void ContextMenu::MakeItemMenu (void) append(*mi); /* Set Clip */ - mi = manage(new Gtk::MenuItem(_("Set Cl_ip"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Set Cl_ip"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SetClip)); if (ClipRefOK || MaskRefOK) { mi->set_sensitive(FALSE); @@ -1769,7 +1769,7 @@ void ContextMenu::MakeItemMenu (void) append(*mi); /* Release Clip */ - mi = manage(new Gtk::MenuItem(_("Release C_lip"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Release C_lip"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ReleaseClip)); if (ClipRefOK) { mi->set_sensitive(TRUE); @@ -1780,7 +1780,7 @@ void ContextMenu::MakeItemMenu (void) append(*mi); /* Group */ - mi = manage(new Gtk::MenuItem(_("_Group"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("_Group"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ActivateGroup)); if (_desktop->selection->isEmpty() || _desktop->selection->single()) { mi->set_sensitive(FALSE); @@ -1882,7 +1882,7 @@ void ContextMenu::ReleaseClip(void) void ContextMenu::MakeGroupMenu(void) { /* Ungroup */ - Gtk::MenuItem* mi = manage(new Gtk::MenuItem(_("_Ungroup"),1)); + Gtk::MenuItem* mi = Gtk::manage(new Gtk::MenuItem(_("_Ungroup"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ActivateUngroup)); mi->show(); append(*mi); @@ -1907,19 +1907,19 @@ void ContextMenu::MakeAnchorMenu(void) Gtk::MenuItem* mi; /* Link dialog */ - mi = manage(new Gtk::MenuItem(_("Link _Properties..."),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Link _Properties..."), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::AnchorLinkProperties)); mi->show(); insert(*mi,positionOfLastDialog++); /* Select item */ - mi = manage(new Gtk::MenuItem(_("_Follow Link"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("_Follow Link"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::AnchorLinkFollow)); mi->show(); append(*mi); /* Reset transformations */ - mi = manage(new Gtk::MenuItem(_("_Remove Link"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("_Remove Link"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::AnchorLinkRemove)); mi->show(); append(*mi); @@ -1961,13 +1961,13 @@ void ContextMenu::MakeImageMenu (void) const gchar *href = ir->attribute("xlink:href"); /* Image properties */ - mi = manage(new Gtk::MenuItem(_("Image _Properties..."),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Image _Properties..."), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageProperties)); mi->show(); insert(*mi,positionOfLastDialog++); /* Edit externally */ - mi = manage(new Gtk::MenuItem(_("Edit Externally..."),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Edit Externally..."), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageEdit)); mi->show(); insert(*mi,positionOfLastDialog++); @@ -1976,7 +1976,7 @@ void ContextMenu::MakeImageMenu (void) } /* Trace Bitmap */ - mi = manage(new Gtk::MenuItem(_("_Trace Bitmap..."),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("_Trace Bitmap..."), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageTraceBitmap)); mi->show(); insert(*mi,positionOfLastDialog++); @@ -1985,7 +1985,7 @@ void ContextMenu::MakeImageMenu (void) } /* Trace Pixel Art */ - mi = manage(new Gtk::MenuItem(_("Trace Pixel Art"),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Trace Pixel Art"), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageTracePixelArt)); mi->show(); insert(*mi,positionOfLastDialog++); @@ -1995,7 +1995,7 @@ void ContextMenu::MakeImageMenu (void) /* Embed image */ if (Inkscape::Verb::getbyid( "org.ekips.filter.embedselectedimages" )) { - mi = manage(new Gtk::MenuItem(C_("Context menu", "Embed Image"))); + mi = Gtk::manage(new Gtk::MenuItem(C_("Context menu", "Embed Image"))); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageEmbed)); mi->show(); insert(*mi,positionOfLastDialog++); @@ -2006,7 +2006,7 @@ void ContextMenu::MakeImageMenu (void) /* Extract image */ if (Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" )) { - mi = manage(new Gtk::MenuItem(C_("Context menu", "Extract Image..."))); + mi = Gtk::manage(new Gtk::MenuItem(C_("Context menu", "Extract Image..."))); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::ImageExtract)); mi->show(); insert(*mi,positionOfLastDialog++); @@ -2151,7 +2151,7 @@ void ContextMenu::MakeShapeMenu (void) Gtk::MenuItem* mi; /* Item dialog */ - mi = manage(new Gtk::MenuItem(_("_Fill and Stroke..."),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("_Fill and Stroke..."), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::FillSettings)); mi->show(); insert(*mi,positionOfLastDialog++); @@ -2171,19 +2171,19 @@ void ContextMenu::MakeTextMenu (void) Gtk::MenuItem* mi; /* Fill and Stroke dialog */ - mi = manage(new Gtk::MenuItem(_("_Fill and Stroke..."),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("_Fill and Stroke..."), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::FillSettings)); mi->show(); insert(*mi,positionOfLastDialog++); /* Edit Text dialog */ - mi = manage(new Gtk::MenuItem(_("_Text and Font..."),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("_Text and Font..."), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::TextSettings)); mi->show(); insert(*mi,positionOfLastDialog++); /* Spellcheck dialog */ - mi = manage(new Gtk::MenuItem(_("Check Spellin_g..."),1)); + mi = Gtk::manage(new Gtk::MenuItem(_("Check Spellin_g..."), 1)); mi->signal_activate().connect(sigc::mem_fun(*this, &ContextMenu::SpellcheckSettings)); mi->show(); insert(*mi,positionOfLastDialog++); diff --git a/src/io/inkjar.cpp b/src/io/inkjar.cpp index 4af140737..b31b98336 100644 --- a/src/io/inkjar.cpp +++ b/src/io/inkjar.cpp @@ -68,7 +68,7 @@ JarFile::JarFile(gchar const*new_filename) { _filename = g_strdup(new_filename); _last_filename = NULL; - fd = -1; + fd = NULL; } //fixme: the following should probably just return a const gchar* and not @@ -104,7 +104,7 @@ bool JarFile::init_inflation() bool JarFile::open() { - if ((fd = ::open(_filename, O_RDONLY)) < 0) { + if ((fd = fopen(_filename, "r")) < 0) { fprintf(stderr, "open failed.\n"); return false; } @@ -116,7 +116,7 @@ bool JarFile::open() bool JarFile::close() { - if (fd >= 0 && !::close(fd)) { + if (fd >= 0 && !fclose(fd)) { inflateEnd(&_zs); return true; } @@ -257,7 +257,7 @@ GByteArray *JarFile::get_next_file_contents() if (method == 8 || flags & 0x0008) { unsigned int file_length = 0;//uncompressed file length - lseek(fd, eflen, SEEK_CUR); + fseek(fd, eflen, SEEK_CUR); guint8 *file_data = get_compressed_file(compressed_size, file_length, crc, flags); if (file_data == NULL) { @@ -275,7 +275,7 @@ GByteArray *JarFile::get_next_file_contents() } g_byte_array_append(gba, file_data, compressed_size); } else { - lseek(fd, compressed_size+eflen, SEEK_CUR); + fseek(fd, compressed_size+eflen, SEEK_CUR); g_byte_array_free(gba, FALSE); return NULL; } @@ -314,7 +314,7 @@ guint8 *JarFile::get_uncompressed_file(guint32 compressed_size, guint32 crc, std::printf("%u bytes written\n", out_a); #endif } - lseek(fd, eflen, SEEK_CUR); + fseek(fd, eflen, SEEK_CUR); g_free(bytes); if (!check_crc(crc, crc2, flags)) { @@ -329,7 +329,7 @@ guint8 *JarFile::get_uncompressed_file(guint32 compressed_size, guint32 crc, int JarFile::read(guint8 *buf, int count) { int nbytes; - if ((nbytes = ::read(fd, buf, count)) != count) { + if ((nbytes = fread(buf, 1, count, fd)) != count) { fprintf(stderr, "read error\n"); exit(1); return 0; @@ -358,8 +358,8 @@ guint8 *JarFile::get_compressed_file(guint32 compressed_size, if (!_zs.avail_in) { - if ((nbytes = ::read(fd, in_buffer, - (leftover_in < RDSZ ? leftover_in : RDSZ))) + if ((nbytes = fread(in_buffer, 1, + (leftover_in < RDSZ ? leftover_in : RDSZ), fd)) < 0) { fprintf(stderr, "jarfile read error"); } diff --git a/src/io/inkjar.h b/src/io/inkjar.h index ea4b0ee32..ee6e33526 100644 --- a/src/io/inkjar.h +++ b/src/io/inkjar.h @@ -27,6 +27,7 @@ #endif #include <glib.h> +#include <cstdio> namespace Inkjar { @@ -87,11 +88,10 @@ typedef uint32_t ub4; * * All memory allocations are done with g_malloc. */ - class JarFile { public: - JarFile() : fd(-1), _filename(NULL), _last_filename(NULL) {} + JarFile() : fd(NULL), _filename(NULL), _last_filename(NULL) {} virtual ~JarFile(); JarFile(gchar const *new_filename); @@ -106,7 +106,7 @@ public: private: - int fd; + FILE *fd; // File descriptor gchar *_filename; z_stream _zs; gchar *_last_filename; diff --git a/src/knot-holder-entity.cpp b/src/knot-holder-entity.cpp index 043685460..6471124ec 100644 --- a/src/knot-holder-entity.cpp +++ b/src/knot-holder-entity.cpp @@ -34,7 +34,7 @@ void KnotHolderEntity::create(SPDesktop *desktop, SPItem *item, KnotHolder *pare const gchar *tip, SPKnotShapeType shape, SPKnotModeType mode, guint32 color) { - knot = sp_knot_new(desktop, tip); + knot = new SPKnot(desktop, tip); this->parent_holder = parent; this->item = item; // TODO: remove the item either from here or from knotholder.cpp @@ -52,11 +52,11 @@ void KnotHolderEntity::create(SPDesktop *desktop, SPItem *item, KnotHolder *pare g_object_set (G_OBJECT(knot->item), "fill_color", color, NULL); update_knot(); - sp_knot_show(knot); + knot->show(); - _moved_connection = knot->_moved_signal.connect(sigc::mem_fun(*parent_holder, &KnotHolder::knot_moved_handler)); - _click_connection = knot->_click_signal.connect(sigc::mem_fun(*parent_holder, &KnotHolder::knot_clicked_handler)); - _ungrabbed_connection = knot->_ungrabbed_signal.connect(sigc::mem_fun(*parent_holder, &KnotHolder::knot_ungrabbed_handler)); + _moved_connection = knot->moved_signal.connect(sigc::mem_fun(*parent_holder, &KnotHolder::knot_moved_handler)); + _click_connection = knot->click_signal.connect(sigc::mem_fun(*parent_holder, &KnotHolder::knot_clicked_handler)); + _ungrabbed_connection = knot->ungrabbed_signal.connect(sigc::mem_fun(*parent_holder, &KnotHolder::knot_ungrabbed_handler)); } @@ -68,7 +68,8 @@ KnotHolderEntity::~KnotHolderEntity() /* unref should call destroy */ if (knot) { - g_object_unref(knot); + //g_object_unref(knot); + knot_unref(knot); } else { // FIXME: This shouldn't occur. Perhaps it is caused by LPE PointParams being knotholder entities, too // If so, it will likely be fixed with upcoming refactoring efforts. @@ -84,7 +85,7 @@ KnotHolderEntity::update_knot() Geom::Point dp(knot_get() * i2dt); _moved_connection.block(); - sp_knot_set_position(knot, dp, SP_KNOT_STATE_NORMAL); + knot->setPosition(dp, SP_KNOT_STATE_NORMAL); _moved_connection.unblock(); } diff --git a/src/knot-holder-entity.h b/src/knot-holder-entity.h index a4e6528cf..a9268d396 100644 --- a/src/knot-holder-entity.h +++ b/src/knot-holder-entity.h @@ -20,9 +20,8 @@ #include "snapper.h" #include "display/sp-canvas-item.h" -class SPItem; -struct SPKnot; - +class SPItem; +class SPKnot; class SPDesktop; class KnotHolder; @@ -84,6 +83,7 @@ public: /** Connection to \a knot's "ungrabbed" signal. */ guint _ungrab_handler_id; +private: sigc::connection _moved_connection; sigc::connection _click_connection; sigc::connection _ungrabbed_connection; diff --git a/src/knot.cpp b/src/knot.cpp index 2179bc3d5..61d0dff39 100644 --- a/src/knot.cpp +++ b/src/knot.cpp @@ -17,7 +17,6 @@ #endif #include <gdk/gdkkeysyms.h> #include <glibmm/i18n.h> -#include "helper/sp-marshal.h" #include "display/sodipodi-ctrl.h" #include "desktop.h" #include "desktop-handles.h" @@ -36,10 +35,11 @@ using Inkscape::DocumentUndo; GDK_POINTER_MOTION_HINT_MASK | \ GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK) -static bool nograb = false; +const gchar *nograbenv = getenv("INKSCAPE_NO_GRAB"); +static bool nograb = (nograbenv && *nograbenv && (*nograbenv != '0')); -static bool grabbed = FALSE; -static bool moved = FALSE; +static bool grabbed = false; +static bool moved = false; static gint xp = 0, yp = 0; // where drag started static gint tolerance = 0; @@ -47,247 +47,138 @@ static bool within_tolerance = false; static bool transform_escaped = false; // true iff resize or rotate was cancelled by esc. -enum { - EVENT, - CLICKED, - DOUBLECLICKED, - GRABBED, - UNGRABBED, - MOVED, - REQUEST, - DISTANCE, - LAST_SIGNAL -}; - -static void sp_knot_class_init(SPKnotClass *klass); -static void sp_knot_init(SPKnot *knot); -static void sp_knot_dispose(GObject *object); +void knot_ref(SPKnot* knot) { + knot->ref_count++; +} + +void knot_unref(SPKnot* knot) { + if (--knot->ref_count < 1) { + delete knot; + } +} -static int sp_knot_handler(SPCanvasItem *item, GdkEvent *event, SPKnot *knot); -static void sp_knot_set_ctrl_state(SPKnot *knot); -static GObjectClass *parent_class; -static guint knot_signals[LAST_SIGNAL] = { 0 }; +static int sp_knot_handler(SPCanvasItem *item, GdkEvent *event, SPKnot *knot); -GType sp_knot_get_type() +SPKnot::SPKnot(SPDesktop *desktop, gchar const *tip) + : ref_count(1) { - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPKnotClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) sp_knot_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (SPKnot), - 16, /* n_preallocs */ - (GInstanceInitFunc) sp_knot_init, - NULL - }; - type = g_type_register_static (G_TYPE_OBJECT, "SPKnot", &info, (GTypeFlags) 0); + this->desktop = NULL; + this->item = NULL; + this->owner = NULL; + this->flags = 0; + + this->size = 8; + this->pos = Geom::Point(0, 0); + this->grabbed_rel_pos = Geom::Point(0, 0); + this->anchor = SP_ANCHOR_CENTER; + this->shape = SP_KNOT_SHAPE_SQUARE; + this->mode = SP_KNOT_MODE_XOR; + this->tip = NULL; + this->_event_handler_id = 0; + this->pressure = 0; + + this->fill[SP_KNOT_STATE_NORMAL] = 0xffffff00; + this->fill[SP_KNOT_STATE_MOUSEOVER] = 0xff0000ff; + this->fill[SP_KNOT_STATE_DRAGGING] = 0x0000ffff; + + this->stroke[SP_KNOT_STATE_NORMAL] = 0x01000000; + this->stroke[SP_KNOT_STATE_MOUSEOVER] = 0x01000000; + this->stroke[SP_KNOT_STATE_DRAGGING] = 0x01000000; + + this->image[SP_KNOT_STATE_NORMAL] = NULL; + this->image[SP_KNOT_STATE_MOUSEOVER] = NULL; + this->image[SP_KNOT_STATE_DRAGGING] = NULL; + + this->cursor[SP_KNOT_STATE_NORMAL] = NULL; + this->cursor[SP_KNOT_STATE_MOUSEOVER] = NULL; + this->cursor[SP_KNOT_STATE_DRAGGING] = NULL; + + this->saved_cursor = NULL; + this->pixbuf = NULL; + + + this->desktop = desktop; + this->flags = SP_KNOT_VISIBLE; + + if (tip) { + this->tip = g_strdup (tip); } - return type; -} -/** - * SPKnot vtable initialization. - */ -static void sp_knot_class_init(SPKnotClass *klass) -{ - GObjectClass *object_class = (GObjectClass*)klass; - - parent_class = (GObjectClass*) g_type_class_peek_parent(klass); - - object_class->dispose = sp_knot_dispose; - - knot_signals[EVENT] = g_signal_new("event", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(SPKnotClass, event), - NULL, NULL, - sp_marshal_BOOLEAN__POINTER, - G_TYPE_BOOLEAN, 1, - GDK_TYPE_EVENT); - - knot_signals[CLICKED] = g_signal_new("clicked", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(SPKnotClass, clicked), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); - - knot_signals[DOUBLECLICKED] = g_signal_new("doubleclicked", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(SPKnotClass, doubleclicked), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); - - knot_signals[GRABBED] = g_signal_new("grabbed", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(SPKnotClass, grabbed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); - - knot_signals[UNGRABBED] = g_signal_new("ungrabbed", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(SPKnotClass, ungrabbed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); - - knot_signals[MOVED] = g_signal_new("moved", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET(SPKnotClass, moved), - NULL, NULL, - sp_marshal_NONE__POINTER_UINT, - G_TYPE_NONE, 2, - G_TYPE_POINTER, G_TYPE_UINT); - - knot_signals[REQUEST] = g_signal_new("request", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(SPKnotClass, request), - NULL, NULL, - sp_marshal_BOOLEAN__POINTER_UINT, - G_TYPE_BOOLEAN, 2, - G_TYPE_POINTER, G_TYPE_UINT); - - knot_signals[DISTANCE] = g_signal_new("distance", - G_TYPE_FROM_CLASS(klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(SPKnotClass, distance), - NULL, NULL, - sp_marshal_DOUBLE__POINTER_UINT, - G_TYPE_DOUBLE, 2, - G_TYPE_POINTER, G_TYPE_UINT); - - const gchar *nograbenv = getenv("INKSCAPE_NO_GRAB"); - nograb = (nograbenv && *nograbenv && (*nograbenv != '0')); -} + this->item = sp_canvas_item_new(sp_desktop_controls (desktop), + SP_TYPE_CTRL, + "anchor", SP_ANCHOR_CENTER, + "size", 8.0, + "filled", TRUE, + "fill_color", 0xffffff00, + "stroked", TRUE, + "stroke_color", 0x01000000, + "mode", SP_KNOT_MODE_XOR, + NULL); -/** - * Callback for SPKnot initialization. - */ -static void sp_knot_init(SPKnot *knot) -{ - knot->desktop = NULL; - knot->item = NULL; - knot->owner = NULL; - knot->flags = 0; - - knot->size = 8; - knot->pos = Geom::Point(0, 0); - knot->grabbed_rel_pos = Geom::Point(0, 0); - knot->anchor = SP_ANCHOR_CENTER; - knot->shape = SP_KNOT_SHAPE_SQUARE; - knot->mode = SP_KNOT_MODE_XOR; - knot->tip = NULL; - knot->_event_handler_id = 0; - knot->pressure = 0; - - knot->fill[SP_KNOT_STATE_NORMAL] = 0xffffff00; - knot->fill[SP_KNOT_STATE_MOUSEOVER] = 0xff0000ff; - knot->fill[SP_KNOT_STATE_DRAGGING] = 0x0000ffff; - - knot->stroke[SP_KNOT_STATE_NORMAL] = 0x01000000; - knot->stroke[SP_KNOT_STATE_MOUSEOVER] = 0x01000000; - knot->stroke[SP_KNOT_STATE_DRAGGING] = 0x01000000; - - knot->image[SP_KNOT_STATE_NORMAL] = NULL; - knot->image[SP_KNOT_STATE_MOUSEOVER] = NULL; - knot->image[SP_KNOT_STATE_DRAGGING] = NULL; - - knot->cursor[SP_KNOT_STATE_NORMAL] = NULL; - knot->cursor[SP_KNOT_STATE_MOUSEOVER] = NULL; - knot->cursor[SP_KNOT_STATE_DRAGGING] = NULL; - - knot->saved_cursor = NULL; - knot->pixbuf = NULL; + this->_event_handler_id = g_signal_connect(G_OBJECT(this->item), "event", + G_CALLBACK(sp_knot_handler), this); } -/** - * Called before SPKnot destruction. - */ -static void sp_knot_dispose(GObject *object) -{ - SPKnot *knot = static_cast<SPKnot *>(object); - +SPKnot::~SPKnot() { #if GTK_CHECK_VERSION(3,0,0) GdkDisplay *display = gdk_display_get_default(); GdkDeviceManager *dm = gdk_display_get_device_manager(display); GdkDevice *device = gdk_device_manager_get_client_pointer(dm); - if ((knot->flags & SP_KNOT_GRABBED) && gdk_display_device_is_grabbed(display, device)) { + if ((this->flags & SP_KNOT_GRABBED) && gdk_display_device_is_grabbed(display, device)) { // This happens e.g. when deleting a node in node tool while dragging it gdk_device_ungrab(device, GDK_CURRENT_TIME); } #else - if ((knot->flags & SP_KNOT_GRABBED) && gdk_pointer_is_grabbed ()) { + if ((this->flags & SP_KNOT_GRABBED) && gdk_pointer_is_grabbed ()) { // This happens e.g. when deleting a node in node tool while dragging it gdk_pointer_ungrab (GDK_CURRENT_TIME); } #endif - if (knot->_event_handler_id > 0) - { - g_signal_handler_disconnect(G_OBJECT (knot->item), knot->_event_handler_id); - knot->_event_handler_id = 0; - } + if (this->_event_handler_id > 0) { + g_signal_handler_disconnect(G_OBJECT (this->item), this->_event_handler_id); + this->_event_handler_id = 0; + } - if (knot->item) { - sp_canvas_item_destroy(knot->item); - knot->item = NULL; + if (this->item) { + sp_canvas_item_destroy(this->item); + this->item = NULL; } for (gint i = 0; i < SP_KNOT_VISIBLE_STATES; i++) { - if (knot->cursor[i]) { + if (this->cursor[i]) { #if GTK_CHECK_VERSION(3,0,0) - g_object_unref(knot->cursor[i]); + g_object_unref(this->cursor[i]); #else - gdk_cursor_unref(knot->cursor[i]); + gdk_cursor_unref(this->cursor[i]); #endif - knot->cursor[i] = NULL; + this->cursor[i] = NULL; } } - if (knot->tip) { - g_free(knot->tip); - knot->tip = NULL; - } - - if (parent_class->dispose) { - (*parent_class->dispose) (object); + if (this->tip) { + g_free(this->tip); + this->tip = NULL; } } -void sp_knot_start_dragging(SPKnot *knot, Geom::Point const &p, gint x, gint y, guint32 etime) -{ +void SPKnot::startDragging(Geom::Point const &p, gint x, gint y, guint32 etime) { // save drag origin xp = x; yp = y; within_tolerance = true; - knot->grabbed_rel_pos = p - knot->pos; - knot->drag_origin = knot->pos; + this->grabbed_rel_pos = p - this->pos; + this->drag_origin = this->pos; + if (!nograb) { - sp_canvas_item_grab(knot->item, - KNOT_EVENT_MASK, - knot->cursor[SP_KNOT_STATE_DRAGGING], - etime); + sp_canvas_item_grab(this->item, KNOT_EVENT_MASK, this->cursor[SP_KNOT_STATE_DRAGGING], etime); } - sp_knot_set_flag(knot, SP_KNOT_GRABBED, TRUE); + + this->setFlag(SP_KNOT_GRABBED, TRUE); + grabbed = TRUE; } @@ -300,23 +191,21 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot g_assert(SP_IS_KNOT(knot)); /* Run client universal event handler, if present */ - - gboolean consumed = FALSE; - - g_signal_emit(knot, knot_signals[EVENT], 0, event, &consumed); + bool consumed = knot->event_signal.emit(knot, event); if (consumed) { - return TRUE; + return true; } - g_object_ref(knot); + knot_ref(knot); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); switch (event->type) { case GDK_2BUTTON_PRESS: if (event->button.button == 1) { - g_signal_emit(knot, knot_signals[DOUBLECLICKED], 0, event->button.state); + knot->doubleclicked_signal.emit(knot, event->button.state); grabbed = FALSE; moved = FALSE; @@ -326,7 +215,8 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot case GDK_BUTTON_PRESS: if ((event->button.button == 1) && knot->desktop && knot->desktop->event_context && !knot->desktop->event_context->space_panning) { Geom::Point const p = knot->desktop->w2d(Geom::Point(event->button.x, event->button.y)); - sp_knot_start_dragging(knot, p, (gint) event->button.x, (gint) event->button.y, event->button.time); + knot->startDragging(p, (gint) event->button.x, (gint) event->button.y, event->button.time); + consumed = TRUE; } break; @@ -340,28 +230,25 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot sp_event_context_discard_delayed_snap_event(knot->desktop->event_context); knot->pressure = 0; + if (transform_escaped) { transform_escaped = false; consumed = TRUE; } else { - sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); + knot->setFlag(SP_KNOT_GRABBED, FALSE); + if (!nograb) { sp_canvas_item_ungrab(knot->item, event->button.time); } + if (moved) { - sp_knot_set_flag(knot, - SP_KNOT_DRAGGING, - FALSE); - g_signal_emit(knot, - knot_signals[UNGRABBED], 0, - event->button.state); - knot->_ungrabbed_signal.emit(knot); + knot->setFlag(SP_KNOT_DRAGGING, FALSE); + + knot->ungrabbed_signal.emit(knot, event->button.state); } else { - g_signal_emit(knot, - knot_signals[CLICKED], 0, - event->button.state); - knot->_click_signal.emit(knot, event->button.state); + knot->click_signal.emit(knot, event->button.state); } + grabbed = FALSE; moved = FALSE; consumed = TRUE; @@ -383,27 +270,26 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot // motion notify coordinates as given (no snapping back to origin) within_tolerance = false; - if (gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &knot->pressure)) + if (gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &knot->pressure)) { knot->pressure = CLAMP (knot->pressure, 0, 1); - else + } else { knot->pressure = 0.5; + } if (!moved) { - g_signal_emit(knot, - knot_signals[GRABBED], 0, - event->motion.state); - sp_knot_set_flag(knot, - SP_KNOT_DRAGGING, - TRUE); + knot->grabbed_signal.emit(knot, event->motion.state); + + knot->setFlag(SP_KNOT_DRAGGING, TRUE); } + sp_event_context_snap_delay_handler(knot->desktop->event_context, NULL, (gpointer) knot, (GdkEventMotion *)event, Inkscape::UI::Tools::DelayedSnapEvent::KNOT_HANDLER); sp_knot_handler_request_position(event, knot); moved = TRUE; } break; case GDK_ENTER_NOTIFY: - sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, TRUE); - sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); + knot->setFlag(SP_KNOT_MOUSEOVER, TRUE); + knot->setFlag(SP_KNOT_GRABBED, FALSE); if (knot->tip && knot->desktop && knot->desktop->event_context) { knot->desktop->event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, knot->tip); @@ -414,8 +300,8 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot consumed = TRUE; break; case GDK_LEAVE_NOTIFY: - sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, FALSE); - sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); + knot->setFlag(SP_KNOT_MOUSEOVER, FALSE); + knot->setFlag(SP_KNOT_GRABBED, FALSE); if (knot->tip && knot->desktop && knot->desktop->event_context) { knot->desktop->event_context->defaultMessageContext()->clear(); @@ -428,24 +314,26 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot case GDK_KEY_PRESS: // keybindings for knot switch (Inkscape::UI::Tools::get_group0_keyval(&event->key)) { case GDK_KEY_Escape: - sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); + knot->setFlag(SP_KNOT_GRABBED, FALSE); + if (!nograb) { sp_canvas_item_ungrab(knot->item, event->button.time); } + if (moved) { - sp_knot_set_flag(knot, - SP_KNOT_DRAGGING, - FALSE); - g_signal_emit(knot, - knot_signals[UNGRABBED], 0, - event->button.state); + knot->setFlag(SP_KNOT_DRAGGING, FALSE); + + knot->ungrabbed_signal.emit(knot, event->button.state); + DocumentUndo::undo(sp_desktop_document(knot->desktop)); knot->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Node or handle drag canceled.")); transform_escaped = true; consumed = TRUE; } + grabbed = FALSE; moved = FALSE; + sp_event_context_discard_delayed_snap_event(knot->desktop->event_context); break; default: @@ -457,164 +345,82 @@ static int sp_knot_handler(SPCanvasItem */*item*/, GdkEvent *event, SPKnot *knot break; } - g_object_unref(knot); + knot_unref(knot); return consumed || grabbed; } -void sp_knot_handler_request_position(GdkEvent *event, SPKnot *knot) -{ +void sp_knot_handler_request_position(GdkEvent *event, SPKnot *knot) { Geom::Point const motion_w(event->motion.x, event->motion.y); Geom::Point const motion_dt = knot->desktop->w2d(motion_w); Geom::Point p = motion_dt - knot->grabbed_rel_pos; - sp_knot_request_position (knot, p, event->motion.state); + + knot->requestPosition(p, event->motion.state); knot->desktop->scroll_to_point (motion_dt); knot->desktop->set_coordinate_status(knot->pos); // display the coordinate of knot, not cursor - they may be different! - if (event->motion.state & GDK_BUTTON1_MASK) - Inkscape::UI::Tools::gobble_motion_events(GDK_BUTTON1_MASK); -} -SPKnot *sp_knot_new(SPDesktop *desktop, const gchar *tip) -{ - g_return_val_if_fail(desktop != NULL, NULL); - - SPKnot * knot = static_cast<SPKnot*>(g_object_new(SP_TYPE_KNOT, 0)); - - knot->desktop = desktop; - knot->flags = SP_KNOT_VISIBLE; - if (tip) { - knot->tip = g_strdup (tip); + if (event->motion.state & GDK_BUTTON1_MASK) { + Inkscape::UI::Tools::gobble_motion_events(GDK_BUTTON1_MASK); } - - knot->item = sp_canvas_item_new(sp_desktop_controls (desktop), - SP_TYPE_CTRL, - "anchor", SP_ANCHOR_CENTER, - "size", 8.0, - "filled", TRUE, - "fill_color", 0xffffff00, - "stroked", TRUE, - "stroke_color", 0x01000000, - "mode", SP_KNOT_MODE_XOR, - NULL); - - knot->_event_handler_id = g_signal_connect(G_OBJECT(knot->item), "event", - G_CALLBACK(sp_knot_handler), knot); - - return knot; } -void sp_knot_show(SPKnot *knot) -{ - g_return_if_fail(knot != NULL); - g_return_if_fail(SP_IS_KNOT (knot)); - - sp_knot_set_flag(knot, SP_KNOT_VISIBLE, TRUE); +void SPKnot::show() { + this->setFlag(SP_KNOT_VISIBLE, TRUE); } -void sp_knot_hide(SPKnot *knot) -{ - g_return_if_fail(knot != NULL); - g_return_if_fail(SP_IS_KNOT(knot)); - - sp_knot_set_flag(knot, SP_KNOT_VISIBLE, FALSE); +void SPKnot::hide() { + this->setFlag(SP_KNOT_VISIBLE, FALSE); } -void sp_knot_request_position(SPKnot *knot, Geom::Point const &p, guint state) -{ - g_return_if_fail(knot != NULL); - g_return_if_fail(SP_IS_KNOT(knot)); - - gboolean done = FALSE; - - g_signal_emit(knot, - knot_signals[REQUEST], 0, - &p, - state, - &done); +void SPKnot::requestPosition(Geom::Point const &p, guint state) { + bool done = this->request_signal.emit(this, &const_cast<Geom::Point&>(p), state); /* If user did not complete, we simply move knot to new position */ - if (!done) { - sp_knot_set_position (knot, p, state); + this->setPosition(p, state); } } -gdouble sp_knot_distance(SPKnot * knot, Geom::Point const &p, guint state) -{ - g_return_val_if_fail(knot != NULL, 1e18); - g_return_val_if_fail(SP_IS_KNOT(knot), 1e18); +void SPKnot::setPosition(Geom::Point const &p, guint state) { + this->pos = p; - gdouble distance = Geom::L2(p - knot->pos); - - g_signal_emit(knot, - knot_signals[DISTANCE], 0, - &p, - state, - &distance); - - return distance; -} - -void sp_knot_set_position(SPKnot *knot, Geom::Point const &p, guint state) -{ - g_return_if_fail(knot != NULL); - g_return_if_fail(SP_IS_KNOT (knot)); - - knot->pos = p; - - if (knot->item) { - SP_CTRL(knot->item)->moveto (p); + if (this->item) { + SP_CTRL(this->item)->moveto(p); } - g_signal_emit(knot, - knot_signals[MOVED], 0, - &p, - state); - knot->_moved_signal.emit(knot, p, state); + this->moved_signal.emit(this, p, state); } -void sp_knot_moveto(SPKnot *knot, Geom::Point const &p) -{ - g_return_if_fail(knot != NULL); - g_return_if_fail(SP_IS_KNOT(knot)); +void SPKnot::moveto(Geom::Point const &p) { + this->pos = p; - knot->pos = p; - - if (knot->item) { - SP_CTRL(knot->item)->moveto (p); + if (this->item) { + SP_CTRL(this->item)->moveto(p); } } -Geom::Point sp_knot_position(SPKnot const *knot) -{ - g_assert(knot != NULL); - g_assert(SP_IS_KNOT (knot)); - - return knot->pos; +Geom::Point SPKnot::position() const { + return this->pos; } -void sp_knot_set_flag(SPKnot *knot, guint flag, bool set) -{ - g_assert(knot != NULL); - g_assert(SP_IS_KNOT(knot)); - +void SPKnot::setFlag(guint flag, bool set) { if (set) { - knot->flags |= flag; + this->flags |= flag; } else { - knot->flags &= ~flag; + this->flags &= ~flag; } switch (flag) { case SP_KNOT_VISIBLE: if (set) { - sp_canvas_item_show(knot->item); + sp_canvas_item_show(this->item); } else { - sp_canvas_item_hide(knot->item); + sp_canvas_item_hide(this->item); } break; case SP_KNOT_MOUSEOVER: case SP_KNOT_DRAGGING: - sp_knot_set_ctrl_state(knot); + this->_setCtrlState(); break; case SP_KNOT_GRABBED: break; @@ -624,39 +430,130 @@ void sp_knot_set_flag(SPKnot *knot, guint flag, bool set) } } -void sp_knot_update_ctrl(SPKnot *knot) -{ - if (!knot->item) { +void SPKnot::updateCtrl() { + if (!this->item) { return; } - g_object_set(knot->item, "shape", knot->shape, NULL); - g_object_set(knot->item, "mode", knot->mode, NULL); - g_object_set(knot->item, "size", (gdouble) knot->size, NULL); - g_object_set(knot->item, "anchor", knot->anchor, NULL); - if (knot->pixbuf) { - g_object_set(knot->item, "pixbuf", knot->pixbuf, NULL); + g_object_set(this->item, "shape", this->shape, NULL); + g_object_set(this->item, "mode", this->mode, NULL); + g_object_set(this->item, "size", (gdouble) this->size, NULL); + g_object_set(this->item, "anchor", this->anchor, NULL); + + if (this->pixbuf) { + g_object_set(this->item, "pixbuf", this->pixbuf, NULL); } - sp_knot_set_ctrl_state(knot); + this->_setCtrlState(); } -/** - * Set knot control state (dragging/mouseover/normal). - */ -static void sp_knot_set_ctrl_state(SPKnot *knot) -{ +void SPKnot::_setCtrlState() { int state = SP_KNOT_STATE_NORMAL; - if (knot->flags & SP_KNOT_DRAGGING) { + + if (this->flags & SP_KNOT_DRAGGING) { state = SP_KNOT_STATE_DRAGGING; - } else if (knot->flags & SP_KNOT_MOUSEOVER) { + } else if (this->flags & SP_KNOT_MOUSEOVER) { state = SP_KNOT_STATE_MOUSEOVER; } - g_object_set(knot->item, "fill_color", knot->fill[state], NULL); - g_object_set(knot->item, "stroke_color", knot->stroke[state], NULL); + + g_object_set(this->item, "fill_color", this->fill[state], NULL); + g_object_set(this->item, "stroke_color", this->stroke[state], NULL); +} + + +void SPKnot::setSize(guint i) { + size = i; } +void SPKnot::setShape(guint i) { + shape = (SPKnotShapeType) i; +} + +void SPKnot::setAnchor(guint i) { + anchor = (SPAnchorType) i; +} + +void SPKnot::setMode(guint i) { + mode = (SPKnotModeType) i; +} +void SPKnot::setPixbuf(gpointer p) { + pixbuf = p; +} + +void SPKnot::setFill(guint32 normal, guint32 mouseover, guint32 dragging) { + fill[SP_KNOT_STATE_NORMAL] = normal; + fill[SP_KNOT_STATE_MOUSEOVER] = mouseover; + fill[SP_KNOT_STATE_DRAGGING] = dragging; +} + +void SPKnot::setStroke(guint32 normal, guint32 mouseover, guint32 dragging) { + stroke[SP_KNOT_STATE_NORMAL] = normal; + stroke[SP_KNOT_STATE_MOUSEOVER] = mouseover; + stroke[SP_KNOT_STATE_DRAGGING] = dragging; +} + +void SPKnot::setImage(guchar* normal, guchar* mouseover, guchar* dragging) { + image[SP_KNOT_STATE_NORMAL] = normal; + image[SP_KNOT_STATE_MOUSEOVER] = mouseover; + image[SP_KNOT_STATE_DRAGGING] = dragging; +} + +void SPKnot::setCursor(GdkCursor* normal, GdkCursor* mouseover, GdkCursor* dragging) { + if (cursor[SP_KNOT_STATE_NORMAL]) { +#if GTK_CHECK_VERSION(3,0,0) + g_object_unref(cursor[SP_KNOT_STATE_NORMAL]); +#else + gdk_cursor_unref(cursor[SP_KNOT_STATE_NORMAL]); +#endif + } + + cursor[SP_KNOT_STATE_NORMAL] = normal; + + if (normal) { +#if GTK_CHECK_VERSION(3,0,0) + g_object_ref(normal); +#else + gdk_cursor_ref(normal); +#endif + } + + if (cursor[SP_KNOT_STATE_MOUSEOVER]) { +#if GTK_CHECK_VERSION(3,0,0) + g_object_unref(cursor[SP_KNOT_STATE_MOUSEOVER]); +#else + gdk_cursor_unref(cursor[SP_KNOT_STATE_MOUSEOVER]); +#endif + } + + cursor[SP_KNOT_STATE_MOUSEOVER] = mouseover; + + if (mouseover) { +#if GTK_CHECK_VERSION(3,0,0) + g_object_ref(mouseover); +#else + gdk_cursor_ref(mouseover); +#endif + } + + if (cursor[SP_KNOT_STATE_DRAGGING]) { +#if GTK_CHECK_VERSION(3,0,0) + g_object_unref(cursor[SP_KNOT_STATE_DRAGGING]); +#else + gdk_cursor_unref(cursor[SP_KNOT_STATE_DRAGGING]); +#endif + } + + cursor[SP_KNOT_STATE_DRAGGING] = dragging; + + if (dragging) { +#if GTK_CHECK_VERSION(3,0,0) + g_object_ref(dragging); +#else + gdk_cursor_ref(dragging); +#endif + } +} /* Local Variables: diff --git a/src/knot.h b/src/knot.h index 4d87d703f..b18f89566 100644 --- a/src/knot.h +++ b/src/knot.h @@ -26,11 +26,8 @@ class SPDesktop; struct SPCanvasItem; -#define SP_TYPE_KNOT (sp_knot_get_type()) -#define SP_KNOT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_KNOT, SPKnot)) -#define SP_KNOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SP_TYPE_KNOT, SPKnotClass)) -#define SP_IS_KNOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_KNOT)) -#define SP_IS_KNOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_KNOT)) +#define SP_KNOT(obj) (dynamic_cast<SPKnot*>(static_cast<SPKnot*>(obj))) +#define SP_IS_KNOT(obj) (dynamic_cast<const SPKnot*>(static_cast<const SPKnot*>(obj)) != NULL) /** @@ -39,7 +36,15 @@ struct SPCanvasItem; * A knot is a draggable object, with callbacks to change something by * dragging it, visuably represented by a canvas item (mostly square). */ -struct SPKnot : GObject { +class SPKnot { +public: + SPKnot(SPDesktop *desktop, gchar const *tip); + virtual ~SPKnot(); + + + int ref_count; + + SPDesktop *desktop; /**< Desktop we are on. */ SPCanvasItem *item; /**< Our CanvasItem. */ SPItem *owner; /**< Optional Owner Item */ @@ -69,180 +74,94 @@ struct SPKnot : GObject { double pressure; /**< The tablet pen pressure when the knot is being dragged. */ - // C++ signals - /** - sigc::signal<void, Geom::Point const &, Geom::Point const &, guint> _moved_signal; - sigc::signal<void, guint> _click_signal; - sigc::signal<Geom::Point> _ungrabbed_signal; - **/ - sigc::signal<void, SPKnot *, Geom::Point const &, guint> _moved_signal; - sigc::signal<void, SPKnot *, guint> _click_signal; - sigc::signal<void, SPKnot *> _ungrabbed_signal; + sigc::signal<void, SPKnot *, guint> click_signal; + sigc::signal<void, SPKnot*, guint> doubleclicked_signal; + sigc::signal<void, SPKnot*, guint> grabbed_signal; + sigc::signal<void, SPKnot *, guint> ungrabbed_signal; + sigc::signal<void, SPKnot *, Geom::Point const &, guint> moved_signal; + sigc::signal<bool, SPKnot*, GdkEvent*> event_signal; - //TODO: all the members above should eventualle become private, accessible via setters/getters - inline void setSize (guint i) {size = i;} - inline void setShape (guint i) {shape = (SPKnotShapeType) i;} - inline void setAnchor (guint i) {anchor = (SPAnchorType) i;} - inline void setMode (guint i) {mode = (SPKnotModeType) i;} - inline void setPixbuf (gpointer p) {pixbuf = p;} - inline void setFill (guint32 normal, guint32 mouseover, guint32 dragging) { - fill[SP_KNOT_STATE_NORMAL] = normal; - fill[SP_KNOT_STATE_MOUSEOVER] = mouseover; - fill[SP_KNOT_STATE_DRAGGING] = dragging; - } - inline void setStroke (guint32 normal, guint32 mouseover, guint32 dragging) { - stroke[SP_KNOT_STATE_NORMAL] = normal; - stroke[SP_KNOT_STATE_MOUSEOVER] = mouseover; - stroke[SP_KNOT_STATE_DRAGGING] = dragging; - } - inline void setImage (guchar* normal, guchar* mouseover, guchar* dragging) { - image[SP_KNOT_STATE_NORMAL] = normal; - image[SP_KNOT_STATE_MOUSEOVER] = mouseover; - image[SP_KNOT_STATE_DRAGGING] = dragging; - } - inline void setCursor (GdkCursor* normal, GdkCursor* mouseover, GdkCursor* dragging) { - if (cursor[SP_KNOT_STATE_NORMAL]) { -#if GTK_CHECK_VERSION(3,0,0) - g_object_unref(cursor[SP_KNOT_STATE_NORMAL]); -#else - gdk_cursor_unref(cursor[SP_KNOT_STATE_NORMAL]); -#endif - } - cursor[SP_KNOT_STATE_NORMAL] = normal; - if (normal) { -#if GTK_CHECK_VERSION(3,0,0) - g_object_ref(normal); -#else - gdk_cursor_ref(normal); -#endif - } - - if (cursor[SP_KNOT_STATE_MOUSEOVER]) { -#if GTK_CHECK_VERSION(3,0,0) - g_object_unref(cursor[SP_KNOT_STATE_MOUSEOVER]); -#else - gdk_cursor_unref(cursor[SP_KNOT_STATE_MOUSEOVER]); -#endif - } - cursor[SP_KNOT_STATE_MOUSEOVER] = mouseover; - if (mouseover) { -#if GTK_CHECK_VERSION(3,0,0) - g_object_ref(mouseover); -#else - gdk_cursor_ref(mouseover); -#endif - } - - if (cursor[SP_KNOT_STATE_DRAGGING]) { -#if GTK_CHECK_VERSION(3,0,0) - g_object_unref(cursor[SP_KNOT_STATE_DRAGGING]); -#else - gdk_cursor_unref(cursor[SP_KNOT_STATE_DRAGGING]); -#endif - } - cursor[SP_KNOT_STATE_DRAGGING] = dragging; - if (dragging) { -#if GTK_CHECK_VERSION(3,0,0) - g_object_ref(dragging); -#else - gdk_cursor_ref(dragging); -#endif - } - } - -}; + sigc::signal<bool, SPKnot*, Geom::Point*, guint> request_signal; -/// The SPKnot vtable. -struct SPKnotClass { - GObjectClass parent_class; - gint (* event) (SPKnot *knot, GdkEvent *event); - /* - * These are unconditional. - */ + //TODO: all the members above should eventualle become private, accessible via setters/getters + void setSize(guint i); + void setShape(guint i); + void setAnchor(guint i); + void setMode(guint i); + void setPixbuf(gpointer p); - void (* clicked) (SPKnot *knot, guint state); - void (* doubleclicked) (SPKnot *knot, guint state); - void (* grabbed) (SPKnot *knot, guint state); - void (* ungrabbed) (SPKnot *knot, guint state); - void (* moved) (SPKnot *knot, Geom::Point const &position, guint state); - void (* stamped) (SPKnot *know, guint state); + void setFill(guint32 normal, guint32 mouseover, guint32 dragging); + void setStroke(guint32 normal, guint32 mouseover, guint32 dragging); + void setImage(guchar* normal, guchar* mouseover, guchar* dragging); - /** Request knot to move to absolute position. */ - bool (* request) (SPKnot *knot, Geom::Point const &pos, guint state); + void setCursor(GdkCursor* normal, GdkCursor* mouseover, GdkCursor* dragging); - /** Find complex distance from knot to point. */ - gdouble (* distance) (SPKnot *knot, Geom::Point const &pos, guint state); -}; + /** + * Show knot on its canvas. + */ + void show(); -/** - * Registers SPKnot class and returns its type number. - */ -GType sp_knot_get_type(); + /** + * Hide knot on its canvas. + */ + void hide(); -/** - * Return new knot object. - */ -SPKnot *sp_knot_new(SPDesktop *desktop, gchar const *tip = NULL); + /** + * Set flag in knot, with side effects. + */ + void setFlag(guint flag, bool set); -#define SP_KNOT_IS_VISIBLE(k) ((k->flags & SP_KNOT_VISIBLE) != 0) -#define SP_KNOT_IS_MOUSEOVER(k) ((k->flags & SP_KNOT_MOUSEOVER) != 0) -#define SP_KNOT_IS_DRAGGING(k) ((k->flags & SP_KNOT_DRAGGING) != 0) -#define SP_KNOT_IS_GRABBED(k) ((k->flags & SP_KNOT_GRABBED) != 0) + /** + * Update knot's pixbuf and set its control state. + */ + void updateCtrl(); -/** - * Show knot on its canvas. - */ -void sp_knot_show(SPKnot *knot); + /** + * Request or set new position for knot. + */ + void requestPosition(Geom::Point const &pos, guint state); -/** - * Hide knot on its canvas. - */ -void sp_knot_hide(SPKnot *knot); + /** + * Update knot for dragging and tell canvas an item was grabbed. + */ + void startDragging(Geom::Point const &p, gint x, gint y, guint32 etime); -/** - * Set flag in knot, with side effects. - */ -void sp_knot_set_flag(SPKnot *knot, guint flag, bool set); + /** + * Move knot to new position and emits "moved" signal. + */ + void setPosition(Geom::Point const &p, guint state); -/** - * Update knot's pixbuf and set its control state. - */ -void sp_knot_update_ctrl(SPKnot *knot); + /** + * Move knot to new position, without emitting a MOVED signal. + */ + void moveto(Geom::Point const &p); -/** - * Request or set new position for knot. - */ -void sp_knot_request_position(SPKnot *knot, Geom::Point const &pos, guint state); + /** + * Returns position of knot. + */ + Geom::Point position() const; -/** - * Return distance of point to knot's position; unused. - */ -gdouble sp_knot_distance(SPKnot *knot, Geom::Point const &p, guint state); +private: + SPKnot(SPKnot const&); + SPKnot& operator=(SPKnot const&); -/** - * Update knot for dragging and tell canvas an item was grabbed. - */ -void sp_knot_start_dragging(SPKnot *knot, Geom::Point const &p, gint x, gint y, guint32 etime); + /** + * Set knot control state (dragging/mouseover/normal). + */ + void _setCtrlState(); +}; -/** - * Move knot to new position and emits "moved" signal. - */ -void sp_knot_set_position(SPKnot *knot, Geom::Point const &p, guint state); +void knot_ref(SPKnot* knot); +void knot_unref(SPKnot* knot); -/** - * Move knot to new position, without emitting a MOVED signal. - */ -void sp_knot_moveto(SPKnot *knot, Geom::Point const &p); +#define SP_KNOT_IS_VISIBLE(k) ((k->flags & SP_KNOT_VISIBLE) != 0) +#define SP_KNOT_IS_MOUSEOVER(k) ((k->flags & SP_KNOT_MOUSEOVER) != 0) +#define SP_KNOT_IS_DRAGGING(k) ((k->flags & SP_KNOT_DRAGGING) != 0) +#define SP_KNOT_IS_GRABBED(k) ((k->flags & SP_KNOT_GRABBED) != 0) void sp_knot_handler_request_position(GdkEvent *event, SPKnot *knot); -/** - * Returns position of knot. - */ -Geom::Point sp_knot_position(SPKnot const *knot); - - #endif // SEEN_SP_KNOT_H /* diff --git a/src/knotholder.cpp b/src/knotholder.cpp index bef89f3af..cf87423d4 100644 --- a/src/knotholder.cpp +++ b/src/knotholder.cpp @@ -63,14 +63,12 @@ KnotHolder::KnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFun g_print ("Error! Throw an exception, please!\n"); } - //g_object_ref(G_OBJECT(item)); // TODO: is this still needed after C++-ification? sp_object_ref(item); sizeUpdatedConn = ControlManager::getManager().connectCtrlSizeChanged(sigc::mem_fun(*this, &KnotHolder::updateControlSizes)); } KnotHolder::~KnotHolder() { - //g_object_unref(G_OBJECT(item)); sp_object_unref(item); for (std::list<KnotHolderEntity *>::iterator i = entity.begin(); i != entity.end(); ++i) @@ -187,7 +185,7 @@ KnotHolder::knot_moved_handler(SPKnot *knot, Geom::Point const &p, guint state) } void -KnotHolder::knot_ungrabbed_handler(SPKnot */*knot*/) +KnotHolder::knot_ungrabbed_handler(SPKnot */*knot*/, guint) { this->dragging = false; diff --git a/src/knotholder.h b/src/knotholder.h index fc91a56fc..3632635f5 100644 --- a/src/knotholder.h +++ b/src/knotholder.h @@ -34,7 +34,7 @@ class PowerStrokePointArrayParamKnotHolderEntity; class KnotHolderEntity; class SPItem; class SPDesktop; -struct SPKnot; +class SPKnot; /* fixme: Think how to make callbacks most sensitive (Lauris) */ typedef void (* SPKnotHolderReleasedFunc) (SPItem *item); @@ -48,7 +48,7 @@ public: void knot_moved_handler(SPKnot *knot, Geom::Point const &p, guint state); void knot_clicked_handler(SPKnot *knot, guint state); - void knot_ungrabbed_handler(SPKnot *knot); + void knot_ungrabbed_handler(SPKnot *knot, guint); void add(KnotHolderEntity *e); diff --git a/src/libuemf/uemf.h b/src/libuemf/uemf.h index a75ba801b..cde1b6c85 100644 --- a/src/libuemf/uemf.h +++ b/src/libuemf/uemf.h @@ -95,8 +95,8 @@ these WMF enumerations is by referencing the following table: /* File: uemf.h -Version: 0.0.25 -Date: 15-JAN-2014 +Version: 0.0.26 +Date: 27-MAR-2014 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu Copyright: 2014 David Mathog and California Institute of Technology (Caltech) @@ -129,6 +129,8 @@ extern "C" { #define U_SYSPAL_NOSTATIC 2 #define U_ELF_VENDOR_SIZE 4 + +#define UNUSED_PARAMETER(x) (void)(x) /** \endcond */ // *************************************************************************** diff --git a/src/libuemf/uemf_endian.c b/src/libuemf/uemf_endian.c index 8f2be57da..2d19361e1 100644 --- a/src/libuemf/uemf_endian.c +++ b/src/libuemf/uemf_endian.c @@ -19,8 +19,8 @@ /* File: uemf_endian.c -Version: 0.0.15 -Date: 24-MAR-2014 +Version: 0.0.16 +Date: 27-MAR-2014 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu Copyright: 2014 David Mathog and California Institute of Technology (Caltech) @@ -36,10 +36,6 @@ extern "C" { #include "uemf.h" #include "uemf_endian.h" -// Unfortunately, C does not allow unnamed function arguments, so use this macro instead... -#define UNUSED(x) (void)(x) - - // hide almost everuything in here from Doxygen //! \cond @@ -429,8 +425,7 @@ by end user code and to further that end prototypes are NOT provided and they ar // all core*_swap call this, U_EMRSETMARGN_swap and some others all it directly // numbered as core5 to be consistent with uemf.c, but must appear before the others as there is no prototype void core5_swap(char *record, int torev){ - UNUSED(torev); - + UNUSED_PARAMETER(torev); PU_ENHMETARECORD pEMR = (PU_ENHMETARECORD)(record); U_swap4(pEMR,2); // iType nSize } diff --git a/src/libuemf/upmf.c b/src/libuemf/upmf.c index 3c652c9b8..01f7ba3a4 100644 --- a/src/libuemf/upmf.c +++ b/src/libuemf/upmf.c @@ -21,8 +21,8 @@ /* File: upmf.c -Version: 0.0.5 -Date: 24-MAR-2014 +Version: 0.0.6 +Date: 26-MAR-2014 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu Copyright: 2014 David Mathog and California Institute of Technology (Caltech) diff --git a/src/libuemf/uwmf_endian.c b/src/libuemf/uwmf_endian.c index 5fbb450dc..38a321ad0 100644 --- a/src/libuemf/uwmf_endian.c +++ b/src/libuemf/uwmf_endian.c @@ -6,11 +6,11 @@ /* File: uwmf_endian.c -Version: 0.1.2 -Date: 18-FEB-2013 +Version: 0.1.3 +Date: 27-MAR-2014 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu -Copyright: 2012 David Mathog and California Institute of Technology (Caltech) +Copyright: 2014 David Mathog and California Institute of Technology (Caltech) */ #ifdef __cplusplus @@ -24,8 +24,6 @@ extern "C" { #include "uwmf.h" #include "uwmf_endian.h" -#define UNUSED(x) (void)(x) - // hide almost everything in this file from Doxygen //! \cond /* Prototypes for functions used here and defined in uemf_endian.c, but which are not supposed @@ -284,7 +282,7 @@ by end user code and to further that end prototypes are NOT provided and they ar /* Size16 EVERY record type should call this, directly or indirectly*/ void U_WMRCORE_SIZE16_swap(char *record, int torev){ - UNUSED(torev); + UNUSED_PARAMETER(torev); U_swap4(record, 1); /* Size16_4 is at offset 0 in U_METARECORD */ } @@ -309,7 +307,7 @@ void U_WMRCORE_U16_N16_swap(char *record, int torev){ /* all records that specify palette objects */ void U_WMRCORE_PALETTE_swap(char *record, int torev){ - UNUSED(torev); + UNUSED_PARAMETER(torev); U_WMRCORE_SIZE16_swap(record, torev); palette_swap(record + offsetof(U_WMRANIMATEPALETTE,Palette)); } @@ -702,7 +700,7 @@ void U_WMRDIBCREATEPATTERNBRUSH_swap(char *record, int torev){ } void U_WMRSTRETCHDIB_swap(char *record, int torev){ - UNUSED(torev); + UNUSED_PARAMETER(torev); U_WMRCORE_U32_N16_swap(record,9,torev); dibheader_swap(record + offsetof(U_WMRSTRETCHDIB,dib), torev); } diff --git a/src/main.cpp b/src/main.cpp index 25f813c2b..00d0fcbb6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -925,7 +925,7 @@ namespace Inkscape { namespace UI { namespace Tools { -guint get_group0_keyval(GdkEventKey* event); +guint get_group0_keyval(GdkEventKey const* event); } } diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index de48ea2be..f888555d2 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -215,7 +215,7 @@ static char const menus_skeleton[] = " <separator/>\n" " <verb verb-id=\"DialogTransform\" />\n" " <verb verb-id=\"DialogAlignDistribute\" />\n" -" <verb verb-id=\"DialogGridArrange\" />\n" +" <verb verb-id=\"DialogArrange\" />\n" " </submenu>\n" " <submenu name=\"" N_("_Path") "\">\n" " <verb verb-id=\"ObjectToPath\" />\n" diff --git a/src/modifier-fns.h b/src/modifier-fns.h deleted file mode 100644 index cab110467..000000000 --- a/src/modifier-fns.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef SEEN_MODIFIER_FNS_H -#define SEEN_MODIFIER_FNS_H - -/** \file - * Functions on GdkEventKey.state that test modifier keys. - * - * The MOD__SHIFT macro in macros.h is equivalent to mod_shift(event-\>key.state). - */ - -/* - * Hereby placed in public domain. - */ - -#include <gdk/gdk.h> -#include <glib.h> - -inline bool -mod_shift(guint const state) -{ - return state & GDK_SHIFT_MASK; -} - -inline bool -mod_ctrl(guint const state) -{ - return state & GDK_CONTROL_MASK; -} - -inline bool -mod_alt(guint const state) -{ - return state & GDK_MOD1_MASK; -} - -inline bool -mod_shift_only(guint const state) -{ - return (state & GDK_SHIFT_MASK) && !(state & GDK_CONTROL_MASK) && !(state & GDK_MOD1_MASK); -} - -inline bool -mod_ctrl_only(guint const state) -{ - return !(state & GDK_SHIFT_MASK) && (state & GDK_CONTROL_MASK) && !(state & GDK_MOD1_MASK); -} - -inline bool -mod_alt_only(guint const state) -{ - return !(state & GDK_SHIFT_MASK) && !(state & GDK_CONTROL_MASK) && (state & GDK_MOD1_MASK); -} - -#endif /* !SEEN_MODIFIER_FNS_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 : diff --git a/src/seltrans.cpp b/src/seltrans.cpp index a55bc3c0d..60a0bfa11 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -54,15 +54,15 @@ using Inkscape::ControlManager; using Inkscape::DocumentUndo; -static void sp_sel_trans_handle_grab(SPKnot *knot, guint state, gpointer data); -static void sp_sel_trans_handle_ungrab(SPKnot *knot, guint state, gpointer data); -static void sp_sel_trans_handle_click(SPKnot *knot, guint state, gpointer data); -static void sp_sel_trans_handle_new_event(SPKnot *knot, Geom::Point *position, guint32 state, gpointer data); -static gboolean sp_sel_trans_handle_request(SPKnot *knot, Geom::Point *p, guint state, gboolean *data); +static void sp_sel_trans_handle_grab(SPKnot *knot, guint state, SPSelTransHandle const* data); +static void sp_sel_trans_handle_ungrab(SPKnot *knot, guint state, SPSelTransHandle const* data); +static void sp_sel_trans_handle_click(SPKnot *knot, guint state, SPSelTransHandle const* data); +static void sp_sel_trans_handle_new_event(SPKnot *knot, Geom::Point const &position, guint32 state, SPSelTransHandle const* data); +static gboolean sp_sel_trans_handle_request(SPKnot *knot, Geom::Point *p, guint state, SPSelTransHandle const *data); extern GdkPixbuf *handles[]; -static gboolean sp_sel_trans_handle_event(SPKnot *knot, GdkEvent *event, gpointer) +static gboolean sp_sel_trans_handle_event(SPKnot *knot, GdkEvent *event, SPSelTransHandle const*) { switch (event->type) { case GDK_MOTION_NOTIFY: @@ -186,7 +186,7 @@ Inkscape::SelTrans::~SelTrans() _sel_modified_connection.disconnect(); for (int i = 0; i < NUMHANDS; i++) { - g_object_unref(G_OBJECT(knots[i])); + knot_unref(knots[i]); knots[i] = NULL; } @@ -574,7 +574,7 @@ void Inkscape::SelTrans::stamp() void Inkscape::SelTrans::_updateHandles() { for (int i = 0; i < NUMHANDS; i++) - sp_knot_hide(knots[i]); + knots[i]->hide(); if ( !_show_handles || _empty ) return; @@ -627,13 +627,13 @@ void Inkscape::SelTrans::_showHandles(SPSelTransType type) // Position knots to scale the selection bbox Geom::Point const bpos(hands[i].x, hands[i].y); Geom::Point p(_bbox->min() + (_bbox->dimensions() * Geom::Scale(bpos))); - sp_knot_moveto(knots[i], p); - sp_knot_show(knots[i]); + knots[i]->moveto(p); + knots[i]->show(); // This controls the center handle's position, because the default can // be moved and needs to be remembered. if( type == HANDLE_CENTER && _center ) - sp_knot_moveto(knots[i], *_center); + knots[i]->moveto(*_center); } } @@ -641,7 +641,7 @@ void Inkscape::SelTrans::_makeHandles() { for (int i = 0; i < NUMHANDS; i++) { SPSelTransTypeInfo info = handtypes[hands[i].type]; - knots[i] = sp_knot_new(_desktop, info.tip); + knots[i] = new SPKnot(_desktop, info.tip); knots[i]->setShape(SP_CTRL_SHAPE_BITMAP); knots[i]->setSize(13); @@ -650,50 +650,46 @@ void Inkscape::SelTrans::_makeHandles() knots[i]->setFill(info.color[0], info.color[1], info.color[2]); knots[i]->setStroke(info.color[3], info.color[4], info.color[5]); knots[i]->setPixbuf(handles[hands[i].control]); - sp_knot_update_ctrl(knots[i]); - - g_signal_connect(G_OBJECT(knots[i]), "request", - G_CALLBACK(sp_sel_trans_handle_request), (gpointer) &hands[i]); - g_signal_connect(G_OBJECT(knots[i]), "moved", - G_CALLBACK(sp_sel_trans_handle_new_event), (gpointer) &hands[i]); - g_signal_connect(G_OBJECT(knots[i]), "grabbed", - G_CALLBACK(sp_sel_trans_handle_grab), (gpointer) &hands[i]); - g_signal_connect(G_OBJECT(knots[i]), "ungrabbed", - G_CALLBACK(sp_sel_trans_handle_ungrab), (gpointer) &hands[i]); - g_signal_connect(G_OBJECT(knots[i]), "clicked", - G_CALLBACK(sp_sel_trans_handle_click), (gpointer) &hands[i]); - g_signal_connect(G_OBJECT(knots[i]), "event", - G_CALLBACK(sp_sel_trans_handle_event), (gpointer) &hands[i]); + knots[i]->updateCtrl(); + + knots[i]->request_signal.connect(sigc::bind(sigc::ptr_fun(sp_sel_trans_handle_request), &hands[i])); + knots[i]->moved_signal.connect(sigc::bind(sigc::ptr_fun(sp_sel_trans_handle_new_event), &hands[i])); + knots[i]->grabbed_signal.connect(sigc::bind(sigc::ptr_fun(sp_sel_trans_handle_grab), &hands[i])); + knots[i]->ungrabbed_signal.connect(sigc::bind(sigc::ptr_fun(sp_sel_trans_handle_ungrab), &hands[i])); + knots[i]->click_signal.connect(sigc::bind(sigc::ptr_fun(sp_sel_trans_handle_click), &hands[i])); + knots[i]->event_signal.connect(sigc::bind(sigc::ptr_fun(sp_sel_trans_handle_event), &hands[i])); } } -static void sp_sel_trans_handle_grab(SPKnot *knot, guint state, gpointer data) +static void sp_sel_trans_handle_grab(SPKnot *knot, guint state, SPSelTransHandle const* data) { SP_SELECT_CONTEXT(knot->desktop->event_context)->_seltrans->handleGrab( knot, state, *(SPSelTransHandle const *) data ); } -static void sp_sel_trans_handle_ungrab(SPKnot *knot, guint /*state*/, gpointer /*data*/) +static void sp_sel_trans_handle_ungrab(SPKnot *knot, guint /*state*/, SPSelTransHandle const* /*data*/) { SP_SELECT_CONTEXT(knot->desktop->event_context)->_seltrans->ungrab(); } -static void sp_sel_trans_handle_new_event(SPKnot *knot, Geom::Point *position, guint state, gpointer data) +static void sp_sel_trans_handle_new_event(SPKnot *knot, Geom::Point const& position, guint state, SPSelTransHandle const *data) { + Geom::Point pos = position; + SP_SELECT_CONTEXT(knot->desktop->event_context)->_seltrans->handleNewEvent( - knot, position, state, *(SPSelTransHandle const *) data + knot, &pos, state, *(SPSelTransHandle const *) data ); } -static gboolean sp_sel_trans_handle_request(SPKnot *knot, Geom::Point *position, guint state, gboolean *data) +static gboolean sp_sel_trans_handle_request(SPKnot *knot, Geom::Point *position, guint state, SPSelTransHandle const *data) { return SP_SELECT_CONTEXT(knot->desktop->event_context)->_seltrans->handleRequest( knot, position, state, *(SPSelTransHandle const *) data ); } -static void sp_sel_trans_handle_click(SPKnot *knot, guint state, gpointer data) +static void sp_sel_trans_handle_click(SPKnot *knot, guint state, SPSelTransHandle const* data) { SP_SELECT_CONTEXT(knot->desktop->event_context)->_seltrans->handleClick( knot, state, *(SPSelTransHandle const *) data @@ -742,7 +738,7 @@ void Inkscape::SelTrans::handleGrab(SPKnot *knot, guint /*state*/, SPSelTransHan break; } - grab(sp_knot_position(knot), handle.x, handle.y, FALSE, FALSE); + grab(knot->position(), handle.x, handle.y, FALSE, FALSE); } @@ -800,7 +796,7 @@ gboolean Inkscape::SelTrans::handleRequest(SPKnot *knot, Geom::Point *position, return TRUE; } if (request(handle, *position, state)) { - sp_knot_set_position(knot, *position, state); + knot->setPosition(*position, state); SP_CTRL(_grip)->moveto(*position); if (handle.type == HANDLE_CENTER) { SP_CTRL(_norm)->moveto(*position); diff --git a/src/seltrans.h b/src/seltrans.h index d97375520..44268ed69 100644 --- a/src/seltrans.h +++ b/src/seltrans.h @@ -27,7 +27,7 @@ #include "sp-item.h" #include "seltrans-handles.h" -struct SPKnot; +class SPKnot; class SPDesktop; struct SPCanvasItem; struct SPCtrlLine; diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index a0aa9692e..60f15a79d 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -183,6 +183,8 @@ void SPGuide::release() { void SPGuide::set(unsigned int key, const gchar *value) { switch (key) { case SP_ATTR_INKSCAPE_LABEL: + if (this->label) g_free(this->label); + if (value) { this->label = g_strdup(value); } else { diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index c3e406e3f..7d80f1e36 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -69,6 +69,7 @@ set(ui_SRC dialog/floating-behavior.cpp dialog/font-substitution.cpp dialog/glyphs.cpp + dialog/grid-arrange-tab.cpp dialog/guides.cpp dialog/icon-preview.cpp dialog/inkscape-preferences.cpp @@ -83,6 +84,7 @@ set(ui_SRC dialog/object-attributes.cpp dialog/object-properties.cpp dialog/ocaldialogs.cpp + dialog/polar-arrange-tab.cpp dialog/print-colors-preview-dialog.cpp dialog/print.cpp dialog/symbols.cpp @@ -103,6 +105,7 @@ set(ui_SRC # dialog/whiteboard-sharewithchat.cpp # dialog/whiteboard-sharewithuser.cpp + widget/anchor-selector.cpp widget/button.cpp widget/color-picker.cpp widget/color-preview.cpp @@ -162,6 +165,7 @@ set(ui_SRC dialog/aboutbox.h dialog/align-and-distribute.h + dialog/arrange-tab.h dialog/behavior.h dialog/calligraphic-profile-rename.h dialog/color-item.h @@ -186,6 +190,7 @@ set(ui_SRC dialog/font-substitution.h dialog/glyphs.h dialog/guides.h + dialog/grid-arrange-tab.h dialog/icon-preview.h dialog/inkscape-preferences.h dialog/input.h @@ -200,6 +205,7 @@ set(ui_SRC dialog/object-properties.h dialog/ocaldialogs.h dialog/panel-dialog.h + dialog/polar-arrange-tab.h dialog/pixelartdialog.h dialog/print-colors-preview-dialog.h dialog/print.h @@ -259,6 +265,7 @@ set(ui_SRC tools/tweak-tool.h tools/zoom-tool.h + widget/anchor-selector.h widget/attr-widget.h widget/button.h widget/color-picker.h diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index c37767a08..daa8aea22 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -5,6 +5,7 @@ ink_common_sources += \ ui/dialog/aboutbox.h \ ui/dialog/align-and-distribute.cpp \ ui/dialog/align-and-distribute.h \ + ui/dialog/arrange-tab.h \ ui/dialog/behavior.h \ ui/dialog/calligraphic-profile-rename.h \ ui/dialog/calligraphic-profile-rename.cpp \ @@ -50,6 +51,8 @@ ink_common_sources += \ ui/dialog/floating-behavior.h \ ui/dialog/glyphs.cpp \ ui/dialog/glyphs.h \ + ui/dialog/grid-arrange-tab.h \ + ui/dialog/grid-arrange-tab.cpp \ ui/dialog/guides.cpp \ ui/dialog/guides.h \ ui/dialog/icon-preview.cpp \ @@ -79,6 +82,8 @@ ink_common_sources += \ ui/dialog/object-properties.cpp \ ui/dialog/object-properties.h \ ui/dialog/panel-dialog.h \ + ui/dialog/polar-arrange-tab.cpp \ + ui/dialog/polar-arrange-tab.h \ ui/dialog/print.cpp \ ui/dialog/print.h \ ui/dialog/print-colors-preview-dialog.cpp \ diff --git a/src/ui/dialog/arrange-tab.h b/src/ui/dialog/arrange-tab.h new file mode 100644 index 000000000..3ffe1ef4c --- /dev/null +++ b/src/ui/dialog/arrange-tab.h @@ -0,0 +1,54 @@ +/** + * @brief Arrange tools base class + */ +/* Authors: + * * Declara Denis + * Copyright (C) 2012 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_UI_DIALOG_ARRANGE_TAB_H +#define INKSCAPE_UI_DIALOG_ARRANGE_TAB_H + +#include <gtkmm/box.h> + +namespace Inkscape { +namespace UI { +namespace Dialog { + +/** + * This interface should be implemented by each arrange mode. + * The class is a Gtk::VBox and will be displayed as a tab in + * the dialog + */ +class ArrangeTab : public Gtk::VBox +{ +public: + ArrangeTab() {}; + virtual ~ArrangeTab() {}; + + /** + * Do the actual work! This method is invoked to actually arrange the + * selection + */ + virtual void arrange() = 0; +}; + +} //namespace Dialog +} //namespace UI +} //namespace Inkscape + + +#endif /* INKSCAPE_UI_DIALOG_ARRANGE_TAB_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 : diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 6d32e3aa8..47e1fdd30 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -116,8 +116,8 @@ DialogManager::DialogManager() { // registerFactory("PrintColorsPreviewDialog", &create<PrintColorsPreviewDialog, FloatingBehavior>); registerFactory("SvgFontsDialog", &create<SvgFontsDialog, FloatingBehavior>); registerFactory("Swatches", &create<SwatchesPanel, FloatingBehavior>); + registerFactory("TileDialog", &create<ArrangeDialog, FloatingBehavior>); registerFactory("Symbols", &create<SymbolsDialog, FloatingBehavior>); - registerFactory("TileDialog", &create<TileDialog, FloatingBehavior>); registerFactory("Trace", &create<TraceDialog, FloatingBehavior>); registerFactory("PixelArt", &create<PixelArtDialog, FloatingBehavior>); registerFactory("Transformation", &create<Transformation, FloatingBehavior>); @@ -150,8 +150,8 @@ DialogManager::DialogManager() { // registerFactory("PrintColorsPreviewDialog", &create<PrintColorsPreviewDialog, DockBehavior>); registerFactory("SvgFontsDialog", &create<SvgFontsDialog, DockBehavior>); registerFactory("Swatches", &create<SwatchesPanel, DockBehavior>); + registerFactory("TileDialog", &create<ArrangeDialog, DockBehavior>); registerFactory("Symbols", &create<SymbolsDialog, DockBehavior>); - registerFactory("TileDialog", &create<TileDialog, DockBehavior>); registerFactory("Trace", &create<TraceDialog, DockBehavior>); registerFactory("PixelArt", &create<PixelArtDialog, DockBehavior>); registerFactory("Transformation", &create<Transformation, DockBehavior>); diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 3cc3f3d88..645294bb5 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -26,11 +26,11 @@ #include "ui/tools/tool-base.h" #include "desktop.h" #include "desktop-handles.h" -#include "modifier-fns.h" #include "shortcuts.h" #include "preferences.h" #include "interface.h" #include "verbs.h" +#include "ui/tool/event-utils.h" #include <gtk/gtk.h> @@ -279,7 +279,7 @@ bool Dialog::_onEvent(GdkEvent *event) case GDK_KEY_F4: case GDK_KEY_w: case GDK_KEY_W: { - if (mod_ctrl_only(event->key.state)) { + if (Inkscape::UI::held_only_control(event->key)) { _close(); ret = true; } diff --git a/src/ui/dialog/document-metadata.cpp b/src/ui/dialog/document-metadata.cpp index efe25d843..09c505860 100644 --- a/src/ui/dialog/document-metadata.cpp +++ b/src/ui/dialog/document-metadata.cpp @@ -122,7 +122,7 @@ DocumentMetadata::build_metadata() _page_metadata1.show(); - Gtk::Label *label = manage (new Gtk::Label); + Gtk::Label *label = Gtk::manage (new Gtk::Label); label->set_markup (_("<b>Dublin Core Entities</b>")); label->set_alignment (0.0); @@ -140,7 +140,7 @@ DocumentMetadata::build_metadata() if ( entity->editable == RDF_EDIT_GENERIC ) { EntityEntry *w = EntityEntry::create (entity, _wr); _rdflist.push_back (w); - Gtk::HBox *space = manage (new Gtk::HBox); + Gtk::HBox *space = Gtk::manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); #if WITH_GTKMM_3_0 @@ -164,7 +164,7 @@ DocumentMetadata::build_metadata() _page_metadata2.show(); row = 0; - Gtk::Label *llabel = manage (new Gtk::Label); + Gtk::Label *llabel = Gtk::manage (new Gtk::Label); llabel->set_markup (_("<b>License</b>")); llabel->set_alignment (0.0); @@ -178,7 +178,7 @@ DocumentMetadata::build_metadata() /* add license selector pull-down and URI */ ++row; _licensor.init (_wr); - Gtk::HBox *space = manage (new Gtk::HBox); + Gtk::HBox *space = Gtk::manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); #if WITH_GTKMM_3_0 diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index a31ab1a09..508fc52b1 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -297,7 +297,7 @@ inline void attach_all(Gtk::Table &table, Gtk::Widget *const arr[], unsigned con table.attach (label, 0, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); #endif } else { - Gtk::HBox *space = manage (new Gtk::HBox); + Gtk::HBox *space = Gtk::manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); #if WITH_GTKMM_3_0 @@ -317,11 +317,11 @@ void DocumentProperties::build_page() { _page_page->show(); - Gtk::Label* label_gen = manage (new Gtk::Label); + Gtk::Label* label_gen = Gtk::manage (new Gtk::Label); label_gen->set_markup (_("<b>General</b>")); - Gtk::Label *label_for = manage (new Gtk::Label); + Gtk::Label *label_for = Gtk::manage (new Gtk::Label); label_for->set_markup (_("<b>Page Size</b>")); - Gtk::Label* label_dsp = manage (new Gtk::Label); + Gtk::Label* label_dsp = Gtk::manage (new Gtk::Label); label_dsp->set_markup (_("<b>Display</b>")); _page_sizer.init(); @@ -356,7 +356,7 @@ void DocumentProperties::build_guides() { _page_guides->show(); - Gtk::Label *label_gui = manage (new Gtk::Label); + Gtk::Label *label_gui = Gtk::manage (new Gtk::Label); label_gui->set_markup (_("<b>Guides</b>")); Gtk::Widget *const widget_array[] = @@ -374,13 +374,13 @@ void DocumentProperties::build_snap() { _page_snap->show(); - Gtk::Label *label_o = manage (new Gtk::Label); + Gtk::Label *label_o = Gtk::manage (new Gtk::Label); label_o->set_markup (_("<b>Snap to objects</b>")); - Gtk::Label *label_gr = manage (new Gtk::Label); + Gtk::Label *label_gr = Gtk::manage (new Gtk::Label); label_gr->set_markup (_("<b>Snap to grids</b>")); - Gtk::Label *label_gu = manage (new Gtk::Label); + Gtk::Label *label_gu = Gtk::manage (new Gtk::Label); label_gu->set_markup (_("<b>Snap to guides</b>")); - Gtk::Label *label_m = manage (new Gtk::Label); + Gtk::Label *label_m = Gtk::manage (new Gtk::Label); label_m->set_markup (_("<b>Miscellaneous</b>")); Gtk::Widget *const array[] = @@ -607,9 +607,9 @@ void DocumentProperties::removeSelectedProfile(){ void DocumentProperties::build_cms() { _page_cms->show(); - Gtk::Label *label_link= manage (new Gtk::Label("", Gtk::ALIGN_START)); + Gtk::Label *label_link= Gtk::manage (new Gtk::Label("", Gtk::ALIGN_START)); label_link->set_markup (_("<b>Linked Color Profiles:</b>")); - Gtk::Label *label_avail = manage (new Gtk::Label("", Gtk::ALIGN_START)); + Gtk::Label *label_avail = Gtk::manage (new Gtk::Label("", Gtk::ALIGN_START)); label_avail->set_markup (_("<b>Available Color Profiles:</b>")); _link_btn.set_tooltip_text(_("Link Profile")); @@ -746,7 +746,7 @@ void DocumentProperties::build_scripting() //# External scripts tab _page_external_scripts->show(); - Gtk::Label *label_external= manage (new Gtk::Label("", Gtk::ALIGN_START)); + Gtk::Label *label_external= Gtk::manage (new Gtk::Label("", Gtk::ALIGN_START)); label_external->set_markup (_("<b>External script files:</b>")); _external_add_btn.set_tooltip_text(_("Add the current file name or browse for a file")); @@ -835,7 +835,7 @@ void DocumentProperties::build_scripting() //# Embedded scripts tab _page_embedded_scripts->show(); - Gtk::Label *label_embedded= manage (new Gtk::Label("", Gtk::ALIGN_START)); + Gtk::Label *label_embedded= Gtk::manage (new Gtk::Label("", Gtk::ALIGN_START)); label_embedded->set_markup (_("<b>Embedded script files:</b>")); _embed_new_btn.set_tooltip_text(_("New")); @@ -922,7 +922,7 @@ void DocumentProperties::build_scripting() // TODO restore? _EmbeddedScriptsList.set_fixed_height_mode(true); //# Set up the Embedded Scripts content box - Gtk::Label *label_embedded_content= manage (new Gtk::Label("", Gtk::ALIGN_START)); + Gtk::Label *label_embedded_content= Gtk::manage (new Gtk::Label("", Gtk::ALIGN_START)); label_embedded_content->set_markup (_("<b>Content:</b>")); label_embedded_content->set_alignment(0.0); @@ -1001,7 +1001,7 @@ void DocumentProperties::build_metadata() _page_metadata1->show(); - Gtk::Label *label = manage (new Gtk::Label); + Gtk::Label *label = Gtk::manage (new Gtk::Label); label->set_markup (_("<b>Dublin Core Entities</b>")); label->set_alignment (0.0); @@ -1019,7 +1019,7 @@ void DocumentProperties::build_metadata() if ( entity->editable == RDF_EDIT_GENERIC ) { EntityEntry *w = EntityEntry::create (entity, _wr); _rdflist.push_back (w); - Gtk::HBox *space = manage (new Gtk::HBox); + Gtk::HBox *space = Gtk::manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); #if WITH_GTKMM_3_0 @@ -1040,15 +1040,15 @@ void DocumentProperties::build_metadata() } } - Gtk::Button *button_save = manage (new Gtk::Button(_("_Save as default"),1)); + Gtk::Button *button_save = Gtk::manage (new Gtk::Button(_("_Save as default"),1)); button_save->set_tooltip_text(_("Save this metadata as the default metadata")); - Gtk::Button *button_load = manage (new Gtk::Button(_("Use _default"),1)); + Gtk::Button *button_load = Gtk::manage (new Gtk::Button(_("Use _default"),1)); button_load->set_tooltip_text(_("Use the previously saved default metadata here")); #if WITH_GTKMM_3_0 - Gtk::ButtonBox *box_buttons = manage (new Gtk::ButtonBox); + Gtk::ButtonBox *box_buttons = Gtk::manage (new Gtk::ButtonBox); #else - Gtk::HButtonBox *box_buttons = manage (new Gtk::HButtonBox); + Gtk::HButtonBox *box_buttons = Gtk::manage (new Gtk::HButtonBox); #endif box_buttons->set_layout(Gtk::BUTTONBOX_END); @@ -1063,7 +1063,7 @@ void DocumentProperties::build_metadata() _page_metadata2->show(); row = 0; - Gtk::Label *llabel = manage (new Gtk::Label); + Gtk::Label *llabel = Gtk::manage (new Gtk::Label); llabel->set_markup (_("<b>License</b>")); llabel->set_alignment (0.0); @@ -1077,7 +1077,7 @@ void DocumentProperties::build_metadata() /* add license selector pull-down and URI */ ++row; _licensor.init (_wr); - Gtk::HBox *space = manage (new Gtk::HBox); + Gtk::HBox *space = Gtk::manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); #if WITH_GTKMM_3_0 @@ -1545,12 +1545,12 @@ void DocumentProperties::update() Gtk::HBox& DocumentProperties::_createPageTabLabel(const Glib::ustring& label, const char *label_image) { - Gtk::HBox *_tab_label_box = manage(new Gtk::HBox(false, 0)); + Gtk::HBox *_tab_label_box = Gtk::manage(new Gtk::HBox(false, 0)); _tab_label_box->set_spacing(4); _tab_label_box->pack_start(*Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_DECORATION, label_image))); - Gtk::Label *_tab_label = manage(new Gtk::Label(label, true)); + Gtk::Label *_tab_label = Gtk::manage(new Gtk::Label(label, true)); _tab_label_box->pack_start(*_tab_label); _tab_label_box->show_all(); diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index 19b873d54..c55d55cda 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -131,7 +131,7 @@ FillAndStroke::_savePagePref(guint page_num) void FillAndStroke::_layoutPageFill() { - fillWdgt = manage(sp_fill_style_widget_new()); + fillWdgt = Gtk::manage(sp_fill_style_widget_new()); #if WITH_GTKMM_3_0 _page_fill->table().attach(*fillWdgt, 0, 0, 1, 1); @@ -143,7 +143,7 @@ FillAndStroke::_layoutPageFill() void FillAndStroke::_layoutPageStrokePaint() { - strokeWdgt = manage(sp_stroke_style_paint_widget_new()); + strokeWdgt = Gtk::manage(sp_stroke_style_paint_widget_new()); #if WITH_GTKMM_3_0 _page_stroke_paint->table().attach(*strokeWdgt, 0, 0, 1, 1); @@ -195,11 +195,11 @@ FillAndStroke::showPageStrokeStyle() Gtk::HBox& FillAndStroke::_createPageTabLabel(const Glib::ustring& label, const char *label_image) { - Gtk::HBox *_tab_label_box = manage(new Gtk::HBox(false, 4)); + Gtk::HBox *_tab_label_box = Gtk::manage(new Gtk::HBox(false, 4)); _tab_label_box->pack_start(*Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_DECORATION, label_image))); - Gtk::Label *_tab_label = manage(new Gtk::Label(label, true)); + Gtk::Label *_tab_label = Gtk::manage(new Gtk::Label(label, true)); _tab_label_box->pack_start(*_tab_label); _tab_label_box->show_all(); diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp new file mode 100644 index 000000000..8c0a4dc66 --- /dev/null +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -0,0 +1,809 @@ +/* + * A simple dialog for creating grid type arrangements of selected objects + * + * Authors: + * Bob Jamison ( based off trace dialog) + * John Cliff + * Other dudes from The Inkscape Organization + * Abhishek Sharma + * Declara Denis + * + * Copyright (C) 2004 Bob Jamison + * Copyright (C) 2004 John Cliff + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +//#define DEBUG_GRID_ARRANGE 1 + +#include "ui/dialog/grid-arrange-tab.h" +#include <gtk/gtk.h> //for GTK_RESPONSE* types +#include <glibmm/i18n.h> +#include <gtkmm/stock.h> + +#if WITH_GTKMM_3_0 +# include <gtkmm/grid.h> +#else +# include <gtkmm/table.h> +#endif + +#include <2geom/transforms.h> + +#include "verbs.h" +#include "preferences.h" +#include "inkscape.h" +#include "desktop-handles.h" +#include "selection.h" +#include "document.h" +#include "document-undo.h" +#include "sp-item.h" +#include "widgets/icon.h" +#include "desktop.h" +//#include "sp-item-transform.h" FIXME +#include "ui/dialog/tile.h" // for Inkscape::UI::Dialog::ArrangeDialog + +/* + * Sort items by their x co-ordinates, taking account of y (keeps rows intact) + * + * <0 *elem1 goes before *elem2 + * 0 *elem1 == *elem2 + * >0 *elem1 goes after *elem2 + */ +static int sp_compare_x_position(SPItem *first, SPItem *second) +{ + using Geom::X; + using Geom::Y; + + Geom::OptRect a = first->documentVisualBounds(); + Geom::OptRect b = second->documentVisualBounds(); + + if ( !a || !b ) { + // FIXME? + return 0; + } + + double const a_height = a->dimensions()[Y]; + double const b_height = b->dimensions()[Y]; + + bool a_in_b_vert = false; + if ((a->min()[Y] < b->min()[Y] + 0.1) && (a->min()[Y] > b->min()[Y] - b_height)) { + a_in_b_vert = true; + } else if ((b->min()[Y] < a->min()[Y] + 0.1) && (b->min()[Y] > a->min()[Y] - a_height)) { + a_in_b_vert = true; + } else if (b->min()[Y] == a->min()[Y]) { + a_in_b_vert = true; + } else { + a_in_b_vert = false; + } + + if (!a_in_b_vert) { + return -1; + } + if (a_in_b_vert && a->min()[X] > b->min()[X]) { + return 1; + } + if (a_in_b_vert && a->min()[X] < b->min()[X]) { + return -1; + } + return 0; +} + +/* + * Sort items by their y co-ordinates. + */ +static int sp_compare_y_position(SPItem *first, SPItem *second) +{ + Geom::OptRect a = first->documentVisualBounds(); + Geom::OptRect b = second->documentVisualBounds(); + + if ( !a || !b ) { + // FIXME? + return 0; + } + + if (a->min()[Geom::Y] > b->min()[Geom::Y]) { + return 1; + } + if (a->min()[Geom::Y] < b->min()[Geom::Y]) { + return -1; + } + + return 0; +} + +namespace Inkscape { +namespace UI { +namespace Dialog { + + +//######################################################################### +//## E V E N T S +//######################################################################### + +/* + * + * This arranges the selection in a grid pattern. + * + */ + +void GridArrangeTab::arrange() +{ + + int cnt,row_cnt,col_cnt,a,row,col; + double grid_left,grid_top,col_width,row_height,paddingx,paddingy,width, height, new_x, new_y; + double total_col_width,total_row_height; + col_width = 0; + row_height = 0; + total_col_width=0; + total_row_height=0; + + // check for correct numbers in the row- and col-spinners + on_col_spinbutton_changed(); + on_row_spinbutton_changed(); + + // set padding to manual values + paddingx = XPadding.getValue("px"); + paddingy = YPadding.getValue("px"); + + std::vector<double> row_heights; + std::vector<double> col_widths; + std::vector<double> row_ys; + std::vector<double> col_xs; + + int NoOfCols = NoOfColsSpinner.get_value_as_int(); + int NoOfRows = NoOfRowsSpinner.get_value_as_int(); + + width = 0; + for (a=0;a<NoOfCols; a++){ + col_widths.push_back(width); + } + + height = 0; + for (a=0;a<NoOfRows; a++){ + row_heights.push_back(height); + } + grid_left = 99999; + grid_top = 99999; + + SPDesktop *desktop = Parent->getDesktop(); + sp_desktop_document(desktop)->ensureUpToDate(); + + Inkscape::Selection *selection = sp_desktop_selection (desktop); + const GSList *items = selection ? selection->itemList() : 0; + cnt=0; + for (; items != NULL; items = items->next) { + SPItem *item = SP_ITEM(items->data); + Geom::OptRect b = item->documentVisualBounds(); + if (!b) { + continue; + } + + width = b->dimensions()[Geom::X]; + height = b->dimensions()[Geom::Y]; + + if (b->min()[Geom::X] < grid_left) { + grid_left = b->min()[Geom::X]; + } + if (b->min()[Geom::Y] < grid_top) { + grid_top = b->min()[Geom::Y]; + } + if (width > col_width) { + col_width = width; + } + if (height > row_height) { + row_height = height; + } + } + + + // require the sorting done before we can calculate row heights etc. + + g_return_if_fail(selection); + const GSList *items2 = selection->itemList(); + GSList *rev = g_slist_copy(const_cast<GSList *>(items2)); + GSList *sorted = NULL; + rev = g_slist_sort(rev, (GCompareFunc) sp_compare_y_position); + sorted = g_slist_sort(rev, (GCompareFunc) sp_compare_x_position); + + + // Calculate individual Row and Column sizes if necessary + + + cnt=0; + const GSList *sizes = sorted; + for (; sizes != NULL; sizes = sizes->next) { + SPItem *item = SP_ITEM(sizes->data); + Geom::OptRect b = item->documentVisualBounds(); + if (b) { + width = b->dimensions()[Geom::X]; + height = b->dimensions()[Geom::Y]; + if (width > col_widths[(cnt % NoOfCols)]) { + col_widths[(cnt % NoOfCols)] = width; + } + if (height > row_heights[(cnt / NoOfCols)]) { + row_heights[(cnt / NoOfCols)] = height; + } + } + + cnt++; + } + + + /// Make sure the top and left of the grid dont move by compensating for align values. + if (RowHeightButton.get_active()){ + grid_top = grid_top - (((row_height - row_heights[0]) / 2)*(VertAlign)); + } + if (ColumnWidthButton.get_active()){ + grid_left = grid_left - (((col_width - col_widths[0]) /2)*(HorizAlign)); + } + + #ifdef DEBUG_GRID_ARRANGE + g_print("\n cx = %f cy= %f gridleft=%f",cx,cy,grid_left); + #endif + + // Calculate total widths and heights, allowing for columns and rows non uniformly sized. + + if (ColumnWidthButton.get_active()){ + total_col_width = col_width * NoOfCols; + col_widths.clear(); + for (a=0;a<NoOfCols; a++){ + col_widths.push_back(col_width); + } + } else { + for (a = 0; a < (int)col_widths.size(); a++) + { + total_col_width += col_widths[a] ; + } + } + + if (RowHeightButton.get_active()){ + total_row_height = row_height * NoOfRows; + row_heights.clear(); + for (a=0;a<NoOfRows; a++){ + row_heights.push_back(row_height); + } + } else { + for (a = 0; a < (int)row_heights.size(); a++) + { + total_row_height += row_heights[a] ; + } + } + + + Geom::OptRect sel_bbox = selection->visualBounds(); + // Fit to bbox, calculate padding between rows accordingly. + if ( sel_bbox && !SpaceManualRadioButton.get_active() ){ +#ifdef DEBUG_GRID_ARRANGE +g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_height,total_col_width, b.extent(Geom::X), b.extent(Geom::Y)); +#endif + paddingx = (sel_bbox->width() - total_col_width) / (NoOfCols -1); + paddingy = (sel_bbox->height() - total_row_height) / (NoOfRows -1); + } + +/* + Horizontal align - Left = 0 + Centre = 1 + Right = 2 + + Vertical align - Top = 0 + Middle = 1 + Bottom = 2 + + X position is calculated by taking the grids left co-ord, adding the distance to the column, + then adding 1/2 the spacing multiplied by the align variable above, + Y position likewise, takes the top of the grid, adds the y to the current row then adds the padding in to align it. + +*/ + + // Calculate row and column x and y coords required to allow for columns and rows which are non uniformly sized. + + for (a=0;a<NoOfCols; a++){ + if (a<1) col_xs.push_back(0); + else col_xs.push_back(col_widths[a-1]+paddingx+col_xs[a-1]); + } + + + for (a=0;a<NoOfRows; a++){ + if (a<1) row_ys.push_back(0); + else row_ys.push_back(row_heights[a-1]+paddingy+row_ys[a-1]); + } + + cnt=0; + for (row_cnt=0; ((sorted != NULL) && (row_cnt<NoOfRows)); row_cnt++) { + + GSList *current_row = NULL; + for (col_cnt = 0; ((sorted != NULL) && (col_cnt<NoOfCols)); col_cnt++) { + current_row = g_slist_append (current_row, sorted->data); + sorted = sorted->next; + } + + for (; current_row != NULL; current_row = current_row->next) { + SPItem *item=SP_ITEM(current_row->data); + Inkscape::XML::Node *repr = item->getRepr(); + Geom::OptRect b = item->documentVisualBounds(); + Geom::Point min; + if (b) { + width = b->dimensions()[Geom::X]; + height = b->dimensions()[Geom::Y]; + min = b->min(); + } else { + width = height = 0; + min = Geom::Point(0, 0); + } + + row = cnt / NoOfCols; + col = cnt % NoOfCols; + + new_x = grid_left + (((col_widths[col] - width)/2)*HorizAlign) + col_xs[col]; + new_y = grid_top + (((row_heights[row] - height)/2)*VertAlign) + row_ys[row]; + + // signs are inverted between x and y due to y inversion + Geom::Point move = Geom::Point(new_x - min[Geom::X], min[Geom::Y] - new_y); + Geom::Affine const affine = Geom::Affine(Geom::Translate(move)); + item->set_i2d_affine(item->i2dt_affine() * affine); + item->doWriteTransform(repr, item->transform, NULL); + SP_OBJECT (current_row->data)->updateRepr(); + cnt +=1; + } + g_slist_free (current_row); + } + + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_ARRANGE, + _("Arrange in a grid")); + +} + + +//######################################################################### +//## E V E N T S +//######################################################################### + +/** + * changed value in # of columns spinbox. + */ +void GridArrangeTab::on_row_spinbutton_changed() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + // in turn, prevent listener from responding + updating = true; + SPDesktop *desktop = Parent->getDesktop(); + + Inkscape::Selection *selection = desktop ? desktop->selection : 0; + g_return_if_fail( selection ); + + GSList const *items = selection->itemList(); + int selcount = g_slist_length((GSList *)items); + + double PerCol = ceil(selcount / NoOfColsSpinner.get_value()); + NoOfRowsSpinner.set_value(PerCol); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/dialogs/gridtiler/NoOfCols", NoOfColsSpinner.get_value()); + updating=false; +} + +/** + * changed value in # of rows spinbox. + */ +void GridArrangeTab::on_col_spinbutton_changed() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + // in turn, prevent listener from responding + updating = true; + SPDesktop *desktop = Parent->getDesktop(); + Inkscape::Selection *selection = desktop ? desktop->selection : 0; + g_return_if_fail(selection); + + GSList const *items = selection->itemList(); + int selcount = g_slist_length((GSList *)items); + + double PerRow = ceil(selcount / NoOfRowsSpinner.get_value()); + NoOfColsSpinner.set_value(PerRow); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/dialogs/gridtiler/NoOfCols", PerRow); + + updating=false; +} + +/** + * changed value in x padding spinbox. + */ +void GridArrangeTab::on_xpad_spinbutton_changed() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/dialogs/gridtiler/XPad", XPadding.getValue("px")); + +} + +/** + * changed value in y padding spinbox. + */ +void GridArrangeTab::on_ypad_spinbutton_changed() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/dialogs/gridtiler/YPad", YPadding.getValue("px")); +} + + +/** + * checked/unchecked autosize Rows button. + */ +void GridArrangeTab::on_RowSize_checkbutton_changed() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (RowHeightButton.get_active()) { + prefs->setDouble("/dialogs/gridtiler/AutoRowSize", 20); + } else { + prefs->setDouble("/dialogs/gridtiler/AutoRowSize", -20); + } + RowHeightBox.set_sensitive ( !RowHeightButton.get_active()); +} + +/** + * checked/unchecked autosize Rows button. + */ +void GridArrangeTab::on_ColSize_checkbutton_changed() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (ColumnWidthButton.get_active()) { + prefs->setDouble("/dialogs/gridtiler/AutoColSize", 20); + } else { + prefs->setDouble("/dialogs/gridtiler/AutoColSize", -20); + } + ColumnWidthBox.set_sensitive ( !ColumnWidthButton.get_active()); +} + +/** + * changed value in columns spinbox. + */ +void GridArrangeTab::on_rowSize_spinbutton_changed() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + // in turn, prevent listener from responding + updating = true; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/dialogs/gridtiler/RowHeight", RowHeightSpinner.get_value()); + updating=false; + +} + +/** + * changed value in rows spinbox. + */ +void GridArrangeTab::on_colSize_spinbutton_changed() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + // in turn, prevent listener from responding + updating = true; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/dialogs/gridtiler/ColWidth", ColumnWidthSpinner.get_value()); + updating=false; + +} + +/** + * changed Radio button in Spacing group. + */ +void GridArrangeTab::Spacing_button_changed() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (SpaceManualRadioButton.get_active()) { + prefs->setDouble("/dialogs/gridtiler/SpacingType", 20); + } else { + prefs->setDouble("/dialogs/gridtiler/SpacingType", -20); + } + + XPadding.set_sensitive ( SpaceManualRadioButton.get_active()); + YPadding.set_sensitive ( SpaceManualRadioButton.get_active()); +} + +/** + * changed Anchor selection widget. + */ +void GridArrangeTab::Align_changed() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + VertAlign = AlignmentSelector.getVerticalAlignment(); + prefs->setInt("/dialogs/gridtiler/VertAlign", VertAlign); + HorizAlign = AlignmentSelector.getHorizontalAlignment(); + prefs->setInt("/dialogs/gridtiler/HorizAlign", HorizAlign); +} + +/** + * Desktop selection changed + */ +void GridArrangeTab::updateSelection() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + // in turn, prevent listener from responding + updating = true; + SPDesktop *desktop = Parent->getDesktop(); + Inkscape::Selection *selection = desktop ? desktop->selection : 0; + GSList const *items = selection ? selection->itemList() : 0; + + if (items) { + int selcount = g_slist_length((GSList *)items); + + if (NoOfColsSpinner.get_value() > 1 && NoOfRowsSpinner.get_value() > 1){ + // Update the number of rows assuming number of columns wanted remains same. + double NoOfRows = ceil(selcount / NoOfColsSpinner.get_value()); + NoOfRowsSpinner.set_value(NoOfRows); + + // if the selection has less than the number set for one row, reduce it appropriately + if (selcount < NoOfColsSpinner.get_value()) { + double NoOfCols = ceil(selcount / NoOfRowsSpinner.get_value()); + NoOfColsSpinner.set_value(NoOfCols); + prefs->setInt("/dialogs/gridtiler/NoOfCols", NoOfCols); + } + } else { + double PerRow = ceil(sqrt(selcount)); + double PerCol = ceil(sqrt(selcount)); + NoOfRowsSpinner.set_value(PerRow); + NoOfColsSpinner.set_value(PerCol); + prefs->setInt("/dialogs/gridtiler/NoOfCols", static_cast<int>(PerCol)); + } + } + + updating = false; +} + + + +/*########################## +## Experimental +##########################*/ + +static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg) +{ + dlg->updateSelection(); +} + + +//######################################################################### +//## C O N S T R U C T O R / D E S T R U C T O R +//######################################################################### +/** + * Constructor + */ +GridArrangeTab::GridArrangeTab(ArrangeDialog *parent) + : Parent(parent), + XPadding(_("X:"), _("Horizontal spacing between columns."), UNIT_TYPE_LINEAR, "", "object-columns", &PaddingUnitMenu), + YPadding(_("Y:"), _("Vertical spacing between rows."), XPadding, "", "object-rows", &PaddingUnitMenu), +#if WITH_GTKMM_3_0 + PaddingTable(Gtk::manage(new Gtk::Grid())) +#else + PaddingTable(Gtk::manage(new Gtk::Table(2, 2, false))) +#endif +{ + // bool used by spin button callbacks to stop loops where they change each other. + updating = false; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + // could not do this in gtkmm - there's no Gtk::SizeGroup public constructor (!) + GtkSizeGroup *_col1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + GtkSizeGroup *_col2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + GtkSizeGroup *_col3 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + + { + // Selection Change signal + g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (updateSelectionCallback), this); + } + + Gtk::Box *contents = this; + +#define MARGIN 2 + + //##Set up the panel + + SPDesktop *desktop = Parent->getDesktop(); + + Inkscape::Selection *selection = desktop ? desktop->selection : 0; + g_return_if_fail( selection ); + int selcount = 1; + if (!selection->isEmpty()) { + GSList const *items = selection->itemList(); + selcount = g_slist_length((GSList *)items); + } + + + /*#### Number of Rows ####*/ + + double PerRow = ceil(sqrt(selcount)); + double PerCol = ceil(sqrt(selcount)); + + #ifdef DEBUG_GRID_ARRANGE + g_print("/n PerRox = %f PerCol = %f selcount = %d",PerRow,PerCol,selcount); + #endif + + NoOfRowsLabel.set_text_with_mnemonic(_("_Rows:")); + NoOfRowsLabel.set_mnemonic_widget(NoOfRowsSpinner); + NoOfRowsBox.pack_start(NoOfRowsLabel, false, false, MARGIN); + + NoOfRowsSpinner.set_digits(0); + NoOfRowsSpinner.set_increments(1, 0); + NoOfRowsSpinner.set_range(1.0, 10000.0); + NoOfRowsSpinner.set_value(PerCol); + NoOfRowsSpinner.signal_changed().connect(sigc::mem_fun(*this, &GridArrangeTab::on_col_spinbutton_changed)); + NoOfRowsSpinner.set_tooltip_text(_("Number of rows")); + NoOfRowsBox.pack_start(NoOfRowsSpinner, false, false, MARGIN); + gtk_size_group_add_widget(_col1, (GtkWidget *) NoOfRowsBox.gobj()); + + RowHeightButton.set_label(_("Equal _height")); + RowHeightButton.set_use_underline(true); + double AutoRow = prefs->getDouble("/dialogs/gridtiler/AutoRowSize", 15); + if (AutoRow>0) + AutoRowSize=true; + else + AutoRowSize=false; + RowHeightButton.set_active(AutoRowSize); + + NoOfRowsBox.pack_start(RowHeightButton, false, false, MARGIN); + + RowHeightButton.set_tooltip_text(_("If not set, each row has the height of the tallest object in it")); + RowHeightButton.signal_toggled().connect(sigc::mem_fun(*this, &GridArrangeTab::on_RowSize_checkbutton_changed)); + + SpinsHBox.pack_start(NoOfRowsBox, false, false, MARGIN); + + + /*#### Label for X ####*/ + padXByYLabel.set_label(" "); + XByYLabelVBox.pack_start(padXByYLabel, false, false, MARGIN); + XByYLabel.set_markup(" × "); + XByYLabelVBox.pack_start(XByYLabel, false, false, MARGIN); + SpinsHBox.pack_start(XByYLabelVBox, false, false, MARGIN); + gtk_size_group_add_widget(_col2, GTK_WIDGET(XByYLabelVBox.gobj())); + + /*#### Number of columns ####*/ + + NoOfColsLabel.set_text_with_mnemonic(_("_Columns:")); + NoOfColsLabel.set_mnemonic_widget(NoOfColsSpinner); + NoOfColsBox.pack_start(NoOfColsLabel, false, false, MARGIN); + + NoOfColsSpinner.set_digits(0); + NoOfColsSpinner.set_increments(1, 0); + NoOfColsSpinner.set_range(1.0, 10000.0); + NoOfColsSpinner.set_value(PerRow); + NoOfColsSpinner.signal_changed().connect(sigc::mem_fun(*this, &GridArrangeTab::on_row_spinbutton_changed)); + NoOfColsSpinner.set_tooltip_text(_("Number of columns")); + NoOfColsBox.pack_start(NoOfColsSpinner, false, false, MARGIN); + gtk_size_group_add_widget(_col3, GTK_WIDGET(NoOfColsBox.gobj())); + + ColumnWidthButton.set_label(_("Equal _width")); + ColumnWidthButton.set_use_underline(true); + double AutoCol = prefs->getDouble("/dialogs/gridtiler/AutoColSize", 15); + if (AutoCol>0) + AutoColSize=true; + else + AutoColSize=false; + ColumnWidthButton.set_active(AutoColSize); + NoOfColsBox.pack_start(ColumnWidthButton, false, false, MARGIN); + + ColumnWidthButton.set_tooltip_text(_("If not set, each column has the width of the widest object in it")); + ColumnWidthButton.signal_toggled().connect(sigc::mem_fun(*this, &GridArrangeTab::on_ColSize_checkbutton_changed)); + + SpinsHBox.pack_start(NoOfColsBox, false, false, MARGIN); + + TileBox.pack_start(SpinsHBox, false, false, MARGIN); + + VertAlign = prefs->getInt("/dialogs/gridtiler/VertAlign", 1); + HorizAlign = prefs->getInt("/dialogs/gridtiler/HorizAlign", 1); + + // Anchor selection widget + AlignLabel.set_label("Alignment:"); + AlignLabel.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + AlignmentSelector.setAlignment(HorizAlign, VertAlign); + AlignmentSelector.on_selectionChanged().connect(sigc::mem_fun(*this, &GridArrangeTab::Align_changed)); + TileBox.pack_start(AlignLabel, false, false, MARGIN); + TileBox.pack_start(AlignmentSelector, true, false, MARGIN); + + { + /*#### Radio buttons to control spacing manually or to fit selection bbox ####*/ + SpaceByBBoxRadioButton.set_label(_("_Fit into selection box")); + SpaceByBBoxRadioButton.set_use_underline (true); + SpaceByBBoxRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &GridArrangeTab::Spacing_button_changed)); + SpacingGroup = SpaceByBBoxRadioButton.get_group(); + + SpacingVBox.pack_start(SpaceByBBoxRadioButton, false, false, MARGIN); + + SpaceManualRadioButton.set_label(_("_Set spacing:")); + SpaceManualRadioButton.set_use_underline (true); + SpaceManualRadioButton.set_group(SpacingGroup); + SpaceManualRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &GridArrangeTab::Spacing_button_changed)); + SpacingVBox.pack_start(SpaceManualRadioButton, false, false, MARGIN); + + TileBox.pack_start(SpacingVBox, false, false, MARGIN); + } + + { + /*#### Padding ####*/ + PaddingUnitMenu.setUnitType(UNIT_TYPE_LINEAR); + PaddingUnitMenu.setUnit("px"); + + YPadding.setDigits(5); + YPadding.setIncrements(0.2, 0); + YPadding.setRange(-10000, 10000); + double yPad = prefs->getDouble("/dialogs/gridtiler/YPad", 15); + YPadding.setValue(yPad, "px"); + YPadding.signal_value_changed().connect(sigc::mem_fun(*this, &GridArrangeTab::on_ypad_spinbutton_changed)); + + XPadding.setDigits(5); + XPadding.setIncrements(0.2, 0); + XPadding.setRange(-10000, 10000); + double xPad = prefs->getDouble("/dialogs/gridtiler/XPad", 15); + XPadding.setValue(xPad, "px"); + + XPadding.signal_value_changed().connect(sigc::mem_fun(*this, &GridArrangeTab::on_xpad_spinbutton_changed)); + } + + PaddingTable->set_border_width(MARGIN); + +#if WITH_GTKMM_3_0 + PaddingTable->set_row_spacing(MARGIN); + PaddingTable->set_column_spacing(MARGIN); + PaddingTable->attach(XPadding, 0, 0, 1, 1); + PaddingTable->attach(PaddingUnitMenu, 1, 0, 1, 1); + PaddingTable->attach(YPadding, 0, 1, 1, 1); +#else + PaddingTable->set_row_spacings(MARGIN); + PaddingTable->set_col_spacings(MARGIN); + PaddingTable->attach(XPadding, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK); + PaddingTable->attach(PaddingUnitMenu, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK); + PaddingTable->attach(YPadding, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK); +#endif + + TileBox.pack_start(*PaddingTable, false, false, MARGIN); + + contents->pack_start(TileBox); + + double SpacingType = prefs->getDouble("/dialogs/gridtiler/SpacingType", 15); + if (SpacingType>0) { + ManualSpacing=true; + } else { + ManualSpacing=false; + } + SpaceManualRadioButton.set_active(ManualSpacing); + SpaceByBBoxRadioButton.set_active(!ManualSpacing); + XPadding.set_sensitive (ManualSpacing); + YPadding.set_sensitive (ManualSpacing); + + //## The OK button FIXME + /*TileOkButton = addResponseButton(C_("Rows and columns dialog","_Arrange"), GTK_RESPONSE_APPLY); + TileOkButton->set_use_underline(true); + TileOkButton->set_tooltip_text(_("Arrange selected objects"));*/ + + show_all_children(); +} + +} //namespace Dialog +} //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 : diff --git a/src/ui/dialog/grid-arrange-tab.h b/src/ui/dialog/grid-arrange-tab.h new file mode 100644 index 000000000..9d6700b39 --- /dev/null +++ b/src/ui/dialog/grid-arrange-tab.h @@ -0,0 +1,154 @@ +/** + * @brief Arranges Objects into a Grid + */ +/* Authors: + * Bob Jamison ( based off trace dialog) + * John Cliff + * Other dudes from The Inkscape Organization + * Abhishek Sharma + * Declara Denis + * + * Copyright (C) 2004 Bob Jamison + * Copyright (C) 2004 John Cliff + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H +#define INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H + +#include <gtkmm.h> + +#include "ui/dialog/arrange-tab.h" + +#include "ui/widget/anchor-selector.h" +#include "ui/widget/scalar-unit.h" +#include "ui/widget/spinbutton.h" + +namespace Inkscape { +namespace UI { +namespace Dialog { + +class ArrangeDialog; + +/** + * Dialog for tiling an object + */ +class GridArrangeTab : public ArrangeTab { +public: + GridArrangeTab(ArrangeDialog *parent); + virtual ~GridArrangeTab() {}; + + /** + * Do the actual work + */ + virtual void arrange(); + + /** + * Respond to selection change + */ + void updateSelection(); + + // Callbacks from spinbuttons + void on_row_spinbutton_changed(); + void on_col_spinbutton_changed(); + void on_xpad_spinbutton_changed(); + void on_ypad_spinbutton_changed(); + void on_RowSize_checkbutton_changed(); + void on_ColSize_checkbutton_changed(); + void on_rowSize_spinbutton_changed(); + void on_colSize_spinbutton_changed(); + void Spacing_button_changed(); + void Align_changed(); + + +private: + GridArrangeTab(GridArrangeTab const &d); // no copy + void operator=(GridArrangeTab const &d); // no assign + + ArrangeDialog *Parent; + + bool userHidden; + bool updating; + + Gtk::VBox TileBox; + Gtk::Button *TileOkButton; + Gtk::Button *TileCancelButton; + + // Number selected label + Gtk::Label SelectionContentsLabel; + + + Gtk::HBox AlignHBox; + Gtk::HBox SpinsHBox; + + // Number per Row + Gtk::VBox NoOfColsBox; + Gtk::Label NoOfColsLabel; + Inkscape::UI::Widget::SpinButton NoOfColsSpinner; + bool AutoRowSize; + Gtk::CheckButton RowHeightButton; + + Gtk::VBox XByYLabelVBox; + Gtk::Label padXByYLabel; + Gtk::Label XByYLabel; + + // Number per Column + Gtk::VBox NoOfRowsBox; + Gtk::Label NoOfRowsLabel; + Inkscape::UI::Widget::SpinButton NoOfRowsSpinner; + bool AutoColSize; + Gtk::CheckButton ColumnWidthButton; + + // Alignment + Gtk::Label AlignLabel; + Inkscape::UI::Widget::AnchorSelector AlignmentSelector; + double VertAlign; + double HorizAlign; + + Inkscape::UI::Widget::UnitMenu PaddingUnitMenu; + Inkscape::UI::Widget::ScalarUnit XPadding; + Inkscape::UI::Widget::ScalarUnit YPadding; + +#if WITH_GTKMM_3_0 + Gtk::Grid *PaddingTable; +#else + Gtk::Table *PaddingTable; +#endif + + // BBox or manual spacing + Gtk::VBox SpacingVBox; + Gtk::RadioButtonGroup SpacingGroup; + Gtk::RadioButton SpaceByBBoxRadioButton; + Gtk::RadioButton SpaceManualRadioButton; + bool ManualSpacing; + + // Row height + Gtk::VBox RowHeightVBox; + Gtk::HBox RowHeightBox; + Gtk::Label RowHeightLabel; + Inkscape::UI::Widget::SpinButton RowHeightSpinner; + + // Column width + Gtk::VBox ColumnWidthVBox; + Gtk::HBox ColumnWidthBox; + Gtk::Label ColumnWidthLabel; + Inkscape::UI::Widget::SpinButton ColumnWidthSpinner; +}; + +} //namespace Dialog +} //namespace UI +} //namespace Inkscape + +#endif /* INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_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 : diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index e84f25733..80740113c 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -68,20 +68,6 @@ void GuidelinePropertiesDialog::showDialog(SPGuide *guide, SPDesktop *desktop) { dialog.run(); } -void GuidelinePropertiesDialog::_colorChanged() -{ -#if WITH_GTKMM_3_0 - const Gdk::RGBA c = _color.get_rgba(); - unsigned r = c.get_red_u()/257, g = c.get_green_u()/257, b = c.get_blue_u()/257; -#else - const Gdk::Color c = _color.get_color(); - unsigned r = c.get_red()/257, g = c.get_green()/257, b = c.get_blue()/257; -#endif - //TODO: why 257? verify this! - - sp_guide_set_color(*_guide, r, g, b, true); -} - void GuidelinePropertiesDialog::_modeChanged() { _mode = !_relative_toggle.get_active(); @@ -100,7 +86,7 @@ void GuidelinePropertiesDialog::_modeChanged() } } -void GuidelinePropertiesDialog::_onApply() +void GuidelinePropertiesDialog::_onOK() { double deg_angle = _spin_angle.getValue(DEG); if (!_mode) @@ -124,18 +110,26 @@ void GuidelinePropertiesDialog::_onApply() sp_guide_moveto(*_guide, newpos, true); - const gchar* name = _label_entry.getEntry()->get_text().c_str(); + const gchar* name = g_strdup( _label_entry.getEntry()->get_text().c_str() ); + sp_guide_set_label(*_guide, name, true); + g_free((gpointer) name); + +#if WITH_GTKMM_3_0 + const Gdk::RGBA c = _color.get_rgba(); + unsigned r = c.get_red_u()/257, g = c.get_green_u()/257, b = c.get_blue_u()/257; +#else + const Gdk::Color c = _color.get_color(); + unsigned r = c.get_red()/257, g = c.get_green()/257, b = c.get_blue()/257; +#endif + //TODO: why 257? verify this! + + sp_guide_set_color(*_guide, r, g, b, true); DocumentUndo::done(_guide->document, SP_VERB_NONE, _("Set guide properties")); } -void GuidelinePropertiesDialog::_onOK() -{ - _onApply(); -} - void GuidelinePropertiesDialog::_onDelete() { SPDocument *doc = _guide->document; @@ -157,10 +151,6 @@ void GuidelinePropertiesDialog::_response(gint response) break; case Gtk::RESPONSE_DELETE_EVENT: break; -/* case GTK_RESPONSE_APPLY: - _onApply(); - break; -*/ default: g_assert_not_reached(); } @@ -222,9 +212,6 @@ void GuidelinePropertiesDialog::_setup() { 1, 3, 3, 4, Gtk::EXPAND | Gtk::FILL, Gtk::FILL); #endif - _color.signal_color_set().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_colorChanged)); - - // unitmenus /* fixme: We should allow percents here too, as percents of the canvas size */ _unit_menu.setUnitType(UNIT_TYPE_LINEAR); diff --git a/src/ui/dialog/guides.h b/src/ui/dialog/guides.h index 422fed7fe..22bf5097a 100644 --- a/src/ui/dialog/guides.h +++ b/src/ui/dialog/guides.h @@ -62,13 +62,11 @@ public: protected: void _setup(); - void _onApply(); void _onOK(); void _onDelete(); void _response(gint response); void _modeChanged(); - void _colorChanged(); private: GuidelinePropertiesDialog(GuidelinePropertiesDialog const &); // no copy diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 03108b403..d826ece09 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1534,9 +1534,9 @@ void InkscapePreferences::initKeyboardShortcuts(Gtk::TreeModel::iterator iter_ui row++; #if WITH_GTKMM_3_0 - Gtk::ButtonBox *box_buttons = manage(new Gtk::ButtonBox); + Gtk::ButtonBox *box_buttons = Gtk::manage(new Gtk::ButtonBox); #else - Gtk::HButtonBox *box_buttons = manage (new Gtk::HButtonBox); + Gtk::HButtonBox *box_buttons = Gtk::manage (new Gtk::HButtonBox); #endif box_buttons->set_layout(Gtk::BUTTONBOX_END); @@ -1549,14 +1549,14 @@ void InkscapePreferences::initKeyboardShortcuts(Gtk::TreeModel::iterator iter_ui _page_keyshortcuts.attach(*box_buttons, 0, 3, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK); #endif - UI::Widget::Button *kb_reset = manage(new UI::Widget::Button(_("Reset"), _("Remove all your customized keyboard shortcuts, and revert to the shortcuts in the shortcut file listed above"))); + UI::Widget::Button *kb_reset = Gtk::manage(new UI::Widget::Button(_("Reset"), _("Remove all your customized keyboard shortcuts, and revert to the shortcuts in the shortcut file listed above"))); box_buttons->pack_start(*kb_reset, true, true, 6); box_buttons->set_child_secondary(*kb_reset); - UI::Widget::Button *kb_import = manage(new UI::Widget::Button(_("Import ..."), _("Import custom keyboard shortcuts from a file"))); + UI::Widget::Button *kb_import = Gtk::manage(new UI::Widget::Button(_("Import ..."), _("Import custom keyboard shortcuts from a file"))); box_buttons->pack_end(*kb_import, true, true, 6); - UI::Widget::Button *kb_export = manage(new UI::Widget::Button(_("Export ..."), _("Export custom keyboard shortcuts to a file"))); + UI::Widget::Button *kb_export = Gtk::manage(new UI::Widget::Button(_("Export ..."), _("Export custom keyboard shortcuts to a file"))); box_buttons->pack_end(*kb_export, true, true, 6); kb_reset->signal_clicked().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBReset) ); diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp index 2d4755fd2..4be6716a5 100644 --- a/src/ui/dialog/input.cpp +++ b/src/ui/dialog/input.cpp @@ -1151,9 +1151,9 @@ InputDialogImpl::ConfPanel::ConfPanel() : useExt.signal_toggled().connect(sigc::mem_fun(*this, &InputDialogImpl::ConfPanel::useExtToggled)); #if WITH_GTKMM_3_0 - Gtk::ButtonBox *buttonBox = manage(new Gtk::ButtonBox); + Gtk::ButtonBox *buttonBox = Gtk::manage(new Gtk::ButtonBox); #else - Gtk::HButtonBox *buttonBox = manage (new Gtk::HButtonBox); + Gtk::HButtonBox *buttonBox = Gtk::manage (new Gtk::HButtonBox); #endif buttonBox->set_layout (Gtk::BUTTONBOX_END); diff --git a/src/ui/dialog/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp index f19828b1f..d5540b88a 100644 --- a/src/ui/dialog/layer-properties.cpp +++ b/src/ui/dialog/layer-properties.cpp @@ -213,7 +213,7 @@ LayerPropertiesDialog::_setup_layers_controls() { _tree.set_model( _store ); _tree.set_headers_visible(false); - Inkscape::UI::Widget::ImageToggler *eyeRenderer = manage( new Inkscape::UI::Widget::ImageToggler( + 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; Gtk::TreeViewColumn* col = _tree.get_column(visibleColNum); @@ -221,7 +221,7 @@ LayerPropertiesDialog::_setup_layers_controls() { col->add_attribute( eyeRenderer->property_active(), _model->_colVisible ); } - Inkscape::UI::Widget::ImageToggler * renderer = manage( new Inkscape::UI::Widget::ImageToggler( + 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; col = _tree.get_column(lockedColNum); @@ -229,7 +229,7 @@ LayerPropertiesDialog::_setup_layers_controls() { col->add_attribute( renderer->property_active(), _model->_colLocked ); } - Gtk::CellRendererText *_text_renderer = manage(new Gtk::CellRendererText()); + Gtk::CellRendererText *_text_renderer = Gtk::manage(new Gtk::CellRendererText()); int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; Gtk::TreeView::Column *_name_column = _tree.get_column(nameColNum); _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp index 381810f1e..b5dac0595 100644 --- a/src/ui/dialog/layers.cpp +++ b/src/ui/dialog/layers.cpp @@ -92,7 +92,7 @@ void LayersPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned i if ( iconName ) { GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); + btn.add( *Gtk::manage(Glib::wrap(child)) ); btn.set_relief(Gtk::RELIEF_NONE); set = true; } @@ -104,7 +104,7 @@ void LayersPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned i if ( !set && action && action->image ) { GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); + btn.add( *Gtk::manage(Glib::wrap(child)) ); set = true; } @@ -149,7 +149,7 @@ Gtk::MenuItem& LayersPanel::_addPopupItem( SPDesktop *desktop, unsigned int code Gtk::Widget* wrapped = 0; if ( iconWidget ) { - wrapped = manage(Glib::wrap(iconWidget)); + wrapped = Gtk::manage(Glib::wrap(iconWidget)); wrapped->show(); } @@ -809,7 +809,7 @@ LayersPanel::LayersPanel() : _tree.set_reorderable(true); _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); - Inkscape::UI::Widget::ImageToggler *eyeRenderer = manage( new Inkscape::UI::Widget::ImageToggler( + 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->signal_pre_toggle().connect( sigc::mem_fun(*this, &LayersPanel::_preToggle) ); @@ -821,7 +821,7 @@ LayersPanel::LayersPanel() : } - Inkscape::UI::Widget::ImageToggler * renderer = manage( new Inkscape::UI::Widget::ImageToggler( + 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->signal_pre_toggle().connect( sigc::mem_fun(*this, &LayersPanel::_preToggle) ); @@ -832,7 +832,7 @@ LayersPanel::LayersPanel() : col->add_attribute( renderer->property_active(), _model->_colLocked ); } - _text_renderer = manage(new Gtk::CellRendererText()); + _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); @@ -880,40 +880,40 @@ LayersPanel::LayersPanel() : SPDesktop* targetDesktop = getDesktop(); - Gtk::Button* btn = manage( new Gtk::Button() ); + Gtk::Button* btn = Gtk::manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_NEW, INKSCAPE_ICON("list-add"), C_("Layers", "New") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_NEW) ); _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); - btn = manage( new Gtk::Button() ); + btn = Gtk::manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_BOTTOM, INKSCAPE_ICON("go-bottom"), C_("Layers", "Bot") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_BOTTOM) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); - btn = manage( new Gtk::Button() ); + btn = Gtk::manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_LOWER, INKSCAPE_ICON("go-down"), C_("Layers", "Dn") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DOWN) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); - btn = manage( new Gtk::Button() ); + btn = Gtk::manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_RAISE, INKSCAPE_ICON("go-up"), C_("Layers", "Up") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_UP) ); _watchingNonTop.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); - btn = manage( new Gtk::Button() ); + btn = Gtk::manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_TOP, INKSCAPE_ICON("go-top"), C_("Layers", "Top") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_TOP) ); _watchingNonTop.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); -// btn = manage( new Gtk::Button("Dup") ); +// btn = Gtk::manage( new Gtk::Button("Dup") ); // btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DUPLICATE) ); // _buttonsRow.add( *btn ); - btn = manage( new Gtk::Button() ); + btn = Gtk::manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, INKSCAPE_ICON("list-remove"), _("X") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DELETE) ); _watching.push_back( btn ); @@ -930,19 +930,19 @@ LayersPanel::LayersPanel() : _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_NEW, 0, "New", (int)BUTTON_NEW ) ); - _popupMenu.append(*manage(new Gtk::SeparatorMenuItem())); + _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(*manage(new Gtk::SeparatorMenuItem())); + _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(*manage(new Gtk::SeparatorMenuItem())); + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, INKSCAPE_ICON("go-up"), "Up", (int)BUTTON_UP ) ); _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, INKSCAPE_ICON("go-down"), "Down", (int)BUTTON_DOWN ) ); diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index b81b300e2..0ab2fc9f7 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -172,7 +172,7 @@ LivePathEffectEditor::LivePathEffectEditor() effectlist_selection->signal_changed().connect( sigc::mem_fun(*this, &LivePathEffectEditor::on_effect_selection_changed) ); //Add the visibility icon column: - Inkscape::UI::Widget::ImageToggler *eyeRenderer = manage( new Inkscape::UI::Widget::ImageToggler( + Inkscape::UI::Widget::ImageToggler *eyeRenderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden")) ); int visibleColNum = effectlist_view.append_column("is_visible", *eyeRenderer) - 1; eyeRenderer->signal_toggled().connect( sigc::mem_fun(*this, &LivePathEffectEditor::on_visibility_toggled) ); diff --git a/src/ui/dialog/new-from-template.cpp b/src/ui/dialog/new-from-template.cpp index 71d1c22d0..f326bb3ee 100644 --- a/src/ui/dialog/new-from-template.cpp +++ b/src/ui/dialog/new-from-template.cpp @@ -29,7 +29,7 @@ NewFromTemplate::NewFromTemplate() get_vbox()->pack_start(_main_widget); Gtk::Alignment *align; - align = manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); + align = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); get_vbox()->pack_end(*align, Gtk::PACK_SHRINK); align->set_padding(0, 0, 0, 15); align->add(_create_template_button); diff --git a/src/ui/dialog/pixelartdialog.cpp b/src/ui/dialog/pixelartdialog.cpp index ce5b6584d..31449d4e7 100644 --- a/src/ui/dialog/pixelartdialog.cpp +++ b/src/ui/dialog/pixelartdialog.cpp @@ -16,6 +16,16 @@ # include <config.h> #endif +#ifdef GLIBMM_DISABLE_DEPRECATED +# undef GLIBMM_DISABLE_DEPRECATED +# include <glibmm/thread.h> +# include <glibmm/dispatcher.h> +# define GLIBMM_DISABLE_DEPRECATED 1 +#else // GLIBMM_DISABLE_DEPRECATED +# include <glibmm/thread.h> +# include <glibmm/dispatcher.h> +#endif // GLIBMM_DISABLE_DEPRECATED + #include "pixelartdialog.h" #include <gtkmm/radiobutton.h> #include <gtkmm/stock.h> @@ -54,18 +64,6 @@ namespace Inkscape { namespace UI { namespace Dialog { -template<class T> -T move(T &obj) -{ -#ifdef LIBDEPIXELIZE_ENABLE_CPP11 - return std::move(obj); -#else - T ret; - std::swap(obj, ret); - return ret; -#endif // LIBDEPIXELIZE_ENABLE_CPP11 -} - /** * A dialog for adjusting pixel art -> vector tracing parameters */ @@ -77,6 +75,23 @@ public: ~PixelArtDialogImpl(); private: + struct Input + { + Glib::RefPtr<Gdk::Pixbuf> pixbuf; + SVGLength x; + SVGLength y; + }; + struct Output + { + Output(Tracer::Splines splines, SVGLength x, SVGLength y) : + splines(splines), x(x), y(y) + {} + + Tracer::Splines splines; + SVGLength x; + SVGLength y; + }; + void setDesktop(SPDesktop *desktop); void setTargetDesktop(SPDesktop *desktop); @@ -89,7 +104,8 @@ private: Tracer::Kopf2011::Options options(); void vectorize(); - void processLibdepixelize(SPImage *img); + void processLibdepixelize(const Input &image); + void importOutput(const Output &out); void setDefaults(); void updatePreview(); @@ -133,9 +149,21 @@ private: Gtk::RadioButton optimizeRadioButton; #endif // LIBDEPIXELIZE_INKSCAPE_ENABLE_SMOOTH + //############ UI Logic data + SPDesktop *desktop; DesktopTracker deskTrack; sigc::connection desktopChangeConn; + + //############ Threads + void workerThread(); + void onWorkerThreadFinished(); + Glib::Thread *thread; + volatile gint abortThread; // C++11's atomic stuff is sooo much nicer + Glib::Dispatcher dispatcher; + std::vector<Input> queue; + std::vector<Output> output; + Tracer::Kopf2011::Options lastOptions; }; void PixelArtDialogImpl::setDesktop(SPDesktop *desktop) @@ -288,6 +316,9 @@ PixelArtDialogImpl::PixelArtDialogImpl() : deskTrack.connect(GTK_WIDGET(gobj())); signalResponse().connect(sigc::mem_fun(*this, &PixelArtDialogImpl::responseCallback)); + + dispatcher.connect( + sigc::mem_fun(*this, &PixelArtDialogImpl::onWorkerThreadFinished) ); } void PixelArtDialogImpl::responseCallback(int response_id) @@ -295,7 +326,8 @@ void PixelArtDialogImpl::responseCallback(int response_id) if (response_id == GTK_RESPONSE_OK) { vectorize(); } else if (response_id == GTK_RESPONSE_CANCEL) { - // TODO + // libdepixelize's interface need to be extended to allow aborts + g_atomic_int_set(&abortThread, true); } else if (response_id == GTK_RESPONSE_HELP) { setDefaults(); } else { @@ -340,39 +372,53 @@ void PixelArtDialogImpl::vectorize() return; } - bool found = false; - for ( GSList const *list = desktop->selection->itemList() ; list ; list = list->next ) { if ( !SP_IS_IMAGE(list->data) ) continue; - found = true; + SPImage *img = SP_IMAGE(list->data); + Input input; + input.pixbuf = Glib::wrap(img->pixbuf->getPixbufRaw(), true); + input.x = img->x; + input.y = img->y; + + if ( input.pixbuf->get_width() > 256 + || input.pixbuf->get_height() > 256 ) { + char *msg = _("Image looks too big. Process may take a while and is" + " wise to save your document before continue." + "\n\nContinue the procedure (without saving)?"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_WARNING, + Gtk::BUTTONS_OK_CANCEL, true); + + if ( dialog.run() != Gtk::RESPONSE_OK ) + continue; + } - processLibdepixelize(SP_IMAGE(list->data)); + queue.push_back(input); } - if ( !found ) { + if ( !queue.size() ) { char *msg = _("Select an <b>image</b> to trace"); msgStack->flash(Inkscape::ERROR_MESSAGE, msg); return; } - DocumentUndo::done(desktop->doc(), SP_VERB_SELECTION_PIXEL_ART, - _("Trace pixel art")); + mainCancelButton->set_sensitive(true); + mainOkButton->set_sensitive(false); - // Flush pending updates - desktop->doc()->ensureUpToDate(); + lastOptions = options(); + + g_atomic_int_set(&abortThread, false); + thread = Glib::Thread::create( + sigc::mem_fun(*this, &PixelArtDialogImpl::workerThread) ); } -void PixelArtDialogImpl::processLibdepixelize(SPImage *img) +void PixelArtDialogImpl::processLibdepixelize(const Input &input) { Tracer::Splines out; - Glib::RefPtr<Gdk::Pixbuf> pixbuf - = Glib::wrap(img->pixbuf->getPixbufRaw(), true); - - if ( pixbuf->get_width() > 256 || pixbuf->get_height() > 256 ) { + if ( input.pixbuf->get_width() > 256 || input.pixbuf->get_height() > 256 ) { char *msg = _("Image looks too big. Process may take a while and it is" " wise to save your document before continuing." "\n\nContinue the procedure (without saving)?"); @@ -384,16 +430,23 @@ void PixelArtDialogImpl::processLibdepixelize(SPImage *img) } if ( voronoiRadioButton.get_active() ) { - out = Tracer::Kopf2011::to_voronoi(pixbuf, options()); + output.push_back(Output(Tracer::Kopf2011::to_voronoi(input.pixbuf, + lastOptions), + input.x, input.y)); } else { - out = Tracer::Kopf2011::to_splines(pixbuf, options()); + output.push_back(Output(Tracer::Kopf2011::to_splines(input.pixbuf, + lastOptions), + input.x, input.y)); } +} +void PixelArtDialogImpl::importOutput(const Output &output) +{ Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::XML::Node *group = xml_doc->createElement("svg:g"); - for ( Tracer::Splines::iterator it = out.begin(), end = out.end() - ; it != end ; ++it ) { + for ( Tracer::Splines::const_iterator it = output.splines.begin(), + end = output.splines.end() ; it != end ; ++it ) { Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); { @@ -421,7 +474,7 @@ void PixelArtDialogImpl::processLibdepixelize(SPImage *img) sp_repr_css_attr_unref(css); } - gchar *str = sp_svg_write_path(Dialog::move(it->pathVector)); + gchar *str = sp_svg_write_path(it->pathVector); repr->setAttribute("d", str); g_free(str); @@ -433,14 +486,20 @@ void PixelArtDialogImpl::processLibdepixelize(SPImage *img) { group->setAttribute("transform", (std::string("translate(") - + sp_svg_length_write_with_units(img->x) - + ' ' + sp_svg_length_write_with_units(img->y) + + sp_svg_length_write_with_units(output.x) + + ' ' + sp_svg_length_write_with_units(output.y) + ')').c_str()); } desktop->currentLayer()->appendChildRepr(group); Inkscape::GC::release(group); + + DocumentUndo::done(desktop->doc(), SP_VERB_SELECTION_PIXEL_ART, + _("Trace pixel art")); + + // Flush pending updates + desktop->doc()->ensureUpToDate(); } void PixelArtDialogImpl::setDefaults() @@ -481,6 +540,29 @@ void PixelArtDialogImpl::updatePreview() pendingPreview = false; } +void PixelArtDialogImpl::workerThread() +{ + for ( std::vector<Input>::iterator it = queue.begin(), end = queue.end() + ; it != end && !g_atomic_int_get(&abortThread) ; ++it ) { + processLibdepixelize(*it); + } + queue.clear(); + dispatcher(); +} + +void PixelArtDialogImpl::onWorkerThreadFinished() +{ + thread->join(); + thread = NULL; + for ( std::vector<Output>::const_iterator it = output.begin(), + end = output.end() ; it != end ; ++it ) { + importOutput(*it); + } + output.clear(); + mainCancelButton->set_sensitive(false); + mainOkButton->set_sensitive(true); +} + /** * Factory method. Use this to create a new PixelArtDialog */ diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp new file mode 100644 index 000000000..a00b8fc02 --- /dev/null +++ b/src/ui/dialog/polar-arrange-tab.cpp @@ -0,0 +1,414 @@ +/** + * @brief Arranges Objects into a Circle/Ellipse + */ +/* Authors: + * Declara Denis + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "ui/dialog/polar-arrange-tab.h" +#include "ui/dialog/tile.h" + +#include <2geom/transforms.h> +#include <glibmm/i18n.h> + +#include "verbs.h" +#include "preferences.h" +#include "inkscape.h" +#include "desktop-handles.h" +#include "selection.h" +#include "document.h" +#include "document-undo.h" +#include "sp-item.h" +#include "widgets/icon.h" +#include "desktop.h" +#include "sp-ellipse.h" +#include "sp-item-transform.h" + +namespace Inkscape { +namespace UI { +namespace Dialog { + +PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) + : parent(parent_), + parametersTable(3, 3, false), + centerY("", "Y coordinate of the center", UNIT_TYPE_LINEAR), + centerX("", "X coordinate of the center", centerY), + radiusY("", "Y coordinate of the radius", UNIT_TYPE_LINEAR), + radiusX("", "X coordinate of the radius", radiusY), + angleY("", "Starting angle", UNIT_TYPE_RADIAL), + angleX("", "End angle", angleY) +{ + anchorPointLabel.set_text(C_("Polar arrange tab", "Anchor point:")); + anchorPointLabel.set_alignment(Gtk::ALIGN_START); + pack_start(anchorPointLabel, false, false); + + anchorBoundingBoxRadio.set_label(C_("Polar arrange tab", "Object's bounding box:")); + anchorRadioGroup = anchorBoundingBoxRadio.get_group(); + anchorBoundingBoxRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_anchor_radio_changed)); + pack_start(anchorBoundingBoxRadio, false, false); + + pack_start(anchorSelector, false, false); + + anchorObjectPivotRadio.set_label(C_("Polar arrange tab", "Object's rotational center")); + anchorObjectPivotRadio.set_group(anchorRadioGroup); + anchorObjectPivotRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_anchor_radio_changed)); + pack_start(anchorObjectPivotRadio, false, false); + + arrangeOnLabel.set_text(C_("Polar arrange tab", "Arrange on:")); + arrangeOnLabel.set_alignment(Gtk::ALIGN_START); + pack_start(arrangeOnLabel, false, false); + + arrangeOnFirstCircleRadio.set_label(C_("Polar arrange tab", "First selected circle/ellipse/arc")); + arrangeRadioGroup = arrangeOnFirstCircleRadio.get_group(); + arrangeOnFirstCircleRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_arrange_radio_changed)); + pack_start(arrangeOnFirstCircleRadio, false, false); + + arrangeOnLastCircleRadio.set_label(C_("Polar arrange tab", "Last selected circle/ellipse/arc")); + arrangeOnLastCircleRadio.set_group(arrangeRadioGroup); + arrangeOnLastCircleRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_arrange_radio_changed)); + pack_start(arrangeOnLastCircleRadio, false, false); + + arrangeOnParametersRadio.set_label(C_("Polar arrange tab", "Parameterized:")); + arrangeOnParametersRadio.set_group(arrangeRadioGroup); + arrangeOnParametersRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_arrange_radio_changed)); + pack_start(arrangeOnParametersRadio, false, false); + + centerLabel.set_text(_("Center X/Y:")); + parametersTable.attach(centerLabel, 0, 1, 0, 1, Gtk::FILL); + centerX.setDigits(2); + centerX.setIncrements(0.2, 0); + centerX.setRange(-10000, 10000); + centerX.setValue(0, "px"); + centerY.setDigits(2); + centerY.setIncrements(0.2, 0); + centerY.setRange(-10000, 10000); + centerY.setValue(0, "px"); + parametersTable.attach(centerX, 1, 2, 0, 1, Gtk::FILL); + parametersTable.attach(centerY, 2, 3, 0, 1, Gtk::FILL); + + radiusLabel.set_text(_("Radius X/Y:")); + parametersTable.attach(radiusLabel, 0, 1, 1, 2, Gtk::FILL); + radiusX.setDigits(2); + radiusX.setIncrements(0.2, 0); + radiusX.setRange(0.001, 10000); + radiusX.setValue(100, "px"); + radiusY.setDigits(2); + radiusY.setIncrements(0.2, 0); + radiusY.setRange(0.001, 10000); + radiusY.setValue(100, "px"); + parametersTable.attach(radiusX, 1, 2, 1, 2, Gtk::FILL); + parametersTable.attach(radiusY, 2, 3, 1, 2, Gtk::FILL); + + angleLabel.set_text(_("Angle X/Y:")); + parametersTable.attach(angleLabel, 0, 1, 2, 3, Gtk::FILL); + angleX.setDigits(2); + angleX.setIncrements(0.2, 0); + angleX.setRange(-10000, 10000); + angleX.setValue(0, "°"); + angleY.setDigits(2); + angleY.setIncrements(0.2, 0); + angleY.setRange(-10000, 10000); + angleY.setValue(180, "°"); + parametersTable.attach(angleX, 1, 2, 2, 3, Gtk::FILL); + parametersTable.attach(angleY, 2, 3, 2, 3, Gtk::FILL); + pack_start(parametersTable, false, false); + + rotateObjectsCheckBox.set_label(_("Rotate objects")); + rotateObjectsCheckBox.set_active(true); + pack_start(rotateObjectsCheckBox, false, false); + + centerX.set_sensitive(false); + centerY.set_sensitive(false); + angleX.set_sensitive(false); + angleY.set_sensitive(false); + radiusX.set_sensitive(false); + radiusY.set_sensitive(false); +} + +/** + * This function rotates an item around a given point by a given amount + * @param item item to rotate + * @param center center of the rotation to perform + * @param rotation amount to rotate the object by + */ +static void rotateAround(SPItem *item, Geom::Point center, Geom::Rotate const &rotation) +{ + Geom::Translate const s(center); + Geom::Affine affine = Geom::Affine(s).inverse() * Geom::Affine(rotation) * Geom::Affine(s); + + // Save old center + center = item->getCenter(); + + item->set_i2d_affine(item->i2dt_affine() * affine); + item->doWriteTransform(item->getRepr(), item->transform); + + if(item->isCenterSet()) + { + item->setCenter(center * affine); + item->updateRepr(); + } +} + +/** + * Calculates the angle at which to put an object given the total amount + * of objects, the index of the objects as well as the arc start and end + * points + * @param arcBegin angle at which the arc begins + * @param arcEnd angle at which the arc ends + * @param count number of objects in the selection + * @param n index of the object in the selection + */ +static float calcAngle(float arcBegin, float arcEnd, int count, int n) +{ + float arcLength = arcEnd - arcBegin; + float delta = std::abs(std::abs(arcLength) - 2*M_PI); + if(delta > 0.01) count--; // If not a complete circle, put an object also at the extremes of the arc; + + float angle = n / (float)count; + // Normalize for arcLength: + angle = angle * arcLength; + angle += arcBegin; + + return angle; +} + +/** + * Calculates the point at which an object needs to be, given the center of the ellipse, + * it's radius (x and y), as well as the angle + */ +static Geom::Point calcPoint(float cx, float cy, float rx, float ry, float angle) +{ + return Geom::Point(cx + cos(angle) * rx, cy + sin(angle) * ry); +} + +/** + * Returns the selected anchor point in document coordinates. If anchor + * is 0 to 8, then a bounding box point has been choosen. If it is 9 however + * the rotational center is chosen. + * @todo still using a hack to get the real coordinate space (subtracting document height + * and inverting axes) + */ +static Geom::Point getAnchorPoint(int anchor, SPItem *item) +{ + Geom::Point source; + + Geom::OptRect bbox = item->documentVisualBounds(); + + switch(anchor) + { + case 0: // Top - Left + case 3: // Middle - Left + case 6: // Bottom - Left + source[0] = bbox->min()[Geom::X]; + break; + case 1: // Top - Middle + case 4: // Middle - Middle + case 7: // Bottom - Middle + source[0] = (bbox->min()[Geom::X] + bbox->max()[Geom::X]) / 2.0f; + break; + case 2: // Top - Right + case 5: // Middle - Right + case 8: // Bottom - Right + source[0] = bbox->max()[Geom::X]; + break; + }; + + switch(anchor) + { + case 0: // Top - Left + case 1: // Top - Middle + case 2: // Top - Right + source[1] = bbox->min()[Geom::Y]; + break; + case 3: // Middle - Left + case 4: // Middle - Middle + case 5: // Middle - Right + source[1] = (bbox->min()[Geom::Y] + bbox->max()[Geom::Y]) / 2.0f; + break; + case 6: // Bottom - Left + case 7: // Bottom - Middle + case 8: // Bottom - Right + source[1] = bbox->max()[Geom::Y]; + break; + }; + + // If using center + if(anchor == 9) + source = item->getCenter(); + else + { + // FIXME: + source[1] -= item->document->getHeight().value("px"); + source[1] *= -1; + } + + return source; +} + +/** + * Moves an SPItem to a given location, the location is based on the given anchor point. + * @param anchor 0 to 8 are the various bounding box points like follows: + * 0 1 2 + * 3 4 5 + * 6 7 8 + * Anchor mode 9 is the rotational center of the object + * @param item Item to move + * @param p point at which to move the object + */ +static void moveToPoint(int anchor, SPItem *item, Geom::Point p) +{ + sp_item_move_rel(item, Geom::Translate(p - getAnchorPoint(anchor, item))); +} + +void PolarArrangeTab::arrange() +{ + Inkscape::Selection *selection = sp_desktop_selection(parent->getDesktop()); + const GSList *items, *tmp; + tmp = items = selection->itemList(); + SPGenericEllipse *referenceEllipse = NULL; // Last ellipse in selection + + bool arrangeOnEllipse = !arrangeOnParametersRadio.get_active(); + bool arrangeOnFirstEllipse = arrangeOnEllipse && arrangeOnFirstCircleRadio.get_active(); + + int count = 0; + while(tmp) + { + if(arrangeOnEllipse) + { + SPItem *item = SP_ITEM(tmp->data); + + if(arrangeOnFirstEllipse) + { + // The first selected ellipse is actually the last one in the list + if(SP_IS_GENERICELLIPSE(item)) + referenceEllipse = SP_GENERICELLIPSE(item); + } else { + // The last selected ellipse is actually the first in list + if(SP_IS_GENERICELLIPSE(item) && referenceEllipse == NULL) + referenceEllipse = SP_GENERICELLIPSE(item); + } + } + tmp = tmp->next; + ++count; + } + + float cx, cy; // Center of the ellipse + float rx, ry; // Radiuses of the ellipse in x and y direction + float arcBeg, arcEnd; // begin and end angles for arcs + Geom::Affine transformation; // Any additional transformation to apply to the objects + + if(arrangeOnEllipse) + { + if(referenceEllipse == NULL) + { + Gtk::MessageDialog dialog(_("Couldn't find an ellipse in selection"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true); + dialog.run(); + return; + } else { + cx = referenceEllipse->cx.value; + cy = referenceEllipse->cy.value; + rx = referenceEllipse->rx.value; + ry = referenceEllipse->ry.value; + arcBeg = referenceEllipse->start; + arcEnd = referenceEllipse->end; + + transformation = referenceEllipse->i2dt_affine(); + + // We decrement the count by 1 as we are not going to lay + // out the reference ellipse + --count; + } + + } else { + // Read options from UI + cx = centerX.getValue("px"); + cy = centerY.getValue("px"); + rx = radiusX.getValue("px"); + ry = radiusY.getValue("px"); + arcBeg = angleX.getValue("rad"); + arcEnd = angleY.getValue("rad"); + transformation.setIdentity(); + referenceEllipse = NULL; + } + + int anchor = 9; + if(anchorBoundingBoxRadio.get_active()) + { + anchor = anchorSelector.getHorizontalAlignment() + + anchorSelector.getVerticalAlignment() * 3; + } + + Geom::Point realCenter = Geom::Point(cx, cy) * transformation; + + tmp = items; + int i = 0; + while(tmp) + { + SPItem *item = SP_ITEM(tmp->data); + + // Ignore the reference ellipse if any + if(item != referenceEllipse) + { + float angle = calcAngle(arcBeg, arcEnd, count, i); + Geom::Point newLocation = calcPoint(cx, cy, rx, ry, angle) * transformation; + + moveToPoint(anchor, item, newLocation); + + if(rotateObjectsCheckBox.get_active()) { + // Calculate the angle by which to rotate each object + angle = -atan2f(newLocation.x() - realCenter.x(), newLocation.y() - realCenter.y()); + rotateAround(item, newLocation, Geom::Rotate(angle)); + } + + ++i; + } + tmp = tmp->next; + } + + DocumentUndo::done(sp_desktop_document(parent->getDesktop()), SP_VERB_SELECTION_ARRANGE, + _("Arrange on ellipse")); +} + +void PolarArrangeTab::updateSelection() +{ +} + +void PolarArrangeTab::on_arrange_radio_changed() +{ + bool arrangeParametric = arrangeOnParametersRadio.get_active(); + + centerX.set_sensitive(arrangeParametric); + centerY.set_sensitive(arrangeParametric); + + angleX.set_sensitive(arrangeParametric); + angleY.set_sensitive(arrangeParametric); + + radiusX.set_sensitive(arrangeParametric); + radiusY.set_sensitive(arrangeParametric); + + parametersTable.set_visible(arrangeParametric); +} + +void PolarArrangeTab::on_anchor_radio_changed() +{ + bool anchorBoundingBox = anchorBoundingBoxRadio.get_active(); + + anchorSelector.set_sensitive(anchorBoundingBox); +} + +} //namespace Dialog +} //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 : diff --git a/src/ui/dialog/polar-arrange-tab.h b/src/ui/dialog/polar-arrange-tab.h new file mode 100644 index 000000000..bfed40bbd --- /dev/null +++ b/src/ui/dialog/polar-arrange-tab.h @@ -0,0 +1,100 @@ +/** + * @brief Arranges Objects into a Circle/Ellipse + */ +/* Authors: + * Declara Denis + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H +#define INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H + +#include "ui/dialog/arrange-tab.h" + +#include "ui/widget/anchor-selector.h" +#include "ui/widget/scalar-unit.h" + +namespace Inkscape { +namespace UI { +namespace Dialog { + +class ArrangeDialog; + +/** + * PolarArrangeTab is a Tab displayed in the Arrange dialog and contains + * enables the user to arrange objects on a circular or elliptical shape + */ +class PolarArrangeTab : public ArrangeTab { +public: + PolarArrangeTab(ArrangeDialog *parent_); + virtual ~PolarArrangeTab() {}; + + /** + * Do the actual arrangement + */ + virtual void arrange(); + + /** + * Respond to selection change + */ + void updateSelection(); + + void on_anchor_radio_changed(); + void on_arrange_radio_changed(); + +private: + PolarArrangeTab(PolarArrangeTab const &d); // no copy + void operator=(PolarArrangeTab const &d); // no assign + + ArrangeDialog *parent; + + Gtk::Label anchorPointLabel; + + Gtk::RadioButtonGroup anchorRadioGroup; + Gtk::RadioButton anchorBoundingBoxRadio; + Gtk::RadioButton anchorObjectPivotRadio; + Inkscape::UI::Widget::AnchorSelector anchorSelector; + + Gtk::Label arrangeOnLabel; + + Gtk::RadioButtonGroup arrangeRadioGroup; + Gtk::RadioButton arrangeOnFirstCircleRadio; + Gtk::RadioButton arrangeOnLastCircleRadio; + Gtk::RadioButton arrangeOnParametersRadio; + + Gtk::Table parametersTable; + + Gtk::Label centerLabel; + Inkscape::UI::Widget::ScalarUnit centerY; + Inkscape::UI::Widget::ScalarUnit centerX; + + Gtk::Label radiusLabel; + Inkscape::UI::Widget::ScalarUnit radiusY; + Inkscape::UI::Widget::ScalarUnit radiusX; + + Gtk::Label angleLabel; + Inkscape::UI::Widget::ScalarUnit angleY; + Inkscape::UI::Widget::ScalarUnit angleX; + + Gtk::CheckButton rotateObjectsCheckBox; + + +}; + +} //namespace Dialog +} //namespace UI +} //namespace Inkscape + +#endif /* INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_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 : diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 5e77a28ab..4f0cb211a 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -645,7 +645,7 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath) : std::vector<SwatchPage*> swatchSets = _getSwatchSets(); for ( std::vector<SwatchPage*>::iterator it = swatchSets.begin(); it != swatchSets.end(); ++it) { SwatchPage* curr = *it; - Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, curr->_name)); + Gtk::RadioMenuItem* single = Gtk::manage(new Gtk::RadioMenuItem(groupOne, curr->_name)); if ( curr == first ) { hotItem = single; } diff --git a/src/ui/dialog/template-load-tab.cpp b/src/ui/dialog/template-load-tab.cpp index 6b1f4542f..d75f81456 100644 --- a/src/ui/dialog/template-load-tab.cpp +++ b/src/ui/dialog/template-load-tab.cpp @@ -42,10 +42,10 @@ TemplateLoadTab::TemplateLoadTab() { set_border_width(10); - _info_widget = manage(new TemplateWidget()); + _info_widget = Gtk::manage(new TemplateWidget()); Gtk::Label *title; - title = manage(new Gtk::Label(_("Search:"))); + title = Gtk::manage(new Gtk::Label(_("Search:"))); _search_box.pack_start(*title, Gtk::PACK_SHRINK); _search_box.pack_start(_keywords_combo, Gtk::PACK_SHRINK, 5); @@ -55,7 +55,7 @@ TemplateLoadTab::TemplateLoadTab() pack_start(*_info_widget, Gtk::PACK_EXPAND_WIDGET, 5); Gtk::ScrolledWindow *scrolled; - scrolled = manage(new Gtk::ScrolledWindow()); + scrolled = Gtk::manage(new Gtk::ScrolledWindow()); scrolled->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); scrolled->add(_tlist_view); _tlist_box.pack_start(*scrolled, Gtk::PACK_EXPAND_WIDGET, 5); diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index d8e6f9b4f..ef91962d4 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -47,7 +47,7 @@ TemplateWidget::TemplateWidget() _short_description_label.set_line_wrap(true); Gtk::Alignment *align; - align = manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); + align = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); pack_end(*align, Gtk::PACK_SHRINK); align->add(_more_info_button); diff --git a/src/ui/dialog/tile.cpp b/src/ui/dialog/tile.cpp index c35d3b554..a3cffb3d4 100644 --- a/src/ui/dialog/tile.cpp +++ b/src/ui/dialog/tile.cpp @@ -6,878 +6,62 @@ * John Cliff * Other dudes from The Inkscape Organization * Abhishek Sharma + * Declara Denis * * Copyright (C) 2004 Bob Jamison * Copyright (C) 2004 John Cliff * * Released under GNU GPL, read the file 'COPYING' for more information */ -//#define DEBUG_GRID_ARRANGE 1 -#include "tile.h" -#include <gtk/gtk.h> //for GTK_RESPONSE* types -#include <glibmm/i18n.h> -#include <gtkmm/stock.h> +#include "ui/dialog/grid-arrange-tab.h" +#include "ui/dialog/polar-arrange-tab.h" -#if WITH_GTKMM_3_0 -# include <gtkmm/grid.h> -#else -# include <gtkmm/table.h> -#endif - -#include <2geom/transforms.h> +#include <glibmm/i18n.h> +#include "tile.h" #include "verbs.h" -#include "preferences.h" -#include "inkscape.h" -#include "desktop-handles.h" -#include "selection.h" -#include "document.h" -#include "document-undo.h" -#include "sp-item.h" -#include "widgets/icon.h" -#include "desktop.h" - -/* - * Sort items by their x co-ordinates, taking account of y (keeps rows intact) - * - * <0 *elem1 goes before *elem2 - * 0 *elem1 == *elem2 - * >0 *elem1 goes after *elem2 - */ -static int sp_compare_x_position(SPItem *first, SPItem *second) -{ - using Geom::X; - using Geom::Y; - - Geom::OptRect a = first->documentVisualBounds(); - Geom::OptRect b = second->documentVisualBounds(); - - if ( !a || !b ) { - // FIXME? - return 0; - } - - double const a_height = a->dimensions()[Y]; - double const b_height = b->dimensions()[Y]; - - bool a_in_b_vert = false; - if ((a->min()[Y] < b->min()[Y] + 0.1) && (a->min()[Y] > b->min()[Y] - b_height)) { - a_in_b_vert = true; - } else if ((b->min()[Y] < a->min()[Y] + 0.1) && (b->min()[Y] > a->min()[Y] - a_height)) { - a_in_b_vert = true; - } else if (b->min()[Y] == a->min()[Y]) { - a_in_b_vert = true; - } else { - a_in_b_vert = false; - } - - if (!a_in_b_vert) { - return -1; - } - if (a_in_b_vert && a->min()[X] > b->min()[X]) { - return 1; - } - if (a_in_b_vert && a->min()[X] < b->min()[X]) { - return -1; - } - return 0; -} - -/* - * Sort items by their y co-ordinates. - */ -static int -sp_compare_y_position(SPItem *first, SPItem *second) -{ - Geom::OptRect a = first->documentVisualBounds(); - Geom::OptRect b = second->documentVisualBounds(); - - if ( !a || !b ) { - // FIXME? - return 0; - } - - if (a->min()[Geom::Y] > b->min()[Geom::Y]) { - return 1; - } - if (a->min()[Geom::Y] < b->min()[Geom::Y]) { - return -1; - } - - return 0; -} namespace Inkscape { namespace UI { namespace Dialog { - -//######################################################################### -//## E V E N T S -//######################################################################### - -/* - * - * This arranges the selection in a grid pattern. - * - */ - -void TileDialog::Grid_Arrange () +ArrangeDialog::ArrangeDialog() + : UI::Widget::Panel("", "/dialogs/gridtiler", SP_VERB_SELECTION_ARRANGE), + _gridArrangeTab(new GridArrangeTab(this)), + _polarArrangeTab(new PolarArrangeTab(this)) { + Gtk::Box *contents = this->_getContents(); - int cnt,row_cnt,col_cnt,a,row,col; - double grid_left,grid_top,col_width,row_height,paddingx,paddingy,width, height, new_x, new_y; - double total_col_width,total_row_height; - col_width = 0; - row_height = 0; - total_col_width=0; - total_row_height=0; - - // check for correct numbers in the row- and col-spinners - on_col_spinbutton_changed(); - on_row_spinbutton_changed(); - - // set padding to manual values - paddingx = XPadding.getValue("px"); - paddingy = YPadding.getValue("px"); - - std::vector<double> row_heights; - std::vector<double> col_widths; - std::vector<double> row_ys; - std::vector<double> col_xs; - - int NoOfCols = NoOfColsSpinner.get_value_as_int(); - int NoOfRows = NoOfRowsSpinner.get_value_as_int(); - - width = 0; - for (a=0;a<NoOfCols; a++){ - col_widths.push_back(width); - } - - height = 0; - for (a=0;a<NoOfRows; a++){ - row_heights.push_back(height); - } - grid_left = 99999; - grid_top = 99999; - - SPDesktop *desktop = getDesktop(); - sp_desktop_document(desktop)->ensureUpToDate(); - - Inkscape::Selection *selection = sp_desktop_selection (desktop); - const GSList *items = selection ? selection->itemList() : 0; - cnt=0; - for (; items != NULL; items = items->next) { - SPItem *item = SP_ITEM(items->data); - Geom::OptRect b = item->documentVisualBounds(); - if (!b) { - continue; - } - - width = b->dimensions()[Geom::X]; - height = b->dimensions()[Geom::Y]; - - if (b->min()[Geom::X] < grid_left) { - grid_left = b->min()[Geom::X]; - } - if (b->min()[Geom::Y] < grid_top) { - grid_top = b->min()[Geom::Y]; - } - if (width > col_width) { - col_width = width; - } - if (height > row_height) { - row_height = height; - } - } - - - // require the sorting done before we can calculate row heights etc. - - g_return_if_fail(selection); - const GSList *items2 = selection->itemList(); - GSList *rev = g_slist_copy(const_cast<GSList *>(items2)); - GSList *sorted = NULL; - rev = g_slist_sort(rev, (GCompareFunc) sp_compare_y_position); - sorted = g_slist_sort(rev, (GCompareFunc) sp_compare_x_position); - - - // Calculate individual Row and Column sizes if necessary - - - cnt=0; - const GSList *sizes = sorted; - for (; sizes != NULL; sizes = sizes->next) { - SPItem *item = SP_ITEM(sizes->data); - Geom::OptRect b = item->documentVisualBounds(); - if (b) { - width = b->dimensions()[Geom::X]; - height = b->dimensions()[Geom::Y]; - if (width > col_widths[(cnt % NoOfCols)]) { - col_widths[(cnt % NoOfCols)] = width; - } - if (height > row_heights[(cnt / NoOfCols)]) { - row_heights[(cnt / NoOfCols)] = height; - } - } - - cnt++; - } - - - /// Make sure the top and left of the grid dont move by compensating for align values. - if (RowHeightButton.get_active()){ - grid_top = grid_top - (((row_height - row_heights[0]) / 2)*(VertAlign)); - } - if (ColumnWidthButton.get_active()){ - grid_left = grid_left - (((col_width - col_widths[0]) /2)*(HorizAlign)); - } - - #ifdef DEBUG_GRID_ARRANGE - g_print("\n cx = %f cy= %f gridleft=%f",cx,cy,grid_left); - #endif - - // Calculate total widths and heights, allowing for columns and rows non uniformly sized. + _notebook.append_page(*_gridArrangeTab, C_("Arrange dialog", "Rectangular grid")); + _notebook.append_page(*_polarArrangeTab, C_("Arrange dialog", "Polar Coordinates")); + _arrangeBox.pack_start(_notebook); - if (ColumnWidthButton.get_active()){ - total_col_width = col_width * NoOfCols; - col_widths.clear(); - for (a=0;a<NoOfCols; a++){ - col_widths.push_back(col_width); - } - } else { - for (a = 0; a < (int)col_widths.size(); a++) - { - total_col_width += col_widths[a] ; - } - } - - if (RowHeightButton.get_active()){ - total_row_height = row_height * NoOfRows; - row_heights.clear(); - for (a=0;a<NoOfRows; a++){ - row_heights.push_back(row_height); - } - } else { - for (a = 0; a < (int)row_heights.size(); a++) - { - total_row_height += row_heights[a] ; - } - } - - - Geom::OptRect sel_bbox = selection->visualBounds(); - // Fit to bbox, calculate padding between rows accordingly. - if ( sel_bbox && !SpaceManualRadioButton.get_active() ){ -#ifdef DEBUG_GRID_ARRANGE -g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_height,total_col_width, b.extent(Geom::X), b.extent(Geom::Y)); -#endif - paddingx = (sel_bbox->width() - total_col_width) / (NoOfCols -1); - paddingy = (sel_bbox->height() - total_row_height) / (NoOfRows -1); - } - -/* - Horizontal align - Left = 0 - Centre = 1 - Right = 2 - - Vertical align - Top = 0 - Middle = 1 - Bottom = 2 - - X position is calculated by taking the grids left co-ord, adding the distance to the column, - then adding 1/2 the spacing multiplied by the align variable above, - Y position likewise, takes the top of the grid, adds the y to the current row then adds the padding in to align it. - -*/ - - // Calculate row and column x and y coords required to allow for columns and rows which are non uniformly sized. - - for (a=0;a<NoOfCols; a++){ - if (a<1) col_xs.push_back(0); - else col_xs.push_back(col_widths[a-1]+paddingx+col_xs[a-1]); - } - - - for (a=0;a<NoOfRows; a++){ - if (a<1) row_ys.push_back(0); - else row_ys.push_back(row_heights[a-1]+paddingy+row_ys[a-1]); - } - - cnt=0; - for (row_cnt=0; ((sorted != NULL) && (row_cnt<NoOfRows)); row_cnt++) { - - GSList *current_row = NULL; - for (col_cnt = 0; ((sorted != NULL) && (col_cnt<NoOfCols)); col_cnt++) { - current_row = g_slist_append (current_row, sorted->data); - sorted = sorted->next; - } - - for (; current_row != NULL; current_row = current_row->next) { - SPItem *item=SP_ITEM(current_row->data); - Inkscape::XML::Node *repr = item->getRepr(); - Geom::OptRect b = item->documentVisualBounds(); - Geom::Point min; - if (b) { - width = b->dimensions()[Geom::X]; - height = b->dimensions()[Geom::Y]; - min = b->min(); - } else { - width = height = 0; - min = Geom::Point(0, 0); - } - - row = cnt / NoOfCols; - col = cnt % NoOfCols; - - new_x = grid_left + (((col_widths[col] - width)/2)*HorizAlign) + col_xs[col]; - new_y = grid_top + (((row_heights[row] - height)/2)*VertAlign) + row_ys[row]; - - // signs are inverted between x and y due to y inversion - Geom::Point move = Geom::Point(new_x - min[Geom::X], min[Geom::Y] - new_y); - Geom::Affine const affine = Geom::Affine(Geom::Translate(move)); - item->set_i2d_affine(item->i2dt_affine() * affine); - item->doWriteTransform(repr, item->transform, NULL); - SP_OBJECT (current_row->data)->updateRepr(); - cnt +=1; - } - g_slist_free (current_row); - } - - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_GRIDTILE, - _("Arrange in a grid")); - -} - - -//######################################################################### -//## E V E N T S -//######################################################################### - - -void TileDialog::_apply() -{ - Grid_Arrange(); -} - - -/** - * changed value in # of columns spinbox. - */ -void TileDialog::on_row_spinbutton_changed() -{ - // quit if run by the attr_changed listener - if (updating) { - return; - } - - // in turn, prevent listener from responding - updating = true; - SPDesktop *desktop = getDesktop(); - - Inkscape::Selection *selection = desktop ? desktop->selection : 0; - g_return_if_fail( selection ); - - GSList const *items = selection->itemList(); - int selcount = g_slist_length((GSList *)items); - - double PerCol = ceil(selcount / NoOfColsSpinner.get_value()); - NoOfRowsSpinner.set_value(PerCol); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/dialogs/gridtiler/NoOfCols", NoOfColsSpinner.get_value()); - updating=false; -} - -/** - * changed value in # of rows spinbox. - */ -void TileDialog::on_col_spinbutton_changed() -{ - // quit if run by the attr_changed listener - if (updating) { - return; - } - - // in turn, prevent listener from responding - updating = true; - SPDesktop *desktop = getDesktop(); - Inkscape::Selection *selection = desktop ? desktop->selection : 0; - g_return_if_fail(selection); - - GSList const *items = selection->itemList(); - int selcount = g_slist_length((GSList *)items); - - double PerRow = ceil(selcount / NoOfRowsSpinner.get_value()); - NoOfColsSpinner.set_value(PerRow); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/dialogs/gridtiler/NoOfCols", PerRow); - - updating=false; + _arrangeButton = this->addResponseButton(C_("Arrange dialog","_Arrange"), GTK_RESPONSE_APPLY); + _arrangeButton->set_use_underline(true); + _arrangeButton->set_tooltip_text(_("Arrange selected objects")); + contents->pack_start(_arrangeBox); + //show_all_children(); } -/** - * changed value in x padding spinbox. - */ -void TileDialog::on_xpad_spinbutton_changed() -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/dialogs/gridtiler/XPad", XPadding.getValue("px")); -} - -/** - * changed value in y padding spinbox. - */ -void TileDialog::on_ypad_spinbutton_changed() +void ArrangeDialog::on_show() { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/dialogs/gridtiler/YPad", YPadding.getValue("px")); + UI::Widget::Panel::on_show(); + _polarArrangeTab->on_arrange_radio_changed(); } - -/** - * checked/unchecked autosize Rows button. - */ -void TileDialog::on_RowSize_checkbutton_changed() +void ArrangeDialog::_apply() { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (RowHeightButton.get_active()) { - prefs->setDouble("/dialogs/gridtiler/AutoRowSize", 20); - } else { - prefs->setDouble("/dialogs/gridtiler/AutoRowSize", -20); - } - RowHeightBox.set_sensitive ( !RowHeightButton.get_active()); -} - -/** - * checked/unchecked autosize Rows button. - */ -void TileDialog::on_ColSize_checkbutton_changed() -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (ColumnWidthButton.get_active()) { - prefs->setDouble("/dialogs/gridtiler/AutoColSize", 20); - } else { - prefs->setDouble("/dialogs/gridtiler/AutoColSize", -20); - } - ColumnWidthBox.set_sensitive ( !ColumnWidthButton.get_active()); -} - -/** - * changed value in columns spinbox. - */ -void TileDialog::on_rowSize_spinbutton_changed() -{ - // quit if run by the attr_changed listener - if (updating) { - return; - } - - // in turn, prevent listener from responding - updating = true; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/dialogs/gridtiler/RowHeight", RowHeightSpinner.get_value()); - updating=false; - -} - -/** - * changed value in rows spinbox. - */ -void TileDialog::on_colSize_spinbutton_changed() -{ - // quit if run by the attr_changed listener - if (updating) { - return; - } - - // in turn, prevent listener from responding - updating = true; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/dialogs/gridtiler/ColWidth", ColumnWidthSpinner.get_value()); - updating=false; - -} - -/** - * changed Radio button in Spacing group. - */ -void TileDialog::Spacing_button_changed() -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (SpaceManualRadioButton.get_active()) { - prefs->setDouble("/dialogs/gridtiler/SpacingType", 20); - } else { - prefs->setDouble("/dialogs/gridtiler/SpacingType", -20); - } - - XPadding.set_sensitive ( SpaceManualRadioButton.get_active()); - YPadding.set_sensitive ( SpaceManualRadioButton.get_active()); -} - -/** - * changed Radio button in Vertical Align group. - */ -void TileDialog::VertAlign_changed() -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (VertTopRadioButton.get_active()) { - VertAlign = 0; - prefs->setInt("/dialogs/gridtiler/VertAlign", 0); - } else if (VertCentreRadioButton.get_active()){ - VertAlign = 1; - prefs->setInt("/dialogs/gridtiler/VertAlign", 1); - } else if (VertBotRadioButton.get_active()){ - VertAlign = 2; - prefs->setInt("/dialogs/gridtiler/VertAlign", 2); - } -} - -/** - * changed Radio button in Vertical Align group. - */ -void TileDialog::HorizAlign_changed() -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (HorizLeftRadioButton.get_active()) { - HorizAlign = 0; - prefs->setInt("/dialogs/gridtiler/HorizAlign", 0); - } else if (HorizCentreRadioButton.get_active()){ - HorizAlign = 1; - prefs->setInt("/dialogs/gridtiler/HorizAlign", 1); - } else if (HorizRightRadioButton.get_active()){ - HorizAlign = 2; - prefs->setInt("/dialogs/gridtiler/HorizAlign", 2); - } -} - -/** - * Desktop selection changed - */ -void TileDialog::updateSelection() -{ - // quit if run by the attr_changed listener - if (updating) { - return; - } - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - // in turn, prevent listener from responding - updating = true; - SPDesktop *desktop = getDesktop(); - Inkscape::Selection *selection = desktop ? desktop->selection : 0; - GSList const *items = selection ? selection->itemList() : 0; - - if (items) { - int selcount = g_slist_length((GSList *)items); - - if (NoOfColsSpinner.get_value() > 1 && NoOfRowsSpinner.get_value() > 1){ - // Update the number of rows assuming number of columns wanted remains same. - double NoOfRows = ceil(selcount / NoOfColsSpinner.get_value()); - NoOfRowsSpinner.set_value(NoOfRows); - - // if the selection has less than the number set for one row, reduce it appropriately - if (selcount < NoOfColsSpinner.get_value()) { - double NoOfCols = ceil(selcount / NoOfRowsSpinner.get_value()); - NoOfColsSpinner.set_value(NoOfCols); - prefs->setInt("/dialogs/gridtiler/NoOfCols", NoOfCols); - } - } else { - double PerRow = ceil(sqrt(selcount)); - double PerCol = ceil(sqrt(selcount)); - NoOfRowsSpinner.set_value(PerRow); - NoOfColsSpinner.set_value(PerCol); - prefs->setInt("/dialogs/gridtiler/NoOfCols", static_cast<int>(PerCol)); - } - } - - updating = false; -} - - - -/*########################## -## Experimental -##########################*/ - -static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, TileDialog *dlg) -{ - dlg->updateSelection(); -} - - -//######################################################################### -//## C O N S T R U C T O R / D E S T R U C T O R -//######################################################################### -/** - * Constructor - */ -TileDialog::TileDialog() - : UI::Widget::Panel("", "/dialogs/gridtiler", SP_VERB_SELECTION_GRIDTILE), - XPadding(_("X:"), _("Horizontal spacing between columns."), UNIT_TYPE_LINEAR, "", "object-columns", &PaddingUnitMenu), - YPadding(_("Y:"), _("Vertical spacing between rows."), UNIT_TYPE_LINEAR, "", "object-rows", &PaddingUnitMenu), -#if WITH_GTKMM_3_0 - PaddingTable(Gtk::manage(new Gtk::Grid())) -#else - PaddingTable(Gtk::manage(new Gtk::Table(2, 2, false))) -#endif -{ - // bool used by spin button callbacks to stop loops where they change each other. - updating = false; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - // could not do this in gtkmm - there's no Gtk::SizeGroup public constructor (!) - GtkSizeGroup *_col1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - GtkSizeGroup *_col2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - GtkSizeGroup *_col3 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - - { - // Selection Change signal - g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (updateSelectionCallback), this); - } - - Gtk::Box *contents = _getContents(); - -#define MARGIN 2 - - //##Set up the panel - - SPDesktop *desktop = getDesktop(); - - Inkscape::Selection *selection = desktop ? desktop->selection : 0; - g_return_if_fail( selection ); - int selcount = 1; - if (!selection->isEmpty()) { - GSList const *items = selection->itemList(); - selcount = g_slist_length((GSList *)items); - } - - - /*#### Number of Rows ####*/ - - double PerRow = ceil(sqrt(selcount)); - double PerCol = ceil(sqrt(selcount)); - - #ifdef DEBUG_GRID_ARRANGE - g_print("/n PerRox = %f PerCol = %f selcount = %d",PerRow,PerCol,selcount); - #endif - - NoOfRowsLabel.set_text_with_mnemonic(_("_Rows:")); - NoOfRowsLabel.set_mnemonic_widget(NoOfRowsSpinner); - NoOfRowsBox.pack_start(NoOfRowsLabel, false, false, MARGIN); - - NoOfRowsSpinner.set_digits(0); - NoOfRowsSpinner.set_increments(1, 0); - NoOfRowsSpinner.set_range(1.0, 10000.0); - NoOfRowsSpinner.set_value(PerCol); - NoOfRowsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_col_spinbutton_changed)); - NoOfRowsSpinner.set_tooltip_text(_("Number of rows")); - NoOfRowsBox.pack_start(NoOfRowsSpinner, false, false, MARGIN); - gtk_size_group_add_widget(_col1, GTK_WIDGET(NoOfRowsBox.gobj())); - - RowHeightButton.set_label(_("Equal _height")); - RowHeightButton.set_use_underline(true); - double AutoRow = prefs->getDouble("/dialogs/gridtiler/AutoRowSize", 15); - if (AutoRow>0) - AutoRowSize=true; - else - AutoRowSize=false; - RowHeightButton.set_active(AutoRowSize); - - NoOfRowsBox.pack_start(RowHeightButton, false, false, MARGIN); - - RowHeightButton.set_tooltip_text(_("If not set, each row has the height of the tallest object in it")); - RowHeightButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::on_RowSize_checkbutton_changed)); - - { - /*#### Radio buttons to control vertical alignment ####*/ - - VertAlignLabel.set_label(_("Align:")); - VertAlignHBox.pack_start(VertAlignLabel, false, false, MARGIN); - - VertTopRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed)); - VertAlignGroup = VertTopRadioButton.get_group(); - VertAlignVBox.pack_start(VertTopRadioButton, false, false, 0); - - VertCentreRadioButton.set_group(VertAlignGroup); - VertCentreRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed)); - VertAlignVBox.pack_start(VertCentreRadioButton, false, false, 0); - - VertBotRadioButton.set_group(VertAlignGroup); - VertBotRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed)); - VertAlignVBox.pack_start(VertBotRadioButton, false, false, 0); - - VertAlign = prefs->getInt("/dialogs/gridtiler/VertAlign", 1); - if (VertAlign == 0) { - VertTopRadioButton.set_active(TRUE); - } - else if (VertAlign == 1) { - VertCentreRadioButton.set_active(TRUE); - } - else if (VertAlign == 2){ - VertBotRadioButton.set_active(TRUE); - } - VertAlignHBox.pack_start(VertAlignVBox, false, false, MARGIN); - NoOfRowsBox.pack_start(VertAlignHBox, false, false, MARGIN); - } - - SpinsHBox.pack_start(NoOfRowsBox, false, false, MARGIN); - - - /*#### Label for X ####*/ - padXByYLabel.set_label(" "); - XByYLabelVBox.pack_start(padXByYLabel, false, false, MARGIN); - XByYLabel.set_markup(" × "); - XByYLabelVBox.pack_start(XByYLabel, false, false, MARGIN); - SpinsHBox.pack_start(XByYLabelVBox, false, false, MARGIN); - gtk_size_group_add_widget(_col2, GTK_WIDGET(XByYLabelVBox.gobj())); - - /*#### Number of columns ####*/ - - NoOfColsLabel.set_text_with_mnemonic(_("_Columns:")); - NoOfColsLabel.set_mnemonic_widget(NoOfColsSpinner); - NoOfColsBox.pack_start(NoOfColsLabel, false, false, MARGIN); - - NoOfColsSpinner.set_digits(0); - NoOfColsSpinner.set_increments(1, 0); - NoOfColsSpinner.set_range(1.0, 10000.0); - NoOfColsSpinner.set_value(PerRow); - NoOfColsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_row_spinbutton_changed)); - NoOfColsSpinner.set_tooltip_text(_("Number of columns")); - NoOfColsBox.pack_start(NoOfColsSpinner, false, false, MARGIN); - gtk_size_group_add_widget(_col3, GTK_WIDGET(NoOfColsBox.gobj())); - - ColumnWidthButton.set_label(_("Equal _width")); - ColumnWidthButton.set_use_underline(true); - double AutoCol = prefs->getDouble("/dialogs/gridtiler/AutoColSize", 15); - if (AutoCol>0) - AutoColSize=true; - else - AutoColSize=false; - ColumnWidthButton.set_active(AutoColSize); - NoOfColsBox.pack_start(ColumnWidthButton, false, false, MARGIN); - - ColumnWidthButton.set_tooltip_text(_("If not set, each column has the width of the widest object in it")); - ColumnWidthButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::on_ColSize_checkbutton_changed)); - - - { - /*#### Radio buttons to control horizontal alignment ####*/ - - HorizAlignLabel.set_label(_("Align:")); - HorizAlignVBox.pack_start(HorizAlignLabel, false, false, MARGIN); - - HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut - - HorizLeftRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed)); - HorizAlignGroup = HorizLeftRadioButton.get_group(); - HorizAlignHBox.pack_start(HorizLeftRadioButton, false, false, 0); - - HorizCentreRadioButton.set_group(HorizAlignGroup); - HorizCentreRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed)); - HorizAlignHBox.pack_start(HorizCentreRadioButton, false, false, 0); - - HorizRightRadioButton.set_group(HorizAlignGroup); - HorizRightRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed)); - HorizAlignHBox.pack_start(HorizRightRadioButton, false, false, 0); - - HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut - - HorizAlign = prefs->getInt("/dialogs/gridtiler/HorizAlign", 1); - if (HorizAlign == 0) { - HorizLeftRadioButton.set_active(TRUE); - } - else if (HorizAlign == 1) { - HorizCentreRadioButton.set_active(TRUE); - } - else if (HorizAlign == 2) { - HorizRightRadioButton.set_active(TRUE); - } - HorizAlignVBox.pack_start(HorizAlignHBox, false, false, MARGIN); - NoOfColsBox.pack_start(HorizAlignVBox, false, false, MARGIN); - } - - SpinsHBox.pack_start(NoOfColsBox, false, false, MARGIN); - - TileBox.pack_start(SpinsHBox, false, false, MARGIN); - - { - /*#### Radio buttons to control spacing manually or to fit selection bbox ####*/ - SpaceByBBoxRadioButton.set_label(_("_Fit into selection box")); - SpaceByBBoxRadioButton.set_use_underline (true); - SpaceByBBoxRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::Spacing_button_changed)); - SpacingGroup = SpaceByBBoxRadioButton.get_group(); - - SpacingVBox.pack_start(SpaceByBBoxRadioButton, false, false, MARGIN); - - SpaceManualRadioButton.set_label(_("_Set spacing:")); - SpaceManualRadioButton.set_use_underline (true); - SpaceManualRadioButton.set_group(SpacingGroup); - SpaceManualRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::Spacing_button_changed)); - SpacingVBox.pack_start(SpaceManualRadioButton, false, false, MARGIN); - - TileBox.pack_start(SpacingVBox, false, false, MARGIN); - } - - { - /*#### Padding ####*/ - PaddingUnitMenu.setUnitType(UNIT_TYPE_LINEAR); - PaddingUnitMenu.setUnit("px"); - - YPadding.setDigits(5); - YPadding.setIncrements(0.2, 0); - YPadding.setRange(-10000, 10000); - double yPad = prefs->getDouble("/dialogs/gridtiler/YPad", 15); - YPadding.setValue(yPad, "px"); - YPadding.signal_value_changed().connect(sigc::mem_fun(*this, &TileDialog::on_ypad_spinbutton_changed)); - - XPadding.setDigits(5); - XPadding.setIncrements(0.2, 0); - XPadding.setRange(-10000, 10000); - double xPad = prefs->getDouble("/dialogs/gridtiler/XPad", 15); - XPadding.setValue(xPad, "px"); - - XPadding.signal_value_changed().connect(sigc::mem_fun(*this, &TileDialog::on_xpad_spinbutton_changed)); - } - - PaddingTable->set_border_width(MARGIN); - -#if WITH_GTKMM_3_0 - PaddingTable->set_row_spacing(MARGIN); - PaddingTable->set_column_spacing(MARGIN); - PaddingTable->attach(XPadding, 0, 0, 1, 1); - PaddingTable->attach(PaddingUnitMenu, 1, 0, 1, 1); - PaddingTable->attach(YPadding, 0, 1, 1, 1); -#else - PaddingTable->set_row_spacings(MARGIN); - PaddingTable->set_col_spacings(MARGIN); - PaddingTable->attach(XPadding, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK); - PaddingTable->attach(PaddingUnitMenu, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK); - PaddingTable->attach(YPadding, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK); -#endif - - TileBox.pack_start(*PaddingTable, false, false, MARGIN); - - contents->pack_start(TileBox); - - double SpacingType = prefs->getDouble("/dialogs/gridtiler/SpacingType", 15); - if (SpacingType>0) { - ManualSpacing=true; - } else { - ManualSpacing=false; - } - SpaceManualRadioButton.set_active(ManualSpacing); - SpaceByBBoxRadioButton.set_active(!ManualSpacing); - XPadding.set_sensitive (ManualSpacing); - YPadding.set_sensitive (ManualSpacing); - - //## The OK button - TileOkButton = addResponseButton(C_("Rows and columns dialog","_Arrange"), GTK_RESPONSE_APPLY); - TileOkButton->set_use_underline(true); - TileOkButton->set_tooltip_text(_("Arrange selected objects")); - - show_all_children(); + switch(_notebook.get_current_page()) + { + case 0: + _gridArrangeTab->arrange(); + break; + case 1: + _polarArrangeTab->arrange(); + break; + } } } //namespace Dialog diff --git a/src/ui/dialog/tile.h b/src/ui/dialog/tile.h index 6e41723fd..2f75a8922 100644 --- a/src/ui/dialog/tile.h +++ b/src/ui/dialog/tile.h @@ -5,6 +5,7 @@ * Bob Jamison ( based off trace dialog) * John Cliff * Other dudes from The Inkscape Organization + * Declara Denis * * Copyright (C) 2004 Bob Jamison * Copyright (C) 2004 John Cliff @@ -29,8 +30,6 @@ #include <gtkmm/radiobutton.h> #include "ui/widget/panel.h" -#include "ui/widget/spinbutton.h" -#include "ui/widget/scalar-unit.h" namespace Gtk { class Button; @@ -46,134 +45,34 @@ namespace Inkscape { namespace UI { namespace Dialog { +class ArrangeTab; +class GridArrangeTab; +class PolarArrangeTab; -/** - * Dialog for tiling an object - */ -class TileDialog : public UI::Widget::Panel { -public: - TileDialog() ; - virtual ~TileDialog() {}; +class ArrangeDialog : public UI::Widget::Panel { +private: + Gtk::VBox _arrangeBox; + Gtk::Notebook _notebook; - /** - * Do the actual work - */ - void Grid_Arrange(); + GridArrangeTab *_gridArrangeTab; + PolarArrangeTab *_polarArrangeTab; - /** - * Respond to selection change - */ - void updateSelection(); + Gtk::Button *_arrangeButton; + +public: + ArrangeDialog(); + virtual ~ArrangeDialog() {}; /** * Callback from Apply */ virtual void _apply(); - // Callbacks from spinbuttons - void on_row_spinbutton_changed(); - void on_col_spinbutton_changed(); - void on_xpad_spinbutton_changed(); - void on_ypad_spinbutton_changed(); - void on_RowSize_checkbutton_changed(); - void on_ColSize_checkbutton_changed(); - void on_rowSize_spinbutton_changed(); - void on_colSize_spinbutton_changed(); - void Spacing_button_changed(); - void VertAlign_changed(); - void HorizAlign_changed(); - - static TileDialog& getInstance() { return *new TileDialog(); } - -private: - TileDialog(TileDialog const &d); // no copy - void operator=(TileDialog const &d); // no assign - - bool userHidden; - bool updating; - - Gtk::Notebook notebook; - - Gtk::VBox TileBox; - Gtk::Button *TileOkButton; - Gtk::Button *TileCancelButton; - - // Number selected label - Gtk::Label SelectionContentsLabel; - - - Gtk::HBox AlignHBox; - Gtk::HBox SpinsHBox; - - // Number per Row - Gtk::VBox NoOfColsBox; - Gtk::Label NoOfColsLabel; - Inkscape::UI::Widget::SpinButton NoOfColsSpinner; - bool AutoRowSize; - Gtk::CheckButton RowHeightButton; - - Gtk::VBox XByYLabelVBox; - Gtk::Label padXByYLabel; - Gtk::Label XByYLabel; - - // Number per Column - Gtk::VBox NoOfRowsBox; - Gtk::Label NoOfRowsLabel; - Inkscape::UI::Widget::SpinButton NoOfRowsSpinner; - bool AutoColSize; - Gtk::CheckButton ColumnWidthButton; - - // Vertical align - Gtk::Label VertAlignLabel; - Gtk::HBox VertAlignHBox; - Gtk::VBox VertAlignVBox; - Gtk::RadioButtonGroup VertAlignGroup; - Gtk::RadioButton VertCentreRadioButton; - Gtk::RadioButton VertTopRadioButton; - Gtk::RadioButton VertBotRadioButton; - double VertAlign; - - // Horizontal align - Gtk::Label HorizAlignLabel; - Gtk::VBox HorizAlignVBox; - Gtk::HBox HorizAlignHBox; - Gtk::RadioButtonGroup HorizAlignGroup; - Gtk::RadioButton HorizCentreRadioButton; - Gtk::RadioButton HorizLeftRadioButton; - Gtk::RadioButton HorizRightRadioButton; - double HorizAlign; - - Inkscape::UI::Widget::UnitMenu PaddingUnitMenu; - Inkscape::UI::Widget::ScalarUnit XPadding; - Inkscape::UI::Widget::ScalarUnit YPadding; - -#if WITH_GTKMM_3_0 - Gtk::Grid *PaddingTable; -#else - Gtk::Table *PaddingTable; -#endif + virtual void on_show(); - // BBox or manual spacing - Gtk::VBox SpacingVBox; - Gtk::RadioButtonGroup SpacingGroup; - Gtk::RadioButton SpaceByBBoxRadioButton; - Gtk::RadioButton SpaceManualRadioButton; - bool ManualSpacing; - - // Row height - Gtk::VBox RowHeightVBox; - Gtk::HBox RowHeightBox; - Gtk::Label RowHeightLabel; - Inkscape::UI::Widget::SpinButton RowHeightSpinner; - - // Column width - Gtk::VBox ColumnWidthVBox; - Gtk::HBox ColumnWidthBox; - Gtk::Label ColumnWidthLabel; - Inkscape::UI::Widget::SpinButton ColumnWidthSpinner; + static ArrangeDialog& getInstance() { return *new ArrangeDialog(); } }; - } //namespace Dialog } //namespace UI } //namespace Inkscape diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp index bd467555e..11e75391b 100644 --- a/src/ui/dialog/tracedialog.cpp +++ b/src/ui/dialog/tracedialog.cpp @@ -778,7 +778,7 @@ TraceDialogImpl::TraceDialogImpl() : rightVBox.pack_start(sioxBox, false, false, 0); //## preview - Gtk::HBox *previewButtonHBox = manage(new Gtk::HBox(false, MARGIN )); + Gtk::HBox *previewButtonHBox = Gtk::manage(new Gtk::HBox(false, MARGIN )); previewLiveButton.set_label(_("Live Preview")); previewLiveButton.set_use_underline(true); previewLiveCallback(); diff --git a/src/ui/previewholder.cpp b/src/ui/previewholder.cpp index 38f6f353f..21f3f38d7 100644 --- a/src/ui/previewholder.cpp +++ b/src/ui/previewholder.cpp @@ -49,25 +49,25 @@ PreviewHolder::PreviewHolder() : _wrap(false), _border(BORDER_NONE) { - _scroller = manage(new Gtk::ScrolledWindow()); + _scroller = Gtk::manage(new Gtk::ScrolledWindow()); ((Gtk::ScrolledWindow *)_scroller)->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); #if WITH_GTKMM_3_0 - _insides = manage(new Gtk::Grid()); + _insides = Gtk::manage(new Gtk::Grid()); _insides->set_column_spacing(8); // Add a container with the scroller and a spacer - Gtk::Grid* spaceHolder = manage(new Gtk::Grid()); + Gtk::Grid* spaceHolder = Gtk::manage(new Gtk::Grid()); _scroller->set_hexpand(); _scroller->set_vexpand(); #else - _insides = manage(new Gtk::Table( 1, 2 )); + _insides = Gtk::manage(new Gtk::Table( 1, 2 )); _insides->set_col_spacings( 8 ); // Add a container with the scroller and a spacer - Gtk::Table* spaceHolder = manage( new Gtk::Table(1, 2) ); + Gtk::Table* spaceHolder = Gtk::manage( new Gtk::Table(1, 2) ); #endif _scroller->add( *_insides ); @@ -134,8 +134,8 @@ void PreviewHolder::addPreview( Previewable* preview ) switch(_view) { case VIEW_TYPE_LIST: { - Gtk::Widget* label = manage(preview->getPreview(PREVIEW_STYLE_BLURB, VIEW_TYPE_LIST, _baseSize, _ratio, _border)); - Gtk::Widget* thing = manage(preview->getPreview(PREVIEW_STYLE_PREVIEW, VIEW_TYPE_LIST, _baseSize, _ratio, _border)); + Gtk::Widget* label = Gtk::manage(preview->getPreview(PREVIEW_STYLE_BLURB, VIEW_TYPE_LIST, _baseSize, _ratio, _border)); + Gtk::Widget* thing = Gtk::manage(preview->getPreview(PREVIEW_STYLE_PREVIEW, VIEW_TYPE_LIST, _baseSize, _ratio, _border)); #if WITH_GTKMM_3_0 thing->set_hexpand(); @@ -154,7 +154,7 @@ void PreviewHolder::addPreview( Previewable* preview ) break; case VIEW_TYPE_GRID: { - Gtk::Widget* thing = manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, VIEW_TYPE_GRID, _baseSize, _ratio, _border)); + Gtk::Widget* thing = Gtk::manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, VIEW_TYPE_GRID, _baseSize, _ratio, _border)); int width = 1; int height = 1; @@ -408,10 +408,10 @@ void PreviewHolder::rebuildUI() { #if WITH_GTKMM_3_0 - _insides = manage(new Gtk::Grid()); + _insides = Gtk::manage(new Gtk::Grid()); _insides->set_column_spacing(8); #else - _insides = manage(new Gtk::Table( 1, 2 )); + _insides = Gtk::manage(new Gtk::Table( 1, 2 )); _insides->set_col_spacings( 8 ); #endif @@ -424,10 +424,10 @@ void PreviewHolder::rebuildUI() } for ( unsigned int i = 0; i < items.size(); i++ ) { - Gtk::Widget* label = manage(items[i]->getPreview(PREVIEW_STYLE_BLURB, _view, _baseSize, _ratio, _border)); + Gtk::Widget* label = Gtk::manage(items[i]->getPreview(PREVIEW_STYLE_BLURB, _view, _baseSize, _ratio, _border)); //label->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); - Gtk::Widget* thing = manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, _view, _baseSize, _ratio, _border)); + Gtk::Widget* thing = Gtk::manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, _view, _baseSize, _ratio, _border)); #if WITH_GTKMM_3_0 thing->set_hexpand(); @@ -458,19 +458,19 @@ void PreviewHolder::rebuildUI() // If this is the last row, flag so the previews can draw a bottom ::BorderStyle border = ((row == height -1) && (_border == BORDER_SOLID)) ? BORDER_SOLID_LAST_ROW : _border; - Gtk::Widget* thing = manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, _view, _baseSize, _ratio, border)); + Gtk::Widget* thing = Gtk::manage(items[i]->getPreview(PREVIEW_STYLE_PREVIEW, _view, _baseSize, _ratio, border)); if ( !_insides ) { calcGridSize( thing, items.size(), width, height ); #if WITH_GTKMM_3_0 - _insides = manage(new Gtk::Grid()); + _insides = Gtk::manage(new Gtk::Grid()); if (_border == BORDER_WIDE) { _insides->set_column_spacing(1); _insides->set_row_spacing(1); } #else - _insides = manage(new Gtk::Table( height, width )); + _insides = Gtk::manage(new Gtk::Table( height, width )); if (_border == BORDER_WIDE) { _insides->set_col_spacings( 1 ); _insides->set_row_spacings( 1 ); @@ -493,9 +493,9 @@ void PreviewHolder::rebuildUI() } if ( !_insides ) { #if WITH_GTKMM_3_0 - _insides = manage(new Gtk::Grid()); + _insides = Gtk::manage(new Gtk::Grid()); #else - _insides = manage(new Gtk::Table( 1, 2 )); + _insides = Gtk::manage(new Gtk::Table( 1, 2 )); #endif } diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 4393446d9..fc36502a5 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -12,6 +12,10 @@ #ifndef SEEN_UI_TOOL_NODE_H #define SEEN_UI_TOOL_NODE_H +#if HAVE_CONFIG_H + #include "config.h" +#endif + #include <iterator> #include <iosfwd> #include <stdexcept> @@ -37,7 +41,7 @@ template <typename> class NodeIterator; } } -#if __cplusplus < 201103L +#if HAVE_TR1_UNORDERED_SET namespace std { namespace tr1 { template <typename N> struct hash< Inkscape::UI::NodeIterator<N> >; diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp index e19f35832..d1355e807 100644 --- a/src/ui/tools/connector-tool.cpp +++ b/src/ui/tools/connector-tool.cpp @@ -201,7 +201,8 @@ ConnectorTool::~ConnectorTool() { for (int i = 0; i < 2; ++i) { if (this->endpt_handle[1]) { - g_object_unref(this->endpt_handle[i]); + //g_object_unref(this->endpt_handle[i]); + knot_unref(this->endpt_handle[i]); this->endpt_handle[i] = NULL; } } @@ -319,7 +320,7 @@ cc_clear_active_knots(SPKnotList k) // Hide the connection points if they exist. if (k.size()) { for (SPKnotList::iterator it = k.begin(); it != k.end(); ++it) { - sp_knot_hide(it->first); + it->first->hide(); } } } @@ -341,7 +342,7 @@ void ConnectorTool::cc_clear_active_conn() { // Hide the endpoint handles. for (int i = 0; i < 2; ++i) { if (this->endpt_handle[i]) { - sp_knot_hide(this->endpt_handle[i]); + this->endpt_handle[i]->hide(); } } } @@ -365,7 +366,7 @@ cc_select_handle(SPKnot* knot) knot->setSize(10); knot->setAnchor(SP_ANCHOR_CENTER); knot->setFill(0x0000ffff, 0x0000ffff, 0x0000ffff); - sp_knot_update_ctrl(knot); + knot->updateCtrl(); } static void @@ -375,7 +376,7 @@ cc_deselect_handle(SPKnot* knot) knot->setSize(8); knot->setAnchor(SP_ANCHOR_CENTER); knot->setFill(0xffffff00, 0xff0000ff, 0xff0000ff); - sp_knot_update_ctrl(knot); + knot->updateCtrl(); } bool ConnectorTool::item_handler(SPItem* item, GdkEvent* event) { @@ -969,7 +970,8 @@ cc_generic_knot_handler(SPCanvasItem *, GdkEvent *event, SPKnot *knot) { g_assert (knot != NULL); - g_object_ref(knot); + //g_object_ref(knot); + knot_ref(knot); ConnectorTool *cc = SP_CONNECTOR_CONTEXT( knot->desktop->event_context); @@ -979,7 +981,7 @@ cc_generic_knot_handler(SPCanvasItem *, GdkEvent *event, SPKnot *knot) gchar const *knot_tip = "Click to join at this point"; switch (event->type) { case GDK_ENTER_NOTIFY: - sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, TRUE); + knot->setFlag(SP_KNOT_MOUSEOVER, TRUE); cc->active_handle = knot; if (knot_tip) @@ -991,7 +993,7 @@ cc_generic_knot_handler(SPCanvasItem *, GdkEvent *event, SPKnot *knot) consumed = TRUE; break; case GDK_LEAVE_NOTIFY: - sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, FALSE); + knot->setFlag(SP_KNOT_MOUSEOVER, FALSE); /* FIXME: the following test is a workaround for LP Bug #1273510. * It seems that a signal is not correctly disconnected, maybe @@ -1010,7 +1012,8 @@ cc_generic_knot_handler(SPCanvasItem *, GdkEvent *event, SPKnot *knot) break; } - g_object_unref(knot); + //g_object_unref(knot); + knot_unref(knot); return consumed; } @@ -1066,14 +1069,14 @@ endpt_handler(SPKnot */*knot*/, GdkEvent *event, ConnectorTool *cc) } void ConnectorTool::_activeShapeAddKnot(SPItem* item) { - SPKnot *knot = sp_knot_new(desktop, 0); + SPKnot *knot = new SPKnot(desktop, 0); knot->owner = item; knot->setShape(SP_KNOT_SHAPE_SQUARE); knot->setSize(8); knot->setAnchor(SP_ANCHOR_CENTER); knot->setFill(0xffffff00, 0xff0000ff, 0xff0000ff); - sp_knot_update_ctrl(knot); + knot->updateCtrl(); // We don't want to use the standard knot handler. g_signal_handler_disconnect(G_OBJECT(knot->item), @@ -1084,8 +1087,8 @@ void ConnectorTool::_activeShapeAddKnot(SPItem* item) { g_signal_connect(G_OBJECT(knot->item), "event", G_CALLBACK(cc_generic_knot_handler), knot); - sp_knot_set_position(knot, item->avoidRef->getConnectionPointPos() * desktop->doc2dt(), 0); - sp_knot_show(knot); + knot->setPosition(item->avoidRef->getConnectionPointPos() * desktop->doc2dt(), 0); + knot->show(); this->knots[knot] = 1; } @@ -1149,17 +1152,17 @@ void ConnectorTool::cc_set_active_conn(SPItem *item) { { // Connector is invisible because it is clipped to the boundary of // two overlpapping shapes. - sp_knot_hide(this->endpt_handle[0]); - sp_knot_hide(this->endpt_handle[1]); + this->endpt_handle[0]->hide(); + this->endpt_handle[1]->hide(); } else { // Just adjust handle positions. Geom::Point startpt = *(curve->first_point()) * i2dt; - sp_knot_set_position(this->endpt_handle[0], startpt, 0); + this->endpt_handle[0]->setPosition(startpt, 0); Geom::Point endpt = *(curve->last_point()) * i2dt; - sp_knot_set_position(this->endpt_handle[1], endpt, 0); + this->endpt_handle[1]->setPosition(endpt, 0); } return; @@ -1184,7 +1187,7 @@ void ConnectorTool::cc_set_active_conn(SPItem *item) { for (int i = 0; i < 2; ++i) { // Create the handle if it doesn't exist if ( this->endpt_handle[i] == NULL ) { - SPKnot *knot = sp_knot_new(this->desktop, + SPKnot *knot = new SPKnot(this->desktop, _("<b>Connector endpoint</b>: drag to reroute or connect to new shapes")); knot->setShape(SP_KNOT_SHAPE_SQUARE); @@ -1192,7 +1195,7 @@ void ConnectorTool::cc_set_active_conn(SPItem *item) { knot->setAnchor(SP_ANCHOR_CENTER); knot->setFill(0xffffff00, 0xff0000ff, 0xff0000ff); knot->setStroke(0x000000ff, 0x000000ff, 0x000000ff); - sp_knot_update_ctrl(knot); + knot->updateCtrl(); // We don't want to use the standard knot handler, // since we don't want this knot to be draggable. @@ -1232,13 +1235,13 @@ void ConnectorTool::cc_set_active_conn(SPItem *item) { } Geom::Point startpt = *(curve->first_point()) * i2dt; - sp_knot_set_position(this->endpt_handle[0], startpt, 0); + this->endpt_handle[0]->setPosition(startpt, 0); Geom::Point endpt = *(curve->last_point()) * i2dt; - sp_knot_set_position(this->endpt_handle[1], endpt, 0); + this->endpt_handle[1]->setPosition(endpt, 0); - sp_knot_show(this->endpt_handle[0]); - sp_knot_show(this->endpt_handle[1]); + this->endpt_handle[0]->show(); + this->endpt_handle[1]->show(); } void cc_create_connection_point(ConnectorTool* cc) @@ -1250,7 +1253,7 @@ void cc_create_connection_point(ConnectorTool* cc) cc_deselect_handle( cc->selected_handle ); } - SPKnot *knot = sp_knot_new(cc->desktop, 0); + SPKnot *knot = new SPKnot(cc->desktop, 0); // We do not process events on this knot. g_signal_handler_disconnect(G_OBJECT(knot->item), @@ -1260,7 +1263,7 @@ void cc_create_connection_point(ConnectorTool* cc) cc_select_handle( knot ); cc->selected_handle = knot; - sp_knot_show(cc->selected_handle); + cc->selected_handle->show(); cc->state = SP_CONNECTOR_CONTEXT_NEWCONNPOINT; } } diff --git a/src/ui/tools/connector-tool.h b/src/ui/tools/connector-tool.h index 9a9ae64cf..868b8e77c 100644 --- a/src/ui/tools/connector-tool.h +++ b/src/ui/tools/connector-tool.h @@ -22,7 +22,7 @@ class SPItem; class SPCurve; -struct SPKnot; +class SPKnot; struct SPCanvasItem; namespace Avoid { diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 6216af295..6f55d361f 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -26,7 +26,6 @@ #include "draw-anchor.h" #include "message-stack.h" #include "message-context.h" -#include "modifier-fns.h" #include "sp-path.h" #include "preferences.h" #include "snap.h" @@ -45,6 +44,7 @@ #include "display/curve.h" #include "livarot/Path.h" #include "tool-factory.h" +#include "ui/tool/event-utils.h" namespace Inkscape { namespace UI { @@ -131,11 +131,11 @@ bool PencilTool::root_handler(GdkEvent* event) { break; case GDK_KEY_PRESS: - ret = this->_handleKeyPress(get_group0_keyval (&event->key), event->key.state); + ret = this->_handleKeyPress(event->key); break; case GDK_KEY_RELEASE: - ret = this->_handleKeyRelease(get_group0_keyval (&event->key), event->key.state); + ret = this->_handleKeyRelease(event->key); break; default: @@ -470,16 +470,16 @@ void PencilTool::_cancel() { this->desktop->canvas->endForcedFullRedraws(); } -bool PencilTool::_handleKeyPress(guint const keyval, guint const state) { +bool PencilTool::_handleKeyPress(GdkEventKey const &event) { bool ret = false; - switch (keyval) { + switch (get_group0_keyval(&event)) { case GDK_KEY_Up: case GDK_KEY_Down: case GDK_KEY_KP_Up: case GDK_KEY_KP_Down: // Prevent the zoom field from activation. - if (!mod_ctrl_only(state)) { + if (!Inkscape::UI::held_only_control(event)) { ret = true; } break; @@ -494,7 +494,7 @@ bool PencilTool::_handleKeyPress(guint const keyval, guint const state) { break; case GDK_KEY_z: case GDK_KEY_Z: - if (mod_ctrl_only(state) && this->npoints != 0) { + if (Inkscape::UI::held_only_control(event) && this->npoints != 0) { // if drawing, cancel, otherwise pass it up for undo if (this->state != SP_PENCIL_CONTEXT_IDLE) { this->_cancel(); @@ -504,7 +504,7 @@ bool PencilTool::_handleKeyPress(guint const keyval, guint const state) { break; case GDK_KEY_g: case GDK_KEY_G: - if (mod_shift_only(state)) { + if (Inkscape::UI::held_only_shift(event)) { sp_selection_to_guides(this->desktop); ret = true; } @@ -523,9 +523,10 @@ bool PencilTool::_handleKeyPress(guint const keyval, guint const state) { return ret; } -bool PencilTool::_handleKeyRelease(guint const keyval, guint const /*state*/) { +bool PencilTool::_handleKeyRelease(GdkEventKey const &event) { bool ret = false; - switch (keyval) { + + switch (get_group0_keyval(&event)) { case GDK_KEY_Alt_L: case GDK_KEY_Alt_R: case GDK_KEY_Meta_L: diff --git a/src/ui/tools/pencil-tool.h b/src/ui/tools/pencil-tool.h index e01b0afb5..e8d156dbd 100644 --- a/src/ui/tools/pencil-tool.h +++ b/src/ui/tools/pencil-tool.h @@ -57,8 +57,8 @@ private: bool _handleButtonPress(GdkEventButton const &bevent); bool _handleMotionNotify(GdkEventMotion const &mevent); bool _handleButtonRelease(GdkEventButton const &revent); - bool _handleKeyPress(guint const keyval, guint const state); - bool _handleKeyRelease(guint const keyval, guint const state); + bool _handleKeyPress(GdkEventKey const &event); + bool _handleKeyRelease(GdkEventKey const &event); void _setStartpoint(Geom::Point const &p); void _setEndpoint(Geom::Point const &p); diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 96ac95926..4195c9eb2 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -1132,7 +1132,7 @@ void sp_event_show_modifier_tip(Inkscape::MessageContext *message_context, * Use this instead of simply event->keyval, so that your keyboard shortcuts * work regardless of layouts (e.g., in Cyrillic). */ -guint get_group0_keyval(GdkEventKey *event) { +guint get_group0_keyval(GdkEventKey const *event) { guint keyval = 0; gdk_keymap_translate_keyboard_state(gdk_keymap_get_for_display( diff --git a/src/ui/tools/tool-base.h b/src/ui/tools/tool-base.h index e11a22296..b27de9030 100644 --- a/src/ui/tools/tool-base.h +++ b/src/ui/tools/tool-base.h @@ -244,7 +244,7 @@ gint gobble_motion_events(gint mask); void sp_event_show_modifier_tip(Inkscape::MessageContext *message_context, GdkEvent *event, gchar const *ctrl_tip, gchar const *shift_tip, gchar const *alt_tip); -guint get_group0_keyval(GdkEventKey *event); +guint get_group0_keyval(GdkEventKey const *event); SPItem *sp_event_context_find_item (SPDesktop *desktop, Geom::Point const &p, bool select_under, bool into_groups); SPItem *sp_event_context_over_item (SPDesktop *desktop, SPItem *item, Geom::Point const &p); diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert index 710b95c2b..608dd5334 100644 --- a/src/ui/widget/Makefile_insert +++ b/src/ui/widget/Makefile_insert @@ -1,6 +1,8 @@ ## Makefile.am fragment sourced by src/Makefile.am. ink_common_sources += \ + ui/widget/anchor-selector.h \ + ui/widget/anchor-selector.cpp \ ui/widget/attr-widget.h \ ui/widget/button.h \ ui/widget/button.cpp \ diff --git a/src/ui/widget/anchor-selector.cpp b/src/ui/widget/anchor-selector.cpp new file mode 100644 index 000000000..82e27ee89 --- /dev/null +++ b/src/ui/widget/anchor-selector.cpp @@ -0,0 +1,97 @@ +/* + * anchor-selector.cpp + * + * Created on: Mar 22, 2012 + * Author: denis + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#include "ui/widget/anchor-selector.h" +#include <iostream> +#include "widgets/icon.h" +#include "ui/icon-names.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +void AnchorSelector::setupButton(const Glib::ustring& icon, Gtk::ToggleButton& button) { + Gtk::Widget* buttonIcon = Gtk::manage(sp_icon_get_icon(icon, Inkscape::ICON_SIZE_SMALL_TOOLBAR)); + buttonIcon->show(); + + button.set_relief(Gtk::RELIEF_NONE); + button.show(); + button.add(*buttonIcon); + button.set_can_focus(false); +} + +AnchorSelector::AnchorSelector() + : Gtk::Alignment(0.5, 0, 0, 0), + _container(3, 3, true) +{ + setupButton(INKSCAPE_ICON("boundingbox_top_left"), _buttons[0]); + setupButton(INKSCAPE_ICON("boundingbox_top"), _buttons[1]); + setupButton(INKSCAPE_ICON("boundingbox_top_right"), _buttons[2]); + setupButton(INKSCAPE_ICON("boundingbox_left"), _buttons[3]); + setupButton(INKSCAPE_ICON("boundingbox_center"), _buttons[4]); + setupButton(INKSCAPE_ICON("boundingbox_right"), _buttons[5]); + setupButton(INKSCAPE_ICON("boundingbox_bottom_left"), _buttons[6]); + setupButton(INKSCAPE_ICON("boundingbox_bottom"), _buttons[7]); + setupButton(INKSCAPE_ICON("boundingbox_bottom_right"), _buttons[8]); + + for(int i = 0; i < 9; ++i) { + _buttons[i].signal_clicked().connect( + sigc::bind(sigc::mem_fun(*this, &AnchorSelector::btn_activated), i)); + _container.attach(_buttons[i], i % 3, i % 3+1, i / 3, i / 3+1, Gtk::FILL, Gtk::FILL); + } + _selection = 4; + _buttons[4].set_active(); + + this->add(_container); +} + +AnchorSelector::~AnchorSelector() +{ + // TODO Auto-generated destructor stub +} + +void AnchorSelector::btn_activated(int index) +{ + + if(_selection == index && _buttons[index].get_active() == false) + { + _buttons[index].set_active(true); + } + else if(_selection != index && _buttons[index].get_active()) + { + int old_selection = _selection; + _selection = index; + _buttons[old_selection].set_active(false); + _selectionChanged.emit(); + } +} + +void AnchorSelector::setAlignment(int horizontal, int vertical) +{ + int index = 3 * vertical + horizontal; + if(index >= 0 && index < 9) + { + _buttons[index].set_active(!_buttons[index].get_active()); + } +} + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/ui/widget/anchor-selector.h b/src/ui/widget/anchor-selector.h new file mode 100644 index 000000000..2263438e3 --- /dev/null +++ b/src/ui/widget/anchor-selector.h @@ -0,0 +1,59 @@ +/* + * anchor-selector.h + * + * Created on: Mar 22, 2012 + * Author: denis + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef ANCHOR_SELECTOR_H_ +#define ANCHOR_SELECTOR_H_ + +#include <gtkmm.h> + +namespace Inkscape { +namespace UI { +namespace Widget { + +class AnchorSelector : public Gtk::Alignment +{ +private: + Gtk::ToggleButton _buttons[9]; + int _selection; + Gtk::Table _container; + + sigc::signal<void> _selectionChanged; + + void setupButton(const Glib::ustring &icon, Gtk::ToggleButton &button); + void btn_activated(int index); + +public: + + int getHorizontalAlignment() { return _selection % 3; } + int getVerticalAlignment() { return _selection / 3; } + + sigc::signal<void> &on_selectionChanged() { return _selectionChanged; } + + void setAlignment(int horizontal, int vertical); + + AnchorSelector(); + virtual ~AnchorSelector(); +}; + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +#endif /* ANCHOR_SELECTOR_H_ */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/ui/widget/licensor.cpp b/src/ui/widget/licensor.cpp index c729354cb..42f352e3c 100644 --- a/src/ui/widget/licensor.cpp +++ b/src/ui/widget/licensor.cpp @@ -97,7 +97,7 @@ void Licensor::init (Registry& wr) LicenseItem *i; wr.setUpdating (true); - i = manage (new LicenseItem (&_proprietary_license, _eentry, wr, NULL)); + i = Gtk::manage (new LicenseItem (&_proprietary_license, _eentry, wr, NULL)); Gtk::RadioButtonGroup group = i->get_group(); add (*i); LicenseItem *pd = i; @@ -105,17 +105,17 @@ void Licensor::init (Registry& wr) for (struct rdf_license_t * license = rdf_licenses; license && license->name; license++) { - i = manage (new LicenseItem (license, _eentry, wr, &group)); + i = Gtk::manage (new LicenseItem (license, _eentry, wr, &group)); add(*i); } // add Other at the end before the URI field for the confused ppl. - LicenseItem *io = manage (new LicenseItem (&_other_license, _eentry, wr, &group)); + LicenseItem *io = Gtk::manage (new LicenseItem (&_other_license, _eentry, wr, &group)); add (*io); pd->set_active(); wr.setUpdating (false); - Gtk::HBox *box = manage (new Gtk::HBox); + Gtk::HBox *box = Gtk::manage (new Gtk::HBox); pack_start (*box, true, true, 0); box->pack_start (_eentry->_label, false, false, 5); diff --git a/src/ui/widget/panel.cpp b/src/ui/widget/panel.cpp index d60eeefe0..b37137228 100644 --- a/src/ui/widget/panel.cpp +++ b/src/ui/widget/panel.cpp @@ -115,8 +115,8 @@ void Panel::_init() Gtk::RadioMenuItem::Group group; Glib::ustring one_label(_("List")); Glib::ustring two_label(_("Grid")); - Gtk::RadioMenuItem *one = manage(new Gtk::RadioMenuItem(group, one_label)); - Gtk::RadioMenuItem *two = manage(new Gtk::RadioMenuItem(group, two_label)); + Gtk::RadioMenuItem *one = Gtk::manage(new Gtk::RadioMenuItem(group, one_label)); + Gtk::RadioMenuItem *two = Gtk::manage(new Gtk::RadioMenuItem(group, two_label)); if (panel_mode == 0) { one->set_active(true); @@ -128,7 +128,7 @@ void Panel::_init() _non_horizontal.push_back(one); _menu->append(*two); _non_horizontal.push_back(two); - Gtk::MenuItem* sep = manage(new Gtk::SeparatorMenuItem()); + Gtk::MenuItem* sep = Gtk::manage(new Gtk::SeparatorMenuItem()); _menu->append(*sep); _non_horizontal.push_back(sep); one->signal_activate().connect(sigc::bind<int, int>(sigc::mem_fun(*this, &Panel::_bounceCall), PANEL_SETTING_MODE, 0)); @@ -147,14 +147,14 @@ void Panel::_init() NC_("Swatches height", "Huge") }; - Gtk::MenuItem *sizeItem = manage(new Gtk::MenuItem(heightItemLabel)); - Gtk::Menu *sizeMenu = manage(new Gtk::Menu()); + Gtk::MenuItem *sizeItem = Gtk::manage(new Gtk::MenuItem(heightItemLabel)); + Gtk::Menu *sizeMenu = Gtk::manage(new Gtk::Menu()); sizeItem->set_submenu(*sizeMenu); Gtk::RadioMenuItem::Group heightGroup; for (unsigned int i = 0; i < G_N_ELEMENTS(heightLabels); i++) { Glib::ustring _label(g_dpgettext2(NULL, "Swatches height", heightLabels[i])); - Gtk::RadioMenuItem* _item = manage(new Gtk::RadioMenuItem(heightGroup, _label)); + Gtk::RadioMenuItem* _item = Gtk::manage(new Gtk::RadioMenuItem(heightGroup, _label)); sizeMenu->append(*_item); if (i == panel_size) { _item->set_active(true); @@ -177,8 +177,8 @@ void Panel::_init() NC_("Swatches width", "Wider") }; - Gtk::MenuItem *item = manage( new Gtk::MenuItem(widthItemLabel)); - Gtk::Menu *type_menu = manage(new Gtk::Menu()); + Gtk::MenuItem *item = Gtk::manage( new Gtk::MenuItem(widthItemLabel)); + Gtk::Menu *type_menu = Gtk::manage(new Gtk::Menu()); item->set_submenu(*type_menu); _menu->append(*item); @@ -194,7 +194,7 @@ void Panel::_init() } for ( guint i = 0; i < G_N_ELEMENTS(widthLabels); ++i ) { Glib::ustring _label(g_dpgettext2(NULL, "Swatches width", widthLabels[i])); - Gtk::RadioMenuItem *_item = manage(new Gtk::RadioMenuItem(widthGroup, _label)); + Gtk::RadioMenuItem *_item = Gtk::manage(new Gtk::RadioMenuItem(widthGroup, _label)); type_menu->append(*_item); if ( i <= hot_index ) { _item->set_active(true); @@ -213,8 +213,8 @@ void Panel::_init() NC_("Swatches border", "Wide"), }; - Gtk::MenuItem *item = manage( new Gtk::MenuItem(widthItemLabel)); - Gtk::Menu *type_menu = manage(new Gtk::Menu()); + Gtk::MenuItem *item = Gtk::manage( new Gtk::MenuItem(widthItemLabel)); + Gtk::Menu *type_menu = Gtk::manage(new Gtk::Menu()); item->set_submenu(*type_menu); _menu->append(*item); @@ -230,7 +230,7 @@ void Panel::_init() } for ( guint i = 0; i < G_N_ELEMENTS(widthLabels); ++i ) { Glib::ustring _label(g_dpgettext2(NULL, "Swatches border", widthLabels[i])); - Gtk::RadioMenuItem *_item = manage(new Gtk::RadioMenuItem(widthGroup, _label)); + Gtk::RadioMenuItem *_item = Gtk::manage(new Gtk::RadioMenuItem(widthGroup, _label)); type_menu->append(*_item); if ( i <= hot_index ) { _item->set_active(true); @@ -242,7 +242,7 @@ void Panel::_init() { //TRANSLATORS: "Wrap" indicates how colour swatches are displayed Glib::ustring wrap_label(C_("Swatches","Wrap")); - Gtk::CheckMenuItem *check = manage(new Gtk::CheckMenuItem(wrap_label)); + Gtk::CheckMenuItem *check = Gtk::manage(new Gtk::CheckMenuItem(wrap_label)); check->set_active(panel_wrap); _menu->append(*check); _non_vertical.push_back(check); @@ -251,7 +251,7 @@ void Panel::_init() } Gtk::SeparatorMenuItem *sep; - sep = manage(new Gtk::SeparatorMenuItem()); + sep = Gtk::manage(new Gtk::SeparatorMenuItem()); _menu->append(*sep); _menu->show_all_children(); @@ -284,7 +284,7 @@ void Panel::_init() pack_start(_top_bar, false, false); - Gtk::HBox* boxy = manage(new Gtk::HBox()); + Gtk::HBox* boxy = Gtk::manage(new Gtk::HBox()); boxy->pack_start(_contents, true, true); boxy->pack_start(_right_bar, false, true); diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 175f6471c..92cb3f03d 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -429,11 +429,11 @@ RegisteredRadioButtonPair::RegisteredRadioButtonPair (const Glib::ustring& label setProgrammatically = false; - add (*manage (new Gtk::Label (label))); - _rb1 = manage (new Gtk::RadioButton (label1, true)); + add(*Gtk::manage(new Gtk::Label(label))); + _rb1 = Gtk::manage(new Gtk::RadioButton(label1, true)); add (*_rb1); Gtk::RadioButtonGroup group = _rb1->get_group(); - _rb2 = manage (new Gtk::RadioButton (group, label2, true)); + _rb2 = Gtk::manage(new Gtk::RadioButton(group, label2, true)); add (*_rb2); _rb2->set_active(); _rb1->set_tooltip_text(tip1); diff --git a/src/ui/widget/tolerance-slider.cpp b/src/ui/widget/tolerance-slider.cpp index d166e3831..5fc588fdc 100644 --- a/src/ui/widget/tolerance-slider.cpp +++ b/src/ui/widget/tolerance-slider.cpp @@ -71,19 +71,19 @@ void ToleranceSlider::init (const Glib::ustring& label1, const Glib::ustring& la // hbox _vbox = new Gtk::VBox; - _hbox = manage (new Gtk::HBox); + _hbox = Gtk::manage(new Gtk::HBox); - Gtk::Label *theLabel1 = manage (new Gtk::Label (label1)); + Gtk::Label *theLabel1 = Gtk::manage(new Gtk::Label(label1)); theLabel1->set_use_underline(); theLabel1->set_alignment(0, 0.5); // align the label with the checkbox text above by indenting 22 px. _hbox->pack_start(*theLabel1, Gtk::PACK_EXPAND_WIDGET, 22); #if WITH_GTKMM_3_0 - _hscale = manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL)); + _hscale = Gtk::manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL)); _hscale->set_range(1.0, 51.0); #else - _hscale = manage (new Gtk::HScale (1.0, 51, 1.0)); + _hscale = Gtk::manage (new Gtk::HScale (1.0, 51, 1.0)); #endif theLabel1->set_mnemonic_widget (*_hscale); @@ -96,13 +96,13 @@ void ToleranceSlider::init (const Glib::ustring& label1, const Glib::ustring& la _hbox->add (*_hscale); - Gtk::Label *theLabel2 = manage (new Gtk::Label (label2)); + Gtk::Label *theLabel2 = Gtk::manage(new Gtk::Label(label2)); theLabel2->set_use_underline(); - Gtk::Label *theLabel3 = manage (new Gtk::Label (label3)); + Gtk::Label *theLabel3 = Gtk::manage(new Gtk::Label(label3)); theLabel3->set_use_underline(); - _button1 = manage (new Gtk::RadioButton); + _button1 = Gtk::manage(new Gtk::RadioButton); _radio_button_group = _button1->get_group(); - _button2 = manage (new Gtk::RadioButton); + _button2 = Gtk::manage(new Gtk::RadioButton); _button2->set_group(_radio_button_group); _button1->set_tooltip_text (tip2); _button2->set_tooltip_text (tip3); diff --git a/src/util/unordered-containers.h b/src/util/unordered-containers.h index 98c2fa3c9..b92f2e7ea 100644 --- a/src/util/unordered-containers.h +++ b/src/util/unordered-containers.h @@ -69,37 +69,6 @@ struct hash<Glib::ustring> : public std::unary_function<Glib::ustring, std::size } }; } // namespace boost - -#elif defined(HAVE_EXT_HASH_SET) - -# include <functional> -# include <ext/hash_set> -# include <ext/hash_map> -# define INK_UNORDERED_SET __gnu_cxx::hash_set -# define INK_UNORDERED_MAP __gnu_cxx::hash_map -# define INK_HASH __gnu_cxx::hash - -#include <cstddef> - -namespace __gnu_cxx { -// hash function for pointers -// TR1 and Boost have this defined by default, __gnu_cxx doesn't -template<typename T> -struct hash<T *> : public std::unary_function<T *, std::size_t> { - std::size_t operator()(T *p) const { - // Taken from Boost - std::size_t x = static_cast<std::size_t>(reinterpret_cast<std::ptrdiff_t>(p)); - return x + (x >> 3); - } -}; - -template <> -struct hash<Glib::ustring> : public std::unary_function<Glib::ustring, std::size_t> { - std::size_t operator()(Glib::ustring const &s) const { - return hash<std::string>()(s.raw()); - } -}; -} // namespace __gnu_cxx #endif #else diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp index 361a7a0de..bb6a2c4d7 100644 --- a/src/vanishing-point.cpp +++ b/src/vanishing-point.cpp @@ -85,12 +85,12 @@ have_VPs_of_same_perspective (VPDragger *dr1, VPDragger *dr2) } static void -vp_knot_moved_handler (SPKnot *knot, Geom::Point const *ppointer, guint state, gpointer data) +vp_knot_moved_handler (SPKnot *knot, Geom::Point const &ppointer, guint state, gpointer data) { VPDragger *dragger = (VPDragger *) data; VPDrag *drag = dragger->parent; - Geom::Point p = *ppointer; + Geom::Point p = ppointer; // FIXME: take from prefs double snap_dist = SNAP_DIST / inkscape_active_desktop()->current_zoom(); @@ -188,7 +188,7 @@ vp_knot_moved_handler (SPKnot *knot, Geom::Point const *ppointer, guint state, g m.unSetup(); if (s.getSnapped()) { p = s.getPoint(); - sp_knot_moveto(knot, p); + knot->moveto(p); } } @@ -277,22 +277,22 @@ VPDragger::VPDragger(VPDrag *parent, Geom::Point p, VanishingPoint &vp) if (vp.is_finite()) { // create the knot - this->knot = sp_knot_new(inkscape_active_desktop(), NULL); + this->knot = new SPKnot(inkscape_active_desktop(), NULL); this->knot->setMode(SP_KNOT_MODE_XOR); this->knot->setFill(VP_KNOT_COLOR_NORMAL, VP_KNOT_COLOR_NORMAL, VP_KNOT_COLOR_NORMAL); this->knot->setStroke(0x000000ff, 0x000000ff, 0x000000ff); - sp_knot_update_ctrl(this->knot); + this->knot->updateCtrl(); knot->item->ctrlType = CTRL_TYPE_ANCHOR; ControlManager::getManager().track(knot->item); // move knot to the given point - sp_knot_set_position (this->knot, this->point, SP_KNOT_STATE_NORMAL); - sp_knot_show (this->knot); + this->knot->setPosition(this->point, SP_KNOT_STATE_NORMAL); + this->knot->show(); // connect knot's signals - g_signal_connect (G_OBJECT (this->knot), "moved", G_CALLBACK (vp_knot_moved_handler), this); - g_signal_connect (G_OBJECT (this->knot), "grabbed", G_CALLBACK (vp_knot_grabbed_handler), this); - g_signal_connect (G_OBJECT (this->knot), "ungrabbed", G_CALLBACK (vp_knot_ungrabbed_handler), this); + this->_moved_connection = this->knot->moved_signal.connect(sigc::bind(sigc::ptr_fun(vp_knot_moved_handler), this)); + this->_grabbed_connection = this->knot->grabbed_signal.connect(sigc::bind(sigc::ptr_fun(vp_knot_grabbed_handler), this)); + this->_ungrabbed_connection = this->knot->ungrabbed_signal.connect(sigc::bind(sigc::ptr_fun(vp_knot_ungrabbed_handler), this)); // add the initial VP (which may be NULL!) this->addVP (vp); @@ -302,11 +302,12 @@ VPDragger::VPDragger(VPDrag *parent, Geom::Point p, VanishingPoint &vp) VPDragger::~VPDragger() { // disconnect signals - g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (vp_knot_moved_handler), this); - g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (vp_knot_grabbed_handler), this); - g_signal_handlers_disconnect_by_func(G_OBJECT(this->knot), (gpointer) G_CALLBACK (vp_knot_ungrabbed_handler), this); + this->_moved_connection.disconnect(); + this->_grabbed_connection.disconnect(); + this->_ungrabbed_connection.disconnect(); + /* unref should call destroy */ - g_object_unref (G_OBJECT (this->knot)); + knot_unref(this->knot); } /** diff --git a/src/vanishing-point.h b/src/vanishing-point.h index 53366fe66..ca34d9118 100644 --- a/src/vanishing-point.h +++ b/src/vanishing-point.h @@ -152,6 +152,11 @@ public: void updateZOrders(); void printVPs(); + +private: + sigc::connection _moved_connection; + sigc::connection _grabbed_connection; + sigc::connection _ungrabbed_connection; }; struct VPDrag { diff --git a/src/verbs.cpp b/src/verbs.cpp index 5914c058a..fad090852 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1187,9 +1187,9 @@ void SelectionVerb::perform(SPAction *action, void *data) case SP_VERB_SELECTION_BREAK_APART: sp_selected_path_break_apart(dt); break; - case SP_VERB_SELECTION_GRIDTILE: + case SP_VERB_SELECTION_ARRANGE: inkscape_dialogs_unhide(); - dt->_dlg_mgr->showDialog("TileDialog"); + dt->_dlg_mgr->showDialog("TileDialog"); //FIXME: denis: What's this string (to be changed) break; default: break; @@ -2562,8 +2562,8 @@ Verb *Verb::_base_verbs[] = { // Advanced tutorial for more info new SelectionVerb(SP_VERB_SELECTION_BREAK_APART, "SelectionBreakApart", N_("Break _Apart"), N_("Break selected paths into subpaths"), INKSCAPE_ICON("path-break-apart")), - new SelectionVerb(SP_VERB_SELECTION_GRIDTILE, "DialogGridArrange", N_("Ro_ws and Columns..."), - N_("Arrange selected objects in a table"), INKSCAPE_ICON("dialog-rows-and-columns")), + new SelectionVerb(SP_VERB_SELECTION_ARRANGE, "DialogArrange", N_("_Arrange..."), + N_("Arrange selected objects in a table or circle"), INKSCAPE_ICON("dialog-rows-and-columns")), // Layer new LayerVerb(SP_VERB_LAYER_NEW, "LayerNew", N_("_Add Layer..."), N_("Create a new layer"), INKSCAPE_ICON("layer-new")), diff --git a/src/verbs.h b/src/verbs.h index 0f764eb29..297ef1655 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -138,7 +138,7 @@ enum { SP_VERB_SELECTION_CREATE_BITMAP, SP_VERB_SELECTION_COMBINE, SP_VERB_SELECTION_BREAK_APART, - SP_VERB_SELECTION_GRIDTILE, + SP_VERB_SELECTION_ARRANGE, // Former SP_VERB_SELECTION_GRIDTILE /* Layer */ SP_VERB_LAYER_NEW, SP_VERB_LAYER_RENAME, diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 9567f81ba..a4cca9472 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -114,7 +114,7 @@ StrokeStyle::StrokeStyleButton::StrokeStyleButton(Gtk::RadioButtonGroup &grp, show(); set_mode(false); - Gtk::Widget *px = manage(Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_LARGE_TOOLBAR, icon))); + Gtk::Widget *px = Gtk::manage(Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_LARGE_TOOLBAR, icon))); g_assert(px != NULL); px->show(); add(*px); @@ -198,7 +198,7 @@ StrokeStyle::StrokeStyle() : hb->pack_start(*widthSpin, false, false, 0); unitSelector = new Inkscape::UI::Widget::UnitMenu(); unitSelector->setUnitType(Inkscape::Util::UNIT_TYPE_LINEAR); - Gtk::Widget *us = manage(unitSelector); + Gtk::Widget *us = Gtk::manage(unitSelector); SPDesktop *desktop = SP_ACTIVE_DESKTOP; unitSelector->addUnit(*unit_table.getUnit("%")); @@ -328,7 +328,7 @@ StrokeStyle::StrokeStyle() : // implement a set_mnemonic_source function in the // SPDashSelector class, so that we do not have to // expose any of the underlying widgets? - dashSelector = manage(new SPDashSelector); + dashSelector = Gtk::manage(new SPDashSelector); dashSelector->show(); @@ -354,7 +354,7 @@ StrokeStyle::StrokeStyle() : hb = spw_hbox(table, 1, 1, i); i++; - startMarkerCombo = manage(new MarkerComboBox("marker-start", SP_MARKER_LOC_START)); + startMarkerCombo = Gtk::manage(new MarkerComboBox("marker-start", SP_MARKER_LOC_START)); startMarkerCombo->set_tooltip_text(_("Start Markers are drawn on the first node of a path or shape")); startMarkerConn = startMarkerCombo->signal_changed().connect( sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( @@ -363,7 +363,7 @@ StrokeStyle::StrokeStyle() : hb->pack_start(*startMarkerCombo, true, true, 0); - midMarkerCombo = manage(new MarkerComboBox("marker-mid", SP_MARKER_LOC_MID)); + midMarkerCombo = Gtk::manage(new MarkerComboBox("marker-mid", SP_MARKER_LOC_MID)); midMarkerCombo->set_tooltip_text(_("Mid Markers are drawn on every node of a path or shape except the first and last nodes")); midMarkerConn = midMarkerCombo->signal_changed().connect( sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( @@ -372,7 +372,7 @@ StrokeStyle::StrokeStyle() : hb->pack_start(*midMarkerCombo, true, true, 0); - endMarkerCombo = manage(new MarkerComboBox("marker-end", SP_MARKER_LOC_END)); + endMarkerCombo = Gtk::manage(new MarkerComboBox("marker-end", SP_MARKER_LOC_END)); endMarkerCombo->set_tooltip_text(_("End Markers are drawn on the last node of a path or shape")); endMarkerConn = endMarkerCombo->signal_changed().connect( sigc::bind<MarkerComboBox *, StrokeStyle *, SPMarkerLoc>( |
