index 9bf2d761d2c9eb9278079365c17c7aa8012fe010..8d7b6ac52291d88ce86a8fe786095af59862df9f 100644 (file)
//---------------------------------------------------
-static DocumentProperties *_instance = 0;
-
static void on_child_added(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, void * data);
static void on_child_removed(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, void * data);
static void on_repr_attr_changed (Inkscape::XML::Node *, gchar const *, gchar const *, gchar const *, bool, gpointer);
-static void on_doc_replaced (SPDesktop* dt, SPDocument* doc);
-static void on_activate_desktop (Inkscape::Application *, SPDesktop* dt, void*);
-static void on_deactivate_desktop (Inkscape::Application *, SPDesktop* dt, void*);
static Inkscape::XML::NodeEventVector const _repr_events = {
on_child_added, /* child_added */
};
-DocumentProperties*
-DocumentProperties::create()
+DocumentProperties &
+DocumentProperties::getInstance()
{
- if (_instance) return _instance;
- _instance = new DocumentProperties;
- _instance->init();
- return _instance;
-}
+ DocumentProperties &instance = *new DocumentProperties();
+ instance.init();
-void
-DocumentProperties::destroy()
-{
- if (_instance)
- {
- delete _instance;
- _instance = 0;
- }
+ return instance;
}
DocumentProperties::DocumentProperties()
- : Dialog ("dialogs.documentoptions", SP_VERB_DIALOG_NAMEDVIEW),
+ : UI::Widget::Panel ("", "dialogs.documentoptions", SP_VERB_DIALOG_NAMEDVIEW),
_page_page(1, 1), _page_guides(1, 1),
- _page_snap(1, 1), _page_grids(1, 1),
+ _page_snap(1, 1), _page_snap_dtls(1, 1),
+ _grids_label_crea("", Gtk::ALIGN_LEFT),
_grids_button_new(_("_New"), _("Create new grid.")),
_grids_button_remove(_("_Remove"), _("Remove selected grid.")),
+ _grids_label_def("", Gtk::ALIGN_LEFT),
_prefs_path("dialogs.documentoptions")
{
- set_resizable (false);
_tt.enable();
- get_vbox()->set_spacing (4);
- get_vbox()->pack_start (_notebook, true, true);
+ _getContents()->set_spacing (4);
+ _getContents()->pack_start(_notebook, true, true);
_notebook.append_page(_page_page, _("Page"));
_notebook.append_page(_page_guides, _("Guides"));
- _notebook.append_page(_page_grids, _("Grids"));
- _notebook.append_page(_page_snap, _("Snapping"));
+ _notebook.append_page(_grids_vbox, _("Grids"));
+ _notebook.append_page(_page_snap, _("Snap"));
+ _notebook.append_page(_page_snap_dtls, _("Snap points"));
build_page();
build_guides();
build_gridspage();
build_snap();
+ build_snap_dtls();
_grids_button_new.signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::onNewGrid));
_grids_button_remove.signal_clicked().connect(sigc::mem_fun(*this, &DocumentProperties::onRemoveGrid));
+
+ signalDocumentReplaced().connect(sigc::mem_fun(*this, &DocumentProperties::_handleDocumentReplaced));
+ signalActivateDesktop().connect(sigc::mem_fun(*this, &DocumentProperties::_handleActivateDesktop));
+ signalDeactiveDesktop().connect(sigc::mem_fun(*this, &DocumentProperties::_handleDeactivateDesktop));
}
void
{
update();
- Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(SP_ACTIVE_DESKTOP));
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(getDesktop()));
repr->addListener (&_repr_events, this);
- Inkscape::XML::Node *root = SP_OBJECT_REPR(sp_desktop_document(SP_ACTIVE_DESKTOP)->root);
+ Inkscape::XML::Node *root = SP_OBJECT_REPR(sp_desktop_document(getDesktop())->root);
root->addListener (&_repr_events, this);
- _doc_replaced_connection = SP_ACTIVE_DESKTOP->connectDocumentReplaced (sigc::ptr_fun (on_doc_replaced));
-
- g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop",
- G_CALLBACK(on_activate_desktop), 0);
-
- g_signal_connect(G_OBJECT(INKSCAPE), "deactivate_desktop",
- G_CALLBACK(on_deactivate_desktop), 0);
-
show_all_children();
-
- present();
+ _grids_button_remove.hide();
}
DocumentProperties::~DocumentProperties()
{
- Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(SP_ACTIVE_DESKTOP));
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(getDesktop()));
repr->removeListenerByData (this);
- Inkscape::XML::Node *root = SP_OBJECT_REPR(sp_desktop_document(SP_ACTIVE_DESKTOP)->root);
+ Inkscape::XML::Node *root = SP_OBJECT_REPR(sp_desktop_document(getDesktop())->root);
root->removeListenerByData (this);
- _doc_replaced_connection.disconnect();
}
//========================================================================
_rcp_hgui.init (_("_Highlight color:"), _("Highlighted guideline color"),
_("Color of a guideline when it is under mouse"),
"guidehicolor", "guidehiopacity", _wr);
+
+ _rcbsng.init (_("_Snap guides while dragging"),
+ _("While dragging a guide, snap to object nodes or bounding box corners ('Nodes' or 'Bounding box corners' must be enabled in the 'Snap' tab)"),
+ "inkscape:snap-guide", _wr);
+
Gtk::Label *label_gui = manage (new Gtk::Label);
label_gui->set_markup (_("<b>Guides</b>"));
0, _rcb_sgui._button,
_rcp_gui._label, _rcp_gui._cp,
_rcp_hgui._label, _rcp_hgui._cp,
+ 0, _rcbsng._button,
};
attach_all(_page_guides.table(), widget_array, G_N_ELEMENTS(widget_array));
DocumentProperties::build_snap()
{
_page_snap.show();
-
- _rcbsnop.init (_("Snap to object _paths"),
- _("Snap to other object paths"),
+ //General options
+ _rcbsnbb.init (_("_Bounding box corners"),
+ _("Snap bounding box corners to grid lines, to guides, and to other bounding boxes (Snapping of bounding boxes is only available in the selector tool)"),
+ "inkscape:snap-bbox", _wr);
+ _rcbsnn.init (_("_Nodes"),
+ _("Snap nodes to grid lines, to guides, to paths, and to other nodes"),
+ "inkscape:snap-nodes", _wr);
+
+ //Options for snapping to objects
+ _rcbsnop.init (_("Snap to pat_hs"),
+ _("Snap nodes to object paths"),
"inkscape:object-paths", _wr);
- _rcbsnon.init (_("Snap to object _nodes"),
- _("Snap to other object nodes"),
+ _rcbsnon.init (_("Snap to n_odes"),
+ _("Snap nodes and guides to object nodes"),
"inkscape:object-nodes", _wr);
- _rsu_sno.init (_("Snap s_ensitivity:"), _("Always snap"),
+ _rcbsnbbn.init (_("Snap to bounding box co_rners"),
+ _("Snap bounding box corners to other bounding box corners"),
+ "inkscape:bbox-nodes", _wr);
+ _rcbsnbbp.init (_("Snap to bounding box _edges"),
+ _("Snap bounding box corners and guides to bounding box edges"),
+ "inkscape:bbox-paths", _wr);
+
+ _rsu_sno.init (_("Snap _distance"), _("Snap at any d_istance"),
_("Snapping distance, in screen pixels, for snapping to objects"),
_("If set, objects snap to the nearest object, regardless of distance"),
"objecttolerance", _wr);
- _rsu_sn.init (_("Snap sens_itivity:"), _("Always snap"),
+
+ //Options for snapping to grids
+ _rsu_sn.init (_("Snap di_stance"), _("Snap at any dis_tance"),
_("Snapping distance, in screen pixels, for snapping to grid"),
_("If set, objects snap to the nearest grid line, regardless of distance"),
"gridtolerance", _wr);
- _rsu_gusn.init (_("Snap sensiti_vity:"), _("Always snap"),
+
+ //Options for snapping to guides
+ _rsu_gusn.init (_("Snap dist_ance"), _("Snap at any distan_ce"),
_("Snapping distance, in screen pixels, for snapping to guides"),
_("If set, objects snap to the nearest guide, regardless of distance"),
"guidetolerance", _wr);
+
+ //Other options to locate here: e.g. visual snapping indicators on/off
+
+ std::list<Gtk::ToggleButton*> slaves;
+ slaves.push_back(_rcbsnop._button);
+ slaves.push_back(_rcbsnon._button);
+ _rcbsnn.setSlaveButton(slaves);
+
+ slaves.clear();
+ slaves.push_back(_rcbsnbbp._button);
+ slaves.push_back(_rcbsnbbn._button);
+ _rcbsnbb.setSlaveButton(slaves);
+
+ Gtk::Label *label_g = manage (new Gtk::Label);
+ label_g->set_markup (_("<b>Snapping of</b>"));
Gtk::Label *label_o = manage (new Gtk::Label);
- label_o->set_markup (_("<b>Object Snapping</b>"));
+ label_o->set_markup (_("<b>Snapping to objects</b>"));
Gtk::Label *label_gr = manage (new Gtk::Label);
- label_gr->set_markup (_("<b>Grid Snapping</b>"));
+ label_gr->set_markup (_("<b>Snapping to grids</b>"));
Gtk::Label *label_gu = manage (new Gtk::Label);
- label_gu->set_markup (_("<b>Guide Snapping</b>"));
+ label_gu->set_markup (_("<b>Snapping to guides</b>"));
+ Gtk::Label *label_m = manage (new Gtk::Label);
+ label_m->set_markup (_("<b>Miscellaneous</b>"));
Gtk::Widget *const array[] =
{
+ label_g, 0,
+ 0, _rcbsnn._button,
+ 0, _rcbsnbb._button,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
label_o, 0,
- 0, _rcbsnop._button,
- 0, _rcbsnon._button,
+ 0, _rcbsnop._button,
+ 0, _rcbsnon._button,
+ 0, _rcbsnbbp._button,
+ 0, _rcbsnbbn._button,
0, _rsu_sno._vbox,
- 0, 0,
+ 0, 0,
label_gr, 0,
0, _rsu_sn._vbox,
- 0, 0,
- label_gu, 0,
- 0, _rsu_gusn._vbox,
+ 0, 0,
+ label_gu, 0,
+ 0, _rsu_gusn._vbox
};
attach_all(_page_snap.table(), array, G_N_ELEMENTS(array));
}
+void
+DocumentProperties::build_snap_dtls()
+{
+ _page_snap_dtls.show();
+
+ _rcbsigg.init (_("_Grid with guides"),
+ _("Snap to grid-guide intersections"),
+ "inkscape:snap-intersection-grid-guide", _wr);
+
+ _rcbsils.init (_("_Line segments"),
+ _("Snap to intersections of line segments ('snap to paths' must be enabled, see the previous tab)"),
+ "inkscape:snap-intersection-line-segments", _wr);
+
+ //Applies to both nodes and guides, but not to bboxes, that's why its located here
+ _rcbic.init (_("_Include the object's rotation center"),
+ _("Also snap the rotation center of an object when snapping nodes or guides"),
+ "inkscape:snap-center", _wr);
+
+ //Other options to locate here: e.g. visual snapping indicators on/off
+
+ Gtk::Label *label_i= manage (new Gtk::Label);
+ label_i->set_markup (_("<b>Snapping to intersections of</b>"));
+ Gtk::Label *label_m = manage (new Gtk::Label);
+ label_m->set_markup (_("<b>Miscellaneous</b>"));
+
+ Gtk::Widget *const array[] =
+ {
+ label_i, 0,
+ 0, _rcbsigg._button,
+ 0, _rcbsils._button,
+ 0, 0,
+ label_m, 0,
+ 0, _rcbic._button,
+ };
+
+ attach_all(_page_snap_dtls.table(), array, G_N_ELEMENTS(array));
+}
+
/**
* Called for _updating_ the dialog (e.g. when a new grid was manually added in XML)
*/
void
DocumentProperties::update_gridspage()
{
- SPDesktop *dt = SP_ACTIVE_DESKTOP;
+ SPDesktop *dt = getDesktop();
SPNamedView *nv = sp_desktop_namedview(dt);
//remove all tabs
}
//add tabs
+ bool grids_present = false;
for (GSList const * l = nv->grids; l != NULL; l = l->next) {
Inkscape::CanvasGrid * grid = (Inkscape::CanvasGrid*) l->data;
_grids_notebook.append_page(grid->getWidget(), grid->repr->attribute("id"));
-
+ grids_present = true;
}
_grids_notebook.show_all();
- _page_grids.table().resize_children();
+ if (grids_present)
+ _grids_button_remove.show();
+ else
+ _grids_button_remove.hide();
}
/**
void
DocumentProperties::build_gridspage()
{
- _page_grids.show();
-
/// \todo FIXME: gray out snapping when grid is off.
/// Dissenting view: you want snapping without grid.
- SPDesktop *dt = SP_ACTIVE_DESKTOP;
+ SPDesktop *dt = getDesktop();
SPNamedView *nv = sp_desktop_namedview(dt);
- Gtk::Label* label_crea = manage (new Gtk::Label);
- label_crea->set_markup (_("<b>Creation</b>"));
- Gtk::Label* label_crea_type = manage (new Gtk::Label);
- label_crea_type->set_markup (_("Gridtype"));
-
+ _grids_label_crea.set_markup(_("<b>Creation</b>"));
+ _grids_label_def.set_markup(_("<b>Defined grids</b>"));
+ _grids_hbox_crea.pack_start(_grids_combo_gridtype, true, true);
+ _grids_hbox_crea.pack_start(_grids_button_new, true, true);
+
for (gint t = 0; t <= GRID_MAXTYPENR; t++) {
_grids_combo_gridtype.append_text( CanvasGrid::getName( (GridType) t ) );
}
_grids_combo_gridtype.set_active_text( CanvasGrid::getName(GRID_RECTANGULAR) );
-
- Gtk::Label* label_def = manage (new Gtk::Label);
- label_def->set_markup (_("<b>Defined grids</b>"));
for (GSList const * l = nv->grids; l != NULL; l = l->next) {
Inkscape::CanvasGrid * grid = (Inkscape::CanvasGrid*) l->data;
_grids_notebook.append_page(grid->getWidget(), grid->repr->attribute("id"));
}
- Gtk::Widget *const widget_array[] =
- {
- label_crea, 0,
- label_crea_type, (Gtk::Widget*) &_grids_combo_gridtype,
- (Gtk::Widget*) &_grids_button_new, (Gtk::Widget*) &_grids_button_remove,
- label_def, 0
- };
- attach_all(_page_grids.table(), widget_array, G_N_ELEMENTS(widget_array));
- _page_grids.table().attach(_grids_notebook, 0, 3, 4, 5,
- Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0);
+ _grids_space.set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y);
+
+ _grids_vbox.set_spacing(4);
+ _grids_vbox.pack_start(_grids_label_crea, false, false);
+ _grids_vbox.pack_start(_grids_hbox_crea, false, false);
+ _grids_vbox.pack_start(_grids_space, false, false);
+ _grids_vbox.pack_start(_grids_label_def, false, false);
+ _grids_vbox.pack_start(_grids_notebook, false, false);
+ _grids_vbox.pack_start(_grids_button_remove, false, false);
+ _grids_button_remove.hide();
}
{
if (_wr.isUpdating()) return;
- SPDesktop *dt = SP_ACTIVE_DESKTOP;
+ SPDesktop *dt = getDesktop();
SPNamedView *nv = sp_desktop_namedview(dt);
_wr.setUpdating (true);
_rcp_hgui.setRgba32 (nv->guidehicolor);
//-----------------------------------------------------------snap
- _rcbsnop.setActive (nv->snap_manager.object.getSnapToPaths());
- _rcbsnon.setActive (nv->snap_manager.object.getSnapToNodes());
+
+ _rcbsnbb.setActive (nv->snap_manager.getSnapModeBBox());
+ _rcbsnn.setActive (nv->snap_manager.getSnapModeNode());
+ _rcbsng.setActive (nv->snap_manager.getSnapModeGuide());
+ _rcbic.setActive (nv->snap_manager.getIncludeItemCenter());
+ _rcbsnop.setActive(nv->snap_manager.object.getSnapToItemPath());
+ _rcbsnon.setActive(nv->snap_manager.object.getSnapToItemNode());
+ _rcbsnbbp.setActive(nv->snap_manager.object.getSnapToBBoxPath());
+ _rcbsnbbn.setActive(nv->snap_manager.object.getSnapToBBoxNode());
_rsu_sno.setValue (nv->objecttolerance);
_rsu_sn.setValue (nv->gridtolerance);
hide();
}
-
-
-static void
-on_child_added(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, void * data)
+void
+DocumentProperties::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *document)
{
- if (!_instance)
- return;
-
- _instance->update_gridspage();
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(desktop));
+ repr->addListener(&_repr_events, this);
+ Inkscape::XML::Node *root = SP_OBJECT_REPR(document->root);
+ root->addListener(&_repr_events, this);
+ update();
}
-static void
-on_child_removed(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, void * data)
+void
+DocumentProperties::_handleActivateDesktop(Inkscape::Application *, SPDesktop *desktop)
{
- if (!_instance)
- return;
-
- _instance->update_gridspage();
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(desktop));
+ repr->addListener(&_repr_events, this);
+ Inkscape::XML::Node *root = SP_OBJECT_REPR(sp_desktop_document(desktop)->root);
+ root->addListener(&_repr_events, this);
+ update();
}
-
-
-/**
- * Called when XML node attribute changed; updates dialog widgets.
- */
-static void
-on_repr_attr_changed (Inkscape::XML::Node *, gchar const *, gchar const *, gchar const *, bool, gpointer)
+void
+DocumentProperties::_handleDeactivateDesktop(Inkscape::Application *, SPDesktop *desktop)
{
- if (!_instance)
- return;
-
- _instance->update();
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(desktop));
+ repr->removeListenerByData(this);
+ Inkscape::XML::Node *root = SP_OBJECT_REPR(sp_desktop_document(desktop)->root);
+ root->removeListenerByData(this);
}
static void
-on_activate_desktop (Inkscape::Application *, SPDesktop* dt, void*)
+on_child_added(Inkscape::XML::Node */*repr*/, Inkscape::XML::Node */*child*/, Inkscape::XML::Node */*ref*/, void *data)
{
- if (!_instance)
- return;
-
- Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(SP_ACTIVE_DESKTOP));
- repr->addListener (&_repr_events, _instance);
- Inkscape::XML::Node *root = SP_OBJECT_REPR(sp_desktop_document(SP_ACTIVE_DESKTOP)->root);
- root->addListener (&_repr_events, _instance);
- _instance->_doc_replaced_connection = SP_ACTIVE_DESKTOP->connectDocumentReplaced (sigc::ptr_fun (on_doc_replaced));
- _instance->update();
+ if (DocumentProperties *dialog = static_cast<DocumentProperties *>(data))
+ dialog->update_gridspage();
}
static void
-on_deactivate_desktop (Inkscape::Application *, SPDesktop* dt, void*)
+on_child_removed(Inkscape::XML::Node */*repr*/, Inkscape::XML::Node */*child*/, Inkscape::XML::Node */*ref*/, void *data)
{
- if (!_instance)
- return;
-
- Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(SP_ACTIVE_DESKTOP));
- repr->removeListenerByData (_instance);
- Inkscape::XML::Node *root = SP_OBJECT_REPR(sp_desktop_document(SP_ACTIVE_DESKTOP)->root);
- root->removeListenerByData (_instance);
- _instance->_doc_replaced_connection.disconnect();
+ if (DocumentProperties *dialog = static_cast<DocumentProperties *>(data))
+ dialog->update_gridspage();
}
+
+
+/**
+ * Called when XML node attribute changed; updates dialog widgets.
+ */
static void
-on_doc_replaced (SPDesktop* dt, SPDocument* doc)
+on_repr_attr_changed (Inkscape::XML::Node *, gchar const *, gchar const *, gchar const *, bool, gpointer data)
{
- if (!_instance)
- return;
-
- Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(dt));
- repr->addListener (&_repr_events, _instance);
- Inkscape::XML::Node *root = SP_OBJECT_REPR(doc->root);
- root->addListener (&_repr_events, _instance);
- _instance->update();
+ if (DocumentProperties *dialog = static_cast<DocumentProperties *>(data))
+ dialog->update();
}
-
-
/*########################################################################
# BUTTON CLICK HANDLERS (callbacks)
########################################################################*/
void
DocumentProperties::onNewGrid()
{
- Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(SP_ACTIVE_DESKTOP));
+ SPDesktop *dt = getDesktop();
+ Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(dt));
+ SPDocument *doc = sp_desktop_document(dt);
Glib::ustring typestring = _grids_combo_gridtype.get_active_text();
- CanvasGrid::writeNewGridToRepr(repr, CanvasGrid::getGridTypeFromName(typestring.c_str()));
+ CanvasGrid::writeNewGridToRepr(repr, doc, CanvasGrid::getGridTypeFromName(typestring.c_str()));
}
gint pagenum = _grids_notebook.get_current_page();
if (pagenum == -1) // no pages
return;
-
+
Gtk::Widget *page = _grids_notebook.get_nth_page(pagenum);
if (!page) return;
-
+
Glib::ustring tabtext = _grids_notebook.get_tab_label_text(*page);
-
+
// find the grid with name tabtext (it's id) and delete that one.
- SPDesktop *dt = SP_ACTIVE_DESKTOP;
+ SPDesktop *dt = getDesktop();
SPNamedView *nv = sp_desktop_namedview(dt);
Inkscape::CanvasGrid * found_grid = NULL;
for (GSList const * l = nv->grids; l != NULL; l = l->next) {
// delete the grid that corresponds with the selected tab
// when the grid is deleted from SVG, the SPNamedview handler automatically deletes the object, so found_grid becomes an invalid pointer!
found_grid->repr->parent()->removeChild(found_grid->repr);
- sp_document_done(sp_desktop_document(dt), SP_VERB_DIALOG_NAMEDVIEW, _("Remove grid"));
+ sp_document_done(sp_desktop_document(dt), SP_VERB_DIALOG_NAMEDVIEW, _("Remove grid"));
}
}