From 72c33248c0b7e5b1d9a63b205947d98e379d1775 Mon Sep 17 00:00:00 2001 From: cilix42 Date: Mon, 18 Aug 2008 00:44:51 +0000 Subject: [PATCH] Apply a geometric construction directly to selected item if the LPE supports it --- src/lpe-tool-context.cpp | 26 ++++++++++++++++++++++++-- src/lpe-tool-context.h | 2 ++ src/widgets/toolbox.cpp | 27 +++++++++++++++++++++------ 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/lpe-tool-context.cpp b/src/lpe-tool-context.cpp index 2a6bf5e50..fb252729d 100644 --- a/src/lpe-tool-context.cpp +++ b/src/lpe-tool-context.cpp @@ -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) { diff --git a/src/lpe-tool-context.h b/src/lpe-tool-context.h index 54716cddf..671ef91e6 100644 --- a/src/lpe-tool-context.h +++ b/src/lpe-tool-context.h @@ -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); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 5a1690492..ad6c213f1 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -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)); } -- 2.30.2