Code

Apply a geometric construction directly to selected item if the LPE supports it
authorcilix42 <cilix42@users.sourceforge.net>
Mon, 18 Aug 2008 00:44:51 +0000 (00:44 +0000)
committercilix42 <cilix42@users.sourceforge.net>
Mon, 18 Aug 2008 00:44:51 +0000 (00:44 +0000)
src/lpe-tool-context.cpp
src/lpe-tool-context.h
src/widgets/toolbox.cpp

index 2a6bf5e50543595564bf1ca977179135a76c6ed1..fb252729dc1643245c5b350343e32c2e5b345282 100644 (file)
@@ -239,7 +239,7 @@ sp_lpetool_context_root_handler(SPEventContext *event_context, GdkEvent *event)
                 bool over_stroke = lc->shape_editor->is_over_stroke(NR::Point(event->button.x, event->button.y), true);
                 g_print ("over_stroke: %s\n", over_stroke ? "true" : "false");
 
-                sp_pen_context_wait_for_LPE_mouse_clicks(lc, type, Effect::acceptsNumClicks(type));
+                sp_pen_context_wait_for_LPE_mouse_clicks(lc, type, Inkscape::LivePathEffect::Effect::acceptsNumClicks(type));
 
                 // we pass the mouse click on to pen tool as the first click which it should collect
                 ret = ((SPEventContextClass *) lpetool_parent_class)->root_handler(event_context, event);
@@ -308,7 +308,11 @@ sp_lpetool_context_root_handler(SPEventContext *event_context, GdkEvent *event)
     return ret;
 }
 
-static int
+/*
+ * Finds the index in the list of geometric subtools corresponding to the given LPE type.
+ * Returns -1 if no subtool is found.
+ */
+int
 lpetool_mode_to_index(Inkscape::LivePathEffect::EffectType const type) {
     for (int i = 0; i < num_subtools; ++i) {
         if (lpesubtools[i] == type) {
@@ -318,6 +322,24 @@ lpetool_mode_to_index(Inkscape::LivePathEffect::EffectType const type) {
     return -1;
 }
 
+/*
+ * Attempts to perform the construction of the given type (i.e., to apply the corresponding LPE) to
+ * a single selected item. Returns whether we succeeded.
+ */
+bool
+lpetool_try_construction(SPLPEToolContext *lc, Inkscape::LivePathEffect::EffectType const type)
+{
+    Inkscape::Selection *selection = sp_desktop_selection(lc->desktop);
+    SPItem *item = selection->singleItem();
+
+    // TODO: should we check whether type represents a valid geometric construction?
+    if (item && SP_IS_LPE_ITEM(item) && Inkscape::LivePathEffect::Effect::acceptsNumClicks(type) == 0) {
+        Inkscape::LivePathEffect::Effect::createAndApply(type, sp_desktop_document(lc->desktop), item);
+        return true;
+    }
+    return false;
+}
+
 void
 lpetool_context_switch_mode(SPLPEToolContext *lc, Inkscape::LivePathEffect::EffectType const type)
 {
index 54716cddf97a38ee06ddf60d2f92ac56539f9bcf..671ef91e637711b7425020088a14b137db0a5aea 100644 (file)
@@ -48,6 +48,8 @@ struct SPLPEToolContext : public SPPenContext {
 
 struct SPLPEToolContextClass : public SPEventContextClass{};
 
+int lpetool_mode_to_index(Inkscape::LivePathEffect::EffectType const type);
+bool lpetool_try_construction(SPLPEToolContext *lc, Inkscape::LivePathEffect::EffectType const type);
 void lpetool_context_switch_mode(SPLPEToolContext *lc, Inkscape::LivePathEffect::EffectType const type);
 void lpetool_context_reset_limiting_bbox(SPLPEToolContext *lc);
 
index 5a1690492c91d3099416822af5e07fde8ae354ab..ad6c213f1c63a51b4bde23240e241d1f594ca81e 100644 (file)
@@ -4791,23 +4791,38 @@ static void sp_dropper_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* main
 // this is called when the mode is changed via the toolbar (i.e., one of the subtool buttons is pressed)
 static void sp_lpetool_mode_changed(EgeSelectOneAction *act, GObject *tbl)
 {
+    g_print ("sp_lpetool_mode_changed()\n");
     using namespace Inkscape::LivePathEffect;
 
     SPDesktop *desktop = (SPDesktop *) g_object_get_data(tbl, "desktop");
+    SPEventContext *ec = desktop->event_context;
+    if (!SP_IS_LPETOOL_CONTEXT(ec)) {
+        g_print ("event context is not a LPEToolContext!\n");
+        return;
+    }
 
     // only take action if run by the attr_changed listener
     if (!g_object_get_data(tbl, "freeze")) {
         // in turn, prevent listener from responding
         g_object_set_data(tbl, "freeze", GINT_TO_POINTER(TRUE));
 
-        // TODO: how can we set *all* actions inactive (such that no sutool is activated?)
-        gint lpeToolMode = ege_select_one_action_get_active(act);
-        if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
-            prefs_set_int_attribute( "tools.lpetool", "mode", lpeToolMode );
+        gint mode = ege_select_one_action_get_active(act);
+        EffectType type = lpesubtools[mode];
+
+        SPLPEToolContext *lc = SP_LPETOOL_CONTEXT(desktop->event_context);
+        bool success = lpetool_try_construction(lc, type);
+        if (success) {
+            // since the construction was already performed, we set the state back to inactive
+            ege_select_one_action_set_active(act, 0);
+            mode = 0;
+        } else {
+            // switch to the chosen subtool
+            SP_LPETOOL_CONTEXT(desktop->event_context)->mode = type;
         }
 
-        EffectType type = lpesubtools[lpeToolMode];
-        SP_LPETOOL_CONTEXT(desktop->event_context)->mode = type;
+        if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
+            prefs_set_int_attribute( "tools.lpetool", "mode", mode );
+        }
 
         g_object_set_data(tbl, "freeze", GINT_TO_POINTER(FALSE));
     }