Code

Filter effects dialog:
[inkscape.git] / src / box3d-context.cpp
index a46783f4cec67789a60e9e636e85d6674444aee8..ada272acd2f88157d70d0758a84b55f5e36f74cc 100644 (file)
@@ -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)
 {
@@ -123,11 +124,11 @@ static void sp_3dbox_context_init(SP3DBoxContext *box3d_context)
                                               Box3D::VanishingPoint( NR::Point( 50.0, 600.0),
                                                                      NR::Point( -1.0,   0.0), Box3D::VP_INFINITE),
                                               // VP in y-direction
-                                              Box3D::VanishingPoint( NR::Point(700.0, 500.0),
-                                                                     NR::Point(sqrt(3.0),1.0), Box3D::VP_INFINITE),
-                                              // VP in z-direction
                                               Box3D::VanishingPoint( NR::Point(500.0,1000.0),
-                                                                     NR::Point(  0.0,   1.0), Box3D::VP_INFINITE));
+                                                                     NR::Point(  0.0,   1.0), Box3D::VP_INFINITE),
+                                              // VP in z-direction
+                                              Box3D::VanishingPoint( NR::Point(700.0, 500.0),
+                                                                     NR::Point(sqrt(3.0),1.0), Box3D::VP_INFINITE));
     }
     
     new (&box3d_context->sel_changed_connection) sigc::connection();
@@ -310,7 +311,7 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven
             event_context->within_tolerance = true;
             
             // remember clicked item, disregarding groups, honoring Alt
-            event_context->item_to_select = sp_event_context_find_item (desktop, button_w, event->button.state & GDK_MOD1_MASK, TRUE);
+            event_context->item_to_select = sp_event_context_find_item (desktop, button_w, event->button.state & GDK_MOD1_MASK, event->button.state & GDK_CONTROL_MASK);
 
             dragging = true;
             
@@ -357,27 +358,31 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven
 
             rc->ctrl_dragged  = event->motion.state & GDK_CONTROL_MASK;
 
-            if (event->motion.state & GDK_SHIFT_MASK)
-                rc->extruded = true; // set rc->extruded once shift is pressed
+            if (event->motion.state & GDK_SHIFT_MASK && !rc->extruded) {
+                /* once shift is pressed, set rc->extruded (no need to create further faces;
+                   all of them are already created in sp_3dbox_init) */
+                rc->extruded = true;
+            }
 
             if (!rc->extruded) {
                rc->drag_ptB = motion_dt;
+               rc->drag_ptC = motion_dt;
             } else {
                 // Without Ctrl, motion of the extruded corner is constrained to the
                 // perspective line from drag_ptB to vanishing point Y.
                 if (!rc->ctrl_dragged) {
-                       rc->drag_ptC = Box3D::perspective_line_snap (rc->drag_ptB, Box3D::Y, motion_dt);
+                       rc->drag_ptC = Box3D::perspective_line_snap (rc->drag_ptB, Box3D::Z, motion_dt);
                 } else {
                     rc->drag_ptC = motion_dt;
                 }
                 rc->drag_ptC = m.freeSnap(Inkscape::Snapper::BBOX_POINT | Inkscape::Snapper::SNAP_POINT, rc->drag_ptC, rc->item).getPoint();
                 if (rc->ctrl_dragged) {
-                       Box3D::PerspectiveLine pl1 (NR::Point (event_context->xp, event_context->yp), Box3D::Z);
+                       Box3D::PerspectiveLine pl1 (NR::Point (event_context->xp, event_context->yp), Box3D::Y);
                        Box3D::PerspectiveLine pl2 (rc->drag_ptB, Box3D::X);
                        NR::Point corner1 = pl1.meet(pl2);
                        
                        Box3D::PerspectiveLine pl3 (corner1, Box3D::X);
-                       Box3D::PerspectiveLine pl4 (rc->drag_ptC, Box3D::Y);
+                       Box3D::PerspectiveLine pl4 (rc->drag_ptC, Box3D::Z);
                        rc->drag_ptB = pl3.meet(pl4);
                 }
             }
@@ -387,7 +392,6 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven
             
             ret = TRUE;
         }
-        ret = TRUE;
         break;
     case GDK_BUTTON_RELEASE:
         event_context->xp = event_context->yp = 0;
@@ -395,7 +399,7 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven
             dragging = false;
 
             if (!event_context->within_tolerance) {
-                // we've been dragging, finish the rect
+                // we've been dragging, finish the box
                 sp_3dbox_finish(rc);
             } else if (event_context->item_to_select) {
                 // no dragging, select clicked item if any
@@ -425,12 +429,14 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven
         case GDK_Shift_R:
         case GDK_Meta_L:  // Meta is when you press Shift+Alt (at least on my machine)
         case GDK_Meta_R:
+            /***
             if (!dragging){
                 sp_event_show_modifier_tip (event_context->defaultMessageContext(), event,
                                             _("<b>Ctrl</b>: make square or integer-ratio rect, lock a rounded corner circular"),
                                             _("<b>Shift</b>: draw around the starting point"),
                                             NULL);
             }
+            ***/
             break;
         case GDK_Up:
         case GDK_Down:
@@ -444,7 +450,7 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven
         case GDK_x:
         case GDK_X:
             if (MOD__ALT_ONLY) {
-                desktop->setToolboxFocusTo ("altx-rect");
+                // desktop->setToolboxFocusTo ("altx-rect");
                 ret = TRUE;
             }
             break;
@@ -460,7 +466,7 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven
                                       event->button.time);
                 dragging = false;
                 if (!event_context->within_tolerance) {
-                    // we've been dragging, finish the rect
+                    // we've been dragging, finish the box
                     sp_3dbox_finish(rc);
                 }
                 // do not return true, so that space would work switching to selector
@@ -500,76 +506,60 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven
     return ret;
 }
 
-static void sp_3dbox_drag(SP3DBoxContext &rc, guint state)
+static void sp_3dbox_drag(SP3DBoxContext &bc, guint state)
 {
-    SPDesktop *desktop = SP_EVENT_CONTEXT(&rc)->desktop;
+    SPDesktop *desktop = SP_EVENT_CONTEXT(&bc)->desktop;
 
-    if (!rc.item) {
+    if (!bc.item) {
 
-        if (Inkscape::have_viable_layer(desktop, rc._message_context) == false) {
+        if (Inkscape::have_viable_layer(desktop, bc._message_context) == false) {
             return;
         }
 
         /* Create object */
-        Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_EVENT_CONTEXT_DOCUMENT(&rc));
+        Inkscape::XML::Document *xml_doc = sp_document_repr_doc(SP_EVENT_CONTEXT_DOCUMENT(&bc));
         Inkscape::XML::Node *repr = xml_doc->createElement("svg:g");
         repr->setAttribute("sodipodi:type", "inkscape:3dbox");
 
         /* Set style */
-        //sp_desktop_apply_style_tool (desktop, repr, "tools.shapes.3dbox", false);
+        sp_desktop_apply_style_tool (desktop, repr, "tools.shapes.3dbox", false);
 
-        rc.item = (SPItem *) desktop->currentLayer()->appendChildRepr(repr);
+        bc.item = (SPItem *) desktop->currentLayer()->appendChildRepr(repr);
         Inkscape::GC::release(repr);
-        rc.item->transform = SP_ITEM(desktop->currentRoot())->getRelativeTransform(desktop->currentLayer());
+        bc.item->transform = SP_ITEM(desktop->currentRoot())->getRelativeTransform(desktop->currentLayer());
 
-        /* The separate faces (created from rear to front) */
-        SP3DBox *box3d = SP_3DBOX(rc.item);
-        box3d->faces[2].hook_path_to_3dbox();
-        box3d->faces[3].hook_path_to_3dbox();
-        box3d->faces[4].hook_path_to_3dbox();
-        box3d->faces[5].hook_path_to_3dbox();
-        box3d->faces[0].hook_path_to_3dbox();
-        box3d->faces[1].hook_path_to_3dbox();
+        /* Hook paths to the faces of the box */
+        for (int i = 0; i < 6; ++i) {
+            SP_3DBOX(bc.item)->faces[i]->hook_path_to_3dbox();
+        }
 
-        rc.item->updateRepr();
+        bc.item->updateRepr();
 
         sp_canvas_force_full_redraw_after_interruptions(desktop->canvas, 5);
     }
 
     // FIXME: remove these extra points
-    NR::Point pt = rc.drag_ptB;
-    NR::Point shift_pt = rc.drag_ptC;
+    NR::Point pt = bc.drag_ptB;
+    NR::Point shift_pt = bc.drag_ptC;
 
     NR::Rect r;
     if (!(state & GDK_SHIFT_MASK)) {
-        r = Inkscape::snap_rectangular_box(desktop, rc.item, pt, rc.center, state);
+        r = Inkscape::snap_rectangular_box(desktop, bc.item, pt, bc.center, state);
     } else {
-        r = Inkscape::snap_rectangular_box(desktop, rc.item, shift_pt, rc.center, state);
-    }
-
-    /*** artefacts of rect ***
-    if ( rc.rx != 0.0 ) {
-        sp_3dbox_set_rx (SP_3DBOX(rc.item), TRUE, rc.rx);
-    }
-    if ( rc.ry != 0.0 ) {
-        if (rc.rx == 0.0)
-            sp_3dbox_set_ry (SP_3DBOX(rc.item), TRUE, CLAMP(rc.ry, 0, MIN(r.dimensions()[NR::X], r.dimensions()[NR::Y])/2));
-        else
-            sp_3dbox_set_ry (SP_3DBOX(rc.item), TRUE, CLAMP(rc.ry, 0, r.dimensions()[NR::Y]));
+        r = Inkscape::snap_rectangular_box(desktop, bc.item, shift_pt, bc.center, state);
     }
-    ***/
 
-    SPEventContext *ec = SP_EVENT_CONTEXT(&rc);
+    SPEventContext *ec = SP_EVENT_CONTEXT(&bc);
     NR::Point origin_w(ec->xp, ec->yp);
     NR::Point origin(desktop->w2d(origin_w));
-    sp_3dbox_position_set(rc);
+    sp_3dbox_position_set(bc);
 
     // status text
-    GString *xs = SP_PX_TO_METRIC_STRING(r.dimensions()[NR::X], desktop->namedview->getDefaultMetric());
-    GString *ys = SP_PX_TO_METRIC_STRING(r.dimensions()[NR::Y], desktop->namedview->getDefaultMetric());
-    rc._message_context->setF(Inkscape::NORMAL_MESSAGE, _("<b>Rectangle</b>: %s &#215; %s; with <b>Ctrl</b> to make square or integer-ratio rectangle; with <b>Shift</b> to draw around the starting point"), xs->str, ys->str);
-    g_string_free(xs, FALSE);
-    g_string_free(ys, FALSE);
+    //GString *Ax = SP_PX_TO_METRIC_STRING(origin[NR::X], desktop->namedview->getDefaultMetric());
+    //GString *Ay = SP_PX_TO_METRIC_STRING(origin[NR::Y], desktop->namedview->getDefaultMetric());
+    bc._message_context->setF(Inkscape::NORMAL_MESSAGE, _("<b>3D Box</b>; with <b>Shift</b> to extrude along the Z axis"));
+    //g_string_free(Ax, FALSE);
+    //g_string_free(Ay, FALSE);
 }
 
 static void sp_3dbox_finish(SP3DBoxContext *rc)
@@ -587,7 +577,7 @@ static void sp_3dbox_finish(SP3DBoxContext *rc)
 
         sp_desktop_selection(desktop)->set(rc->item);
         sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
-                         _("Create 3d box"));
+                         _("Create 3D box"));
 
         rc->item = NULL;
     }