From 3a4914d91bd981c3dcfe44b0b83919e7538c673d Mon Sep 17 00:00:00 2001 From: cilix42 Date: Wed, 4 Jul 2007 10:49:11 +0000 Subject: [PATCH] Two variants of resizing 3D boxes (using three/four handles, respectively, demonstrating different behaviours). Much of this will be reverted once the final behaviour is settled. --- share/icons/icons.svg | 57 +++++++++++++++++++++++- src/box3d-context.cpp | 1 + src/box3d-context.h | 3 ++ src/object-edit.cpp | 85 ++++++++++++++++++++++++++++------- src/widgets/toolbox.cpp | 99 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 228 insertions(+), 17 deletions(-) diff --git a/share/icons/icons.svg b/share/icons/icons.svg index a579af719..cf0b3cf3b 100644 --- a/share/icons/icons.svg +++ b/share/icons/icons.svg @@ -4275,7 +4275,7 @@ inkscape:window-height="764" inkscape:window-width="1021" inkscape:cy="1119.1738" - inkscape:cx="696.90117" + inkscape:cx="821.60243" inkscape:zoom="4.050284" gridtolerance="6" snaptogrid="false" @@ -15087,4 +15087,59 @@ http://www.inkscape.org/ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:3.83003211;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" id="path4995" /> + + + + + + + + + + + diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp index 1ec86b827..a6a431905 100644 --- a/src/box3d-context.cpp +++ b/src/box3d-context.cpp @@ -91,6 +91,7 @@ static void sp_3dbox_context_class_init(SP3DBoxContextClass *klass) } Box3D::Perspective3D * SP3DBoxContext::current_perspective = NULL; +guint SP3DBoxContext::number_of_handles = 3; static void sp_3dbox_context_init(SP3DBoxContext *box3d_context) { diff --git a/src/box3d-context.h b/src/box3d-context.h index bf1d0e5ab..c244699b4 100644 --- a/src/box3d-context.h +++ b/src/box3d-context.h @@ -51,6 +51,9 @@ struct SP3DBoxContext : public SPEventContext { bool ctrl_dragged; /* whether we are ctrl-dragging */ bool extruded; /* whether shift-dragging already occured (i.e. the box is already extruded) */ + /* temporary member until the precise behaviour is sorted out */ + static guint number_of_handles; + static Box3D::Perspective3D *current_perspective; sigc::connection sel_changed_connection; diff --git a/src/object-edit.cpp b/src/object-edit.cpp index 684c4404f..563e7daa6 100644 --- a/src/object-edit.cpp +++ b/src/object-edit.cpp @@ -49,7 +49,8 @@ #define sp_round(v,m) (((v) < 0.0) ? ((ceil((v) / (m) - 0.5)) * (m)) : ((floor((v) / (m) + 0.5)) * (m))) static SPKnotHolder *sp_rect_knot_holder(SPItem *item, SPDesktop *desktop); -static SPKnotHolder *sp_3dbox_knot_holder(SPItem *item, SPDesktop *desktop); +//static +SPKnotHolder *sp_3dbox_knot_holder(SPItem *item, SPDesktop *desktop, guint number_of_handles); static SPKnotHolder *sp_arc_knot_holder(SPItem *item, SPDesktop *desktop); static SPKnotHolder *sp_star_knot_holder(SPItem *item, SPDesktop *desktop); static SPKnotHolder *sp_spiral_knot_holder(SPItem *item, SPDesktop *desktop); @@ -64,7 +65,7 @@ sp_item_knot_holder(SPItem *item, SPDesktop *desktop) if (SP_IS_RECT(item)) { return sp_rect_knot_holder(item, desktop); } else if (SP_IS_3DBOX(item)) { - return sp_3dbox_knot_holder(item, desktop); + return sp_3dbox_knot_holder(item, desktop, SP3DBoxContext::number_of_handles); } else if (SP_IS_ARC(item)) { return sp_arc_knot_holder(item, desktop); } else if (SP_IS_STAR(item)) { @@ -529,7 +530,7 @@ static SPKnotHolder *sp_rect_knot_holder(SPItem *item, SPDesktop *desktop) /* 3D Box */ static void sp_3dbox_knot_set(SPItem *item, guint knot_id, Box3D::Axis direction, - NR::Point const &new_pos, NR::Point const &origin, guint state) + NR::Point const &new_pos, NR::Point const &origin, guint state) { g_assert(item != NULL); SP3DBox *box = SP_3DBOX(item); @@ -538,11 +539,13 @@ static void sp_3dbox_knot_set(SPItem *item, guint knot_id, Box3D::Axis direction SPDocument *doc = SP_OBJECT_DOCUMENT(box); gdouble height = sp_document_height(doc); - if (direction == Box3D::Z) { - sp_3dbox_move_corner_in_Z_direction (box, knot_id, NR::Point (new_pos[NR::X], height - new_pos[NR::Y])); - } else { - sp_3dbox_move_corner_in_XY_plane (box, knot_id, NR::Point (new_pos[NR::X], height - new_pos[NR::Y])); - } + if (direction == Box3D::Z) { + sp_3dbox_move_corner_in_Z_direction (box, knot_id, NR::Point (new_pos[NR::X], height - new_pos[NR::Y]), + !(state & GDK_SHIFT_MASK)); + } else { + sp_3dbox_move_corner_in_XY_plane (box, knot_id, NR::Point (new_pos[NR::X], height - new_pos[NR::Y]), + (state & GDK_SHIFT_MASK) ? direction : Box3D::XY); + } sp_3dbox_update_curves (box); } @@ -560,7 +563,12 @@ static NR::Point sp_3dbox_knot_get(SPItem *item, guint knot_id) static void sp_3dbox_knot1_set(SPItem *item, NR::Point const &new_pos, NR::Point const &origin, guint state) { - sp_3dbox_knot_set (item, 1, Box3D::XY, new_pos, origin, state); + sp_3dbox_knot_set (item, 1, Box3D::Y, new_pos, origin, state); +} + +static void sp_3dbox_knot1_set_constrained(SPItem *item, NR::Point const &new_pos, NR::Point const &origin, guint state) +{ + sp_3dbox_knot_set (item, 1, Box3D::Y, new_pos, origin, state ^ GDK_SHIFT_MASK); } static NR::Point sp_3dbox_knot1_get(SPItem *item) @@ -570,7 +578,12 @@ static NR::Point sp_3dbox_knot1_get(SPItem *item) static void sp_3dbox_knot2_set(SPItem *item, NR::Point const &new_pos, NR::Point const &origin, guint state) { - sp_3dbox_knot_set (item, 2, Box3D::XY, new_pos, origin, state); + sp_3dbox_knot_set (item, 2, Box3D::X, new_pos, origin, state); +} + +static void sp_3dbox_knot2_set_constrained(SPItem *item, NR::Point const &new_pos, NR::Point const &origin, guint state) +{ + sp_3dbox_knot_set (item, 2, Box3D::X, new_pos, origin, state ^ GDK_SHIFT_MASK); } static NR::Point sp_3dbox_knot2_get(SPItem *item) @@ -578,6 +591,20 @@ static NR::Point sp_3dbox_knot2_get(SPItem *item) return sp_3dbox_knot_get(item, 2); } +static void sp_3dbox_knot3_set(SPItem *item, NR::Point const &new_pos, NR::Point const &origin, guint state) +{ + if (!(state & GDK_SHIFT_MASK)) { + sp_3dbox_knot_set (item, 3, Box3D::Y, new_pos, origin, state); + } else { + sp_3dbox_knot_set (item, 3, Box3D::Z, new_pos, origin, state ^ GDK_SHIFT_MASK); + } +} + +static NR::Point sp_3dbox_knot3_get(SPItem *item) +{ + return sp_3dbox_knot_get(item, 3); +} + static void sp_3dbox_knot5_set(SPItem *item, NR::Point const &new_pos, NR::Point const &origin, guint state) { sp_3dbox_knot_set (item, 5, Box3D::Z, new_pos, origin, state); @@ -588,16 +615,42 @@ static NR::Point sp_3dbox_knot5_get(SPItem *item) return sp_3dbox_knot_get(item, 5); } -static SPKnotHolder * -sp_3dbox_knot_holder(SPItem *item, SPDesktop *desktop) +static void sp_3dbox_knot7_set(SPItem *item, NR::Point const &new_pos, NR::Point const &origin, guint state) +{ + sp_3dbox_knot_set (item, 7, Box3D::Z, new_pos, origin, state); +} + +static NR::Point sp_3dbox_knot7_get(SPItem *item) +{ + return sp_3dbox_knot_get(item, 7); +} + +//static +SPKnotHolder * +sp_3dbox_knot_holder(SPItem *item, SPDesktop *desktop, guint number_of_handles) { g_assert(item != NULL); SPKnotHolder *knot_holder = sp_knot_holder_new(desktop, item, NULL); - sp_knot_holder_add(knot_holder, sp_3dbox_knot1_set, sp_3dbox_knot1_get, NULL,_("Resize box in X/Y direction")); - sp_knot_holder_add(knot_holder, sp_3dbox_knot2_set, sp_3dbox_knot2_get, NULL,_("Resize box in X/Y direction")); - sp_knot_holder_add(knot_holder, sp_3dbox_knot5_set, sp_3dbox_knot5_get, NULL,_("Resize box in Z direction")); - sp_pat_knot_holder(item, knot_holder); + switch (number_of_handles) { + case 3: + sp_knot_holder_add(knot_holder, sp_3dbox_knot1_set, sp_3dbox_knot1_get, NULL,_("Resize box in X/Y direction")); + sp_knot_holder_add(knot_holder, sp_3dbox_knot2_set, sp_3dbox_knot2_get, NULL,_("Resize box in X/Y direction")); + sp_knot_holder_add(knot_holder, sp_3dbox_knot5_set, sp_3dbox_knot5_get, NULL,_("Resize box in Z direction")); + sp_pat_knot_holder(item, knot_holder); + break; + case 4: + sp_knot_holder_add(knot_holder, sp_3dbox_knot1_set_constrained, sp_3dbox_knot1_get, NULL,_("Resize box in X/Y direction")); + sp_knot_holder_add(knot_holder, sp_3dbox_knot2_set_constrained, sp_3dbox_knot2_get, NULL,_("Resize box in X/Y direction")); + sp_knot_holder_add_full(knot_holder, sp_3dbox_knot3_set, sp_3dbox_knot3_get, NULL, + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR, _("Resize box in Y direction")); + sp_knot_holder_add(knot_holder, sp_3dbox_knot7_set, sp_3dbox_knot7_get, NULL,_("Resize box in Z direction")); + sp_pat_knot_holder(item, knot_holder); + break; + default: + g_print ("Wrong number of handles (%d): Not implemented yet.\n", number_of_handles); + break; + } return knot_holder; } diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 26798bce4..cd2506bef 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -64,6 +64,7 @@ #include "node-context.h" #include "shape-editor.h" #include "sp-rect.h" +#include "box3d.h" #include "box3d-context.h" #include "sp-star.h" #include "sp-spiral.h" @@ -93,6 +94,11 @@ #include "ege-select-one-action.h" #include "helper/unit-tracker.h" +// FIXME: The next two lines are only temporarily added until +// the final resizing behaviour of 3D boxes is sorted out. +#include "knotholder.h" +SPKnotHolder *sp_3dbox_knot_holder(SPItem *item, SPDesktop *desktop, guint number_of_handles); + using Inkscape::UnitTracker; typedef void (*SetupFunction)(GtkWidget *toolbox, SPDesktop *desktop); @@ -281,6 +287,9 @@ static gchar const * ui_descr = " " " " " " + " " + " " + " " " " " " @@ -2130,6 +2139,60 @@ static void sp_3dbox_toggle_vp_changed( GtkToggleAction *act, gpointer data ) } +static void sp_3dboxtb_handles_state_changed( EgeSelectOneAction *act, GObject *tbl ) +{ + SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); + if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) { + if ( ege_select_one_action_get_active( act ) != 0 ) { + prefs_set_string_attribute("tools.shapes.3dbox", "constrainedXYmoving", "true"); + } else { + prefs_set_string_attribute("tools.shapes.3dbox", "constrainedXYmoving", NULL); + } + } + + // quit if run by the attr_changed listener + if (g_object_get_data( tbl, "freeze" )) { + return; + } + + // in turn, prevent listener from responding + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); + + bool modmade = false; + + SPEventContext *ec = SP_EVENT_CONTEXT(inkscape_active_event_context()); + if (!SP_IS_3DBOX_CONTEXT(ec)) return; + SP3DBoxContext *bc = SP_3DBOX_CONTEXT(ec); + for (GSList const *items = sp_desktop_selection(desktop)->itemList(); + items != NULL; + items = items->next) + { + if (SP_IS_3DBOX((SPItem *) items->data)) { + if (ec->shape_knot_holder) { + sp_knot_holder_destroy(ec->shape_knot_holder); + if ( ege_select_one_action_get_active(act) != 0 ) { + bc->number_of_handles = 4; + ec->shape_knot_holder = sp_3dbox_knot_holder((SPItem *) items->data, SP_ACTIVE_DESKTOP, 4);; + } else { + bc->number_of_handles = 3; + ec->shape_knot_holder = sp_3dbox_knot_holder((SPItem *) items->data, SP_ACTIVE_DESKTOP, 3);; + } + } else { + g_print ("Warning: No KnotHolder detected!!!\n"); + } + modmade = true; + } + } + + if (modmade) { + sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + _("3D Box: Change number of handles")); + } + + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); +} + + static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { bool toggled = false; @@ -2177,6 +2240,42 @@ static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction } gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), toggled ); } + + + /* Number of handles and resizing behaviour */ + { + GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); + + GtkTreeIter iter; + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("Three Handles"), + 1, _("Switch to three handles (arbitrary resizing in XY-direction)"), + 2, "3dbox_three_handles", + -1 ); + + gtk_list_store_append( model, &iter ); + gtk_list_store_set( model, &iter, + 0, _("Four Handles"), + 1, _("Switch to four handles (constrained resizing in XY-direction)"), + 2, "3dbox_four_handles", + -1 ); + + EgeSelectOneAction* act = ege_select_one_action_new( "3DBoxHandlesAction", _(""), _(""), NULL, GTK_TREE_MODEL(model) ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + g_object_set_data( holder, "handles_action", act ); + + ege_select_one_action_set_appearance( act, "full" ); + ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); + g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); + ege_select_one_action_set_icon_column( act, 2 ); + ege_select_one_action_set_tooltip_column( act, 1 ); + + gchar const *handlestr = prefs_get_string_attribute("tools.shapes.3dbox", "constrainedXYmoving"); + bool isConstrained = (!handlestr || (handlestr && !strcmp(handlestr, "true"))); + ege_select_one_action_set_active( act, isConstrained ? 0 : 1 ); + g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_3dboxtb_handles_state_changed), holder ); + } } //######################## -- 2.30.2