From b7616586becf853e568343908ffa94b943249e10 Mon Sep 17 00:00:00 2001 From: cilix42 Date: Mon, 18 Aug 2008 00:38:00 +0000 Subject: [PATCH] Add a ShapeEditor to LPEToolContext which allows us to edit nodes (switching selections doesn't work right yet; changing the cursor would also be nice) --- src/event-context.cpp | 15 +++++++ src/event-context.h | 3 ++ src/lpe-tool-context.cpp | 86 ++++++++++++++++++++++++++++++---------- src/lpe-tool-context.h | 6 ++- src/nodepath.cpp | 26 +++++++++++- src/widgets/toolbox.cpp | 2 +- 6 files changed, 113 insertions(+), 25 deletions(-) diff --git a/src/event-context.cpp b/src/event-context.cpp index 450d1994d..b1c4f87ef 100644 --- a/src/event-context.cpp +++ b/src/event-context.cpp @@ -53,6 +53,8 @@ #include "attributes.h" #include "rubberband.h" #include "selcue.h" +#include "node-context.h" +#include "lpe-tool-context.h" #include "event-context.h" @@ -1036,6 +1038,19 @@ sp_event_context_over_item (SPDesktop *desktop, SPItem *item, NR::Point const p) return item_at_point; } +ShapeEditor * +sp_event_context_get_shape_editor (SPEventContext *ec) +{ + if (SP_IS_NODE_CONTEXT(ec)) { + return SP_NODE_CONTEXT(ec)->shape_editor; + } else if (SP_IS_LPETOOL_CONTEXT(ec)) { + return SP_LPETOOL_CONTEXT(ec)->shape_editor; + } else { + g_warning("ShapeEditor only exists in Node and Geometric Tool."); + return NULL; + } +} + /** * Called when SPEventContext subclass node attribute changed. */ diff --git a/src/event-context.h b/src/event-context.h index 54d854844..6284b6e2c 100644 --- a/src/event-context.h +++ b/src/event-context.h @@ -27,6 +27,7 @@ struct GrDrag; struct SPDesktop; struct SPItem; class KnotHolder; +class ShapeEditor; namespace Inkscape { class MessageContext; @@ -118,6 +119,8 @@ guint get_group0_keyval(GdkEventKey *event); SPItem *sp_event_context_find_item (SPDesktop *desktop, NR::Point const p, bool select_under, bool into_groups); SPItem *sp_event_context_over_item (SPDesktop *desktop, SPItem *item, NR::Point const p); +ShapeEditor *sp_event_context_get_shape_editor (SPEventContext *ec); + void ec_shape_event_attr_changed(Inkscape::XML::Node *shape_repr, gchar const *name, gchar const *old_value, gchar const *new_value, bool const is_interactive, gpointer const data); diff --git a/src/lpe-tool-context.cpp b/src/lpe-tool-context.cpp index c909f0a09..631207b10 100644 --- a/src/lpe-tool-context.cpp +++ b/src/lpe-tool-context.cpp @@ -21,6 +21,9 @@ #include "desktop.h" #include "message-context.h" #include "prefs-utils.h" +#include "shape-editor.h" +#include "selection.h" +#include "desktop-handles.h" /** @@ -135,7 +138,8 @@ sp_lpetool_context_init(SPLPEToolContext *lc) static void sp_lpetool_context_dispose(GObject *object) { - //SPLPEToolContext *erc = SP_LPETOOL_CONTEXT(object); + SPLPEToolContext *lc = SP_LPETOOL_CONTEXT(object); + delete lc->shape_editor; G_OBJECT_CLASS(lpetool_parent_class)->dispose(object); } @@ -148,15 +152,45 @@ sp_lpetool_context_setup(SPEventContext *ec) if (((SPEventContextClass *) lpetool_parent_class)->setup) ((SPEventContextClass *) lpetool_parent_class)->setup(ec); - lc->_message_context = new Inkscape::MessageContext((ec->desktop)->messageStack()); + Inkscape::Selection *selection = sp_desktop_selection (ec->desktop); + SPItem *item = selection->singleItem(); //lc->my_nc = new NodeContextCpp(lc->desktop, lc->prefs_repr, lc->key); + lc->shape_editor = new ShapeEditor(ec->desktop); + +// TODO temp force: + ec->enableSelectionCue(); + + if (item) { + lc->shape_editor->set_item(item, SH_NODEPATH); + lc->shape_editor->set_item(item, SH_KNOTHOLDER); + } if (prefs_get_int_attribute("tools.lpetool", "selcue", 0) != 0) { ec->enableSelectionCue(); } -// TODO temp force: - ec->enableSelectionCue(); + + lc->_message_context = new Inkscape::MessageContext((ec->desktop)->messageStack()); + + lc->shape_editor->update_statusbar(); +} + +/** +\brief Callback that processes the "changed" signal on the selection; +destroys old and creates new nodepath and reassigns listeners to the new selected item's repr +*/ +void +sp_lpetool_context_selection_changed(Inkscape::Selection *selection, gpointer data) +{ + SPLPEToolContext *lc = SP_LPETOOL_CONTEXT(data); + + // TODO: update ShapeEditorsCollective instead + lc->shape_editor->unset_item(SH_NODEPATH); + lc->shape_editor->unset_item(SH_KNOTHOLDER); + SPItem *item = selection->singleItem(); + lc->shape_editor->set_item(item, SH_NODEPATH); + lc->shape_editor->set_item(item, SH_KNOTHOLDER); + lc->shape_editor->update_statusbar(); } static void @@ -204,32 +238,40 @@ sp_lpetool_context_root_handler(SPEventContext *event_context, GdkEvent *event) switch (event->type) { case GDK_BUTTON_PRESS: - { - using namespace Inkscape::LivePathEffect; + if (event->button.button == 1 && !event_context->space_panning) { + // save drag origin + event_context->xp = (gint) event->button.x; + event_context->yp = (gint) event->button.y; + event_context->within_tolerance = true; + lc->shape_editor->cancel_hit(); - int mode = prefs_get_int_attribute("tools.lpetool", "mode", 0); - EffectType type = lpesubtools[mode]; - g_print ("Activating mode %d\n", mode); + using namespace Inkscape::LivePathEffect; - sp_pen_context_wait_for_LPE_mouse_clicks(lc, type, Effect::acceptsNumClicks(type)); + int mode = prefs_get_int_attribute("tools.lpetool", "mode", 0); + EffectType type = lpesubtools[mode]; + g_print ("Activating mode %d\n", mode); - // we pass the mouse click on to pen tool as the first click which it should collect - if (((SPEventContextClass *) lpetool_parent_class)->root_handler) { - ret = ((SPEventContextClass *) lpetool_parent_class)->root_handler(event_context, event); - } + // save drag origin + 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"); - ret = true; - break; - } - /** - if (event->button.button == 1 && !event_context->space_panning) { + sp_pen_context_wait_for_LPE_mouse_clicks(lc, type, Effect::acceptsNumClicks(type)); + + // we pass the mouse click on to pen tool as the first click which it should collect + if (((SPEventContextClass *) lpetool_parent_class)->root_handler) { + ret = ((SPEventContextClass *) lpetool_parent_class)->root_handler(event_context, event); + } + + ret = true; + break; + + /** SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(dc); NR::Point const button_w(event->button.x, event->button.y); NR::Point const button_dt(desktop->w2d(button_w)); - if (Inkscape::have_viable_layer(desktop, dc->_message_context) == false) { return TRUE; } @@ -260,8 +302,8 @@ sp_lpetool_context_root_handler(SPEventContext *event_context, GdkEvent *event) sp_canvas_force_full_redraw_after_interruptions(desktop->canvas, 3); dc->is_drawing = true; + **/ } - **/ break; case GDK_MOTION_NOTIFY: /** @@ -440,11 +482,13 @@ sp_lpetool_context_root_handler(SPEventContext *event_context, GdkEvent *event) break; } + /** if (!ret) { if (((SPEventContextClass *) lpetool_parent_class)->root_handler) { ret = ((SPEventContextClass *) lpetool_parent_class)->root_handler(event_context, event); } } + **/ return ret; } diff --git a/src/lpe-tool-context.h b/src/lpe-tool-context.h index ea21ecd51..032d89b68 100644 --- a/src/lpe-tool-context.h +++ b/src/lpe-tool-context.h @@ -36,8 +36,12 @@ enum LPEToolState { LPETOOL_STATE_NODE }; +class ShapeEditor; + struct SPLPEToolContext : public SPPenContext { - LPEToolState tool_state; + //int tool_state; + + ShapeEditor* shape_editor; }; struct SPLPEToolContextClass : public SPEventContextClass{}; diff --git a/src/nodepath.cpp b/src/nodepath.cpp index 0f6224093..817c588c3 100644 --- a/src/nodepath.cpp +++ b/src/nodepath.cpp @@ -37,6 +37,7 @@ #include "message-stack.h" #include "message-context.h" #include "node-context.h" +#include "lpe-tool-context.h" #include "shape-editor.h" #include "selection-chemistry.h" #include "selection.h" @@ -836,6 +837,23 @@ static gchar *create_typestr(Inkscape::NodePath::Path *np) return typestr; } +// Returns different message contexts depending on the current context. This function should only +// be called when ec is either a SPNodeContext or SPLPEToolContext, thus we return NULL in all +// other cases. +static Inkscape::MessageContext * +get_message_context(SPEventContext *ec) +{ + Inkscape::MessageContext *mc; + if (SP_IS_NODE_CONTEXT(ec)) { + mc = SP_NODE_CONTEXT(ec)->_node_message_context; + } else if (SP_IS_LPETOOL_CONTEXT(ec)) { + mc = ec->defaultMessageContext(); + } else { + g_warning ("Nodepath should only be present in Node tool or Geometric tool."); + return NULL; + } +} + /** \brief Fills node and handle positions for three nodes, splitting line marked by end at distance t. @@ -3903,7 +3921,9 @@ static void node_handle_moved(SPKnot *knot, NR::Point *p, guint state, gpointer if (!desktop) return; SPEventContext *ec = desktop->event_context; if (!ec) return; - Inkscape::MessageContext *mc = SP_NODE_CONTEXT (ec)->_node_message_context; + g_print ("4\n"); + Inkscape::MessageContext *mc = get_message_context(ec); + g_print ("5\n"); if (!mc) return; double degrees = 180 / M_PI * rnew.a; @@ -4728,7 +4748,9 @@ sp_nodepath_update_statusbar(Inkscape::NodePath::Path *nodepath)//!!!move to Sha SPEventContext *ec = desktop->event_context; if (!ec) return; - Inkscape::MessageContext *mc = SP_NODE_CONTEXT (ec)->_node_message_context; + g_print ("6\n"); + Inkscape::MessageContext *mc = get_message_context(ec); + g_print ("7\n"); if (!mc) return; inkscape_active_desktop()->emitToolSubselectionChanged(NULL); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 675900e74..9731436f0 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -4850,7 +4850,7 @@ void sp_lpetool_toolbox_sel_changed(Inkscape::Selection *selection, GObject *tbl) { using namespace Inkscape::LivePathEffect; - g_print ("sp_node_toolbox_sel_changed()\n"); + g_print ("sp_lpetool_toolbox_sel_changed()\n"); { GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "lpetool_test_action" ) ); SPItem *item = selection->singleItem(); -- 2.30.2