From 6d26f0c3415176c2f2a85da0426cad95f46ca3cc Mon Sep 17 00:00:00 2001 From: acspike Date: Wed, 19 Apr 2006 03:51:07 +0000 Subject: [PATCH] Adding fit canvas verbs a few fixes in verbs.cpp and a new button --- src/document.cpp | 22 +++++++ src/document.h | 3 + src/selection-chemistry.cpp | 45 ++++++++++++++ src/selection-chemistry.h | 4 ++ src/ui/dialog/document-properties.cpp | 23 ++++++- src/verbs.cpp | 88 ++++++++++++++++++++++++++- src/verbs.h | 6 +- 7 files changed, 186 insertions(+), 5 deletions(-) diff --git a/src/document.cpp b/src/document.cpp index c5fa71f2b..863266c05 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -51,6 +51,8 @@ #include "unit-constants.h" #include "prefs-utils.h" #include "libavoid/router.h" +#include "libnr/nr-rect.h" +#include "sp-item-transform.h" #include "display/nr-arena-item.h" @@ -480,6 +482,26 @@ gdouble sp_document_height(SPDocument *document) return SP_ROOT(document->root)->height.computed; } +/** + * Given an NRRect that may, for example, correspond to the bbox of an object + * this function fits the canvas to that rect by resizing the canvas + * and translating the document root into position. + */ +void SPDocument::fitToRect(NRRect const & rect) +{ + g_return_if_fail(!empty(rect)); + + gdouble w = rect.x1 - rect.x0; + gdouble h = rect.y1 - rect.y0; + gdouble old_height = sp_document_height(this); + SPUnit unit = sp_unit_get_by_id(SP_UNIT_PX); + sp_document_set_width(this, w, &unit); + sp_document_set_height(this, h, &unit); + + NR::translate tr = NR::translate::translate(-rect.x0,-(rect.y0 + (h - old_height))); + sp_item_move_rel((SPItem *) root, tr); +} + void sp_document_set_uri(SPDocument *document, gchar const *uri) { g_return_if_fail(document != NULL); diff --git a/src/document.h b/src/document.h index 7cf1dc2de..f06ad2f6d 100644 --- a/src/document.h +++ b/src/document.h @@ -31,6 +31,7 @@ namespace Avoid { class Router; } +struct NRRect; struct SPDesktop; struct SPItem; struct SPObject; @@ -120,6 +121,8 @@ public: void reset_key (void *dummy); sigc::connection _selection_changed_connection; sigc::connection _desktop_activated_connection; + + void SPDocument::fitToRect(NRRect const & rect); }; SPDocument *sp_document_new (const gchar *uri, unsigned int keepalive, bool make_new = false); diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 0e208f216..c87817a40 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -65,6 +65,8 @@ #include "layer-fns.h" #include "context-fns.h" #include +#include "helper/units.h" +#include "sp-item.h" using NR::X; using NR::Y; @@ -2542,6 +2544,49 @@ void sp_selection_unset_mask(bool apply_clip_path) { sp_document_done (document); } +void fit_canvas_to_selection(SPDesktop *desktop) { + g_return_if_fail(desktop != NULL); + SPDocument *doc = sp_desktop_document(desktop); + + g_return_if_fail(doc != NULL); + g_return_if_fail(desktop->selection != NULL); + g_return_if_fail(!desktop->selection->isEmpty()); + NRRect bbox = {0,0,0,0}; + + desktop->selection->bounds(&bbox); + g_return_if_fail(!empty(bbox)); + + doc->fitToRect(bbox); +}; + +void fit_canvas_to_drawing(SPDocument *doc) { + g_return_if_fail(doc != NULL); + NRRect bbox = {0,0,0,0}; + + sp_document_ensure_up_to_date (doc); + sp_item_invoke_bbox(SP_ITEM(doc->root), &bbox, sp_item_i2r_affine(SP_ITEM(doc->root)), TRUE); + + g_return_if_fail(!empty(bbox)); + + doc->fitToRect(bbox); +}; + +void fit_canvas_to_selection_or_drawing(SPDesktop *desktop) { + g_return_if_fail(desktop != NULL); + SPDocument *doc = sp_desktop_document(desktop); + + g_return_if_fail(doc != NULL); + g_return_if_fail(desktop->selection != NULL); + + if (desktop->selection->isEmpty()) { + fit_canvas_to_drawing(doc); + } else { + fit_canvas_to_selection(desktop); + } + + sp_document_done(doc); +}; + /* Local Variables: mode:c++ diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h index 1e2e4cf07..45e45077a 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -93,6 +93,10 @@ void sp_selection_create_bitmap_copy (); void sp_selection_set_mask(bool apply_clip_path, bool apply_to_layer); void sp_selection_unset_mask(bool apply_clip_path); +void fit_canvas_to_selection(SPDesktop *desktop); +void fit_canvas_to_drawing(SPDocument *doc); +void fit_canvas_to_selection_or_drawing(SPDesktop *desktop); + /* selection cycling */ typedef enum diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 9951f5956..4d7b8abc7 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -32,6 +32,7 @@ #include "desktop-handles.h" #include "desktop.h" #include "sp-namedview.h" +#include "helper/action.h" #include "document-properties.h" @@ -55,6 +56,8 @@ 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 void fire_fit_canvas_to_selection_or_drawing(); + static Inkscape::XML::NodeEventVector const _repr_events = { NULL, /* child_added */ NULL, /* child_removed */ @@ -190,6 +193,8 @@ DocumentProperties::build_page() "bordercolor", "borderopacity", _wr); _rcb_shad.init (_("_Show border shadow"), _("If set, page border shows a shadow on its right and lower side"), "inkscape:showpageshadow", _wr, false); _rum_deflt.init (_("Default _units:"), "inkscape:document-units", _wr); + Gtk::Button* fit_canv = manage(new Gtk::Button(_("Fit canvas to current selection"))); + fit_canv->signal_clicked().connect(sigc::ptr_fun(fire_fit_canvas_to_selection_or_drawing)); Gtk::Label* label_gen = manage (new Gtk::Label); label_gen->set_markup (_("General")); Gtk::Label* label_bor = manage (new Gtk::Label); @@ -203,10 +208,11 @@ DocumentProperties::build_page() label_gen, 0, _rum_deflt._label, _rum_deflt._sel, _rcp_bg._label, _rcp_bg._cp, - 0, 0, + 0, 0, label_for, 0, 0, &_page_sizer, - 0, 0, + 0, fit_canv, + 0, 0, label_bor, 0, 0, _rcb_canb._button, 0, _rcb_bord._button, @@ -490,6 +496,19 @@ on_doc_replaced (SPDesktop* dt, SPDocument* doc) _instance->update(); } +static void +fire_fit_canvas_to_selection_or_drawing() { + SPDesktop *dt = SP_ACTIVE_DESKTOP; + if (!dt) return; + Verb *verb = Verb::get( SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING ); + if (verb) { + SPAction *action = verb->get_action(dt); + if (action) { + sp_action_perform(action, NULL); + } + } +} + } // namespace Dialog } // namespace UI diff --git a/src/verbs.cpp b/src/verbs.cpp index 29cf9a749..66792ae41 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -586,6 +586,7 @@ Verb::get_action(Inkscape::UI::View::View *view) action = this->make_action(view); // if (action == NULL) printf("Hmm, NULL in %s\n", _name); + if (action == NULL) printf("Hmm, NULL in %s\n", _name); if (!_default_sensitive) { sp_action_set_sensitive(action, 0); } else { @@ -1771,8 +1772,6 @@ SPActionEventVector DialogVerb::vector = SPActionEventVector HelpVerb::vector = {{NULL},HelpVerb::perform, NULL, NULL, NULL}; - -/* *********** Effect Last ********** */ /** * Action vector to define functions called if a staticly defined tutorial verb * is called @@ -1780,6 +1779,8 @@ SPActionEventVector HelpVerb::vector = SPActionEventVector TutorialVerb::vector = {{NULL},TutorialVerb::perform, NULL, NULL, NULL}; +/* *********** Effect Last ********** */ + /** \brief A class to represent the last effect issued */ class EffectLastVerb : public Verb { private: @@ -1847,6 +1848,79 @@ EffectLastVerb::perform(SPAction *action, void *data, void *pdata) } /* *********** End Effect Last ********** */ +/* *********** Fit Canvas ********** */ + +/** \brief A class to represent the canvas fitting verbs */ +class FitCanvasVerb : public Verb { +private: + static void perform(SPAction *action, void *mydata, void *otherdata); + static SPActionEventVector vector; +protected: + virtual SPAction *make_action(Inkscape::UI::View::View *view); +public: + /** \brief Use the Verb initializer with the same parameters. */ + FitCanvasVerb(unsigned int const code, + gchar const *id, + gchar const *name, + gchar const *tip, + gchar const *image) : + Verb(code, id, name, tip, image) + { + set_default_sensitive(false); + } +}; /* FitCanvasVerb class */ + +/** + * The vector to attach in the fit canvas verb. + */ +SPActionEventVector FitCanvasVerb::vector = + {{NULL},FitCanvasVerb::perform, NULL, NULL, NULL}; + +/** \brief Create an action for a \c FitCanvasVerb + \param view Which view the action should be created for + \return The built action. + + Calls \c make_action_helper with the \c vector. +*/ +SPAction * +FitCanvasVerb::make_action(Inkscape::UI::View::View *view) +{ + SPAction *action = make_action_helper(view, &vector); + return action; +} + +/** \brief Decode the verb code and take appropriate action */ +void +FitCanvasVerb::perform(SPAction *action, void *data, void *pdata) +{ + SPDesktop *dt = static_cast(sp_action_get_view(action)); + if (!dt) return; + SPDocument *doc = sp_desktop_document(dt); + if (!doc) return; + + switch ((long) data) { + case SP_VERB_FIT_CANVAS_TO_SELECTION: + fit_canvas_to_selection(dt); + break; + case SP_VERB_FIT_CANVAS_TO_DRAWING: + fit_canvas_to_drawing(doc); + break; + case SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING: + fit_canvas_to_selection_or_drawing(dt); + break; + default: + return; + } + + return; +} +/* *********** End Fit Canvas ********** */ + + + + + + /* these must be in the same order as the SP_VERB_* enum in "verbs.h" */ Verb *Verb::_base_verbs[] = { /* Header */ @@ -2246,6 +2320,8 @@ Verb *Verb::_base_verbs[] = { N_("Memory usage information"), NULL), new HelpVerb(SP_VERB_HELP_ABOUT, "HelpAbout", N_("_About Inkscape"), N_("Inkscape version, authors, license"), /*"help_about"*/"inkscape_options"), + //new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("_License"), + // N_("Distribution terms"), /*"show_license"*/"inkscape_options"), /* Tutorials */ new TutorialVerb(SP_VERB_TUTORIAL_BASIC, "TutorialsBasic", N_("Inkscape: _Basic"), @@ -2270,6 +2346,14 @@ Verb *Verb::_base_verbs[] = { new EffectLastVerb(SP_VERB_EFFECT_LAST_PREF, "EffectLastPref", N_("Previous Effect Settings..."), N_("Repeat the last effect with new settings"), NULL/*"tutorial_tips"*/), + /* Fit Canvas */ + new FitCanvasVerb(SP_VERB_FIT_CANVAS_TO_SELECTION, "FitCanvasToSelection", N_("Fit Canvas to Selection"), + N_("Fit the canvas to the current selection"), NULL), + new FitCanvasVerb(SP_VERB_FIT_CANVAS_TO_DRAWING, "FitCanvasToDrawing", N_("Fit Canvas to Drawing"), + N_("Fit the canvas to the drawing"), NULL), + new FitCanvasVerb(SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING, "FitCanvasToSelectionOrDrawing", N_("Fit Canvas to Selection or Drawing"), + N_("Fit the canvas to the current selection or the drawing if there is no selection"), NULL), + /* Footer */ new Verb(SP_VERB_LAST, NULL, NULL, NULL, NULL) }; diff --git a/src/verbs.h b/src/verbs.h index 521fdabaf..d715466e7 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -212,7 +212,7 @@ enum { SP_VERB_HELP_ABOUT_EXTENSIONS, SP_VERB_HELP_MEMORY, SP_VERB_HELP_ABOUT, - SP_VERB_SHOW_LICENSE, + //SP_VERB_SHOW_LICENSE, /* Tutorials */ SP_VERB_TUTORIAL_BASIC, SP_VERB_TUTORIAL_SHAPES, @@ -224,6 +224,10 @@ enum { /* Effects */ SP_VERB_EFFECT_LAST, SP_VERB_EFFECT_LAST_PREF, + /* Fit Canvas */ + SP_VERB_FIT_CANVAS_TO_SELECTION, + SP_VERB_FIT_CANVAS_TO_DRAWING, + SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING, /* Footer */ SP_VERB_LAST }; -- 2.30.2