X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fbox3d-context.cpp;h=f23e4d8836b182eac748e9fdfe972d7b23e5b1b3;hb=9dc68827cbd515262ecb8d5ae8547d9e82c72e00;hp=128b5f2ff187bd27f882963d59180c587e857e87;hpb=09ba3247163582bf2e30e17c4c154aa259ce038a;p=inkscape.git diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp index 128b5f2ff..f23e4d883 100644 --- a/src/box3d-context.cpp +++ b/src/box3d-context.cpp @@ -1,11 +1,11 @@ -#define __SP_BOX3D_CONTEXT_C__ - /* * 3D box drawing context * * Author: * Lauris Kaplinski * bulia byak + * Jon A. Cruz + * Abhishek Sharma * * Copyright (C) 2007 Maximilian Albert * Copyright (C) 2006 Johan Engelen @@ -49,6 +49,8 @@ #include "line-geometry.h" #include "shape-editor.h" +using Inkscape::DocumentUndo; + static void sp_box3d_context_class_init(Box3DContextClass *klass); static void sp_box3d_context_init(Box3DContext *box3d_context); static void sp_box3d_context_dispose(GObject *object); @@ -123,16 +125,17 @@ static void sp_box3d_context_init(Box3DContext *box3d_context) static void sp_box3d_context_finish(SPEventContext *ec) { - Box3DContext *bc = SP_BOX3D_CONTEXT(ec); - SPDesktop *desktop = ec->desktop; + Box3DContext *bc = SP_BOX3D_CONTEXT(ec); + SPDesktop *desktop = ec->desktop; - sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), GDK_CURRENT_TIME); - sp_box3d_finish(bc); + sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), GDK_CURRENT_TIME); + sp_box3d_finish(bc); bc->sel_changed_connection.disconnect(); +// sp_repr_remove_listener_by_data(cc->active_shape_repr, cc); if (((SPEventContextClass *) parent_class)->finish) { - ((SPEventContextClass *) parent_class)->finish(ec); - } + ((SPEventContextClass *) parent_class)->finish(ec); + } } @@ -179,17 +182,18 @@ static void sp_box3d_context_selection_changed(Inkscape::Selection *selection, g if (selection->perspList().size() == 1) { // selecting a single box changes the current perspective - ec->desktop->doc()->current_persp3d = selection->perspList().front(); + ec->desktop->doc()->setCurrentPersp3D(selection->perspList().front()); } } -/* create a default perspective in document defs if none is present - (can happen after 'vacuum defs' or when a pre-0.46 file is opened) */ -static void sp_box3d_context_check_for_persp_in_defs(SPDocument *document) { - SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document); +/* Create a default perspective in document defs if none is present (which can happen, among other + * circumstances, after 'vacuum defs' or when a pre-0.46 file is opened). + */ +static void sp_box3d_context_ensure_persp_in_defs(SPDocument *document) { + SPDefs *defs = reinterpret_cast(SP_DOCUMENT_DEFS(document)); bool has_persp = false; - for (SPObject *child = sp_object_first_child(defs); child != NULL; child = SP_OBJECT_NEXT(child) ) { + for ( SPObject *child = defs->firstChild(); child; child = child->getNext() ) { if (SP_IS_PERSP3D(child)) { has_persp = true; break; @@ -197,7 +201,7 @@ static void sp_box3d_context_check_for_persp_in_defs(SPDocument *document) { } if (!has_persp) { - document->current_persp3d = persp3d_create_xml_element (document); + document->setCurrentPersp3D(persp3d_create_xml_element (document)); } } @@ -209,8 +213,6 @@ static void sp_box3d_context_setup(SPEventContext *ec) ((SPEventContextClass *) parent_class)->setup(ec); } - sp_box3d_context_check_for_persp_in_defs(sp_desktop_document (ec->desktop)); - ec->shape_editor = new ShapeEditor(ec->desktop); SPItem *item = sp_desktop_selection(ec->desktop)->singleItem(); @@ -267,13 +269,13 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven static bool dragging; SPDesktop *desktop = event_context->desktop; + SPDocument *document = sp_desktop_document (desktop); Inkscape::Selection *selection = sp_desktop_selection (desktop); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int const snaps = prefs->getInt("/options/rotationsnapsperpi/value", 12); Box3DContext *bc = SP_BOX3D_CONTEXT(event_context); - g_assert (SP_ACTIVE_DOCUMENT->current_persp3d); - Persp3D *cur_persp = SP_ACTIVE_DOCUMENT->current_persp3d; + Persp3D *cur_persp = document->getCurrentPersp3D(); event_context->tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100); @@ -283,6 +285,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven if ( event->button.button == 1 && !event_context->space_panning) { Geom::Point const button_w(event->button.x, event->button.y); + Geom::Point button_dt(desktop->w2d(button_w)); // save drag origin event_context->xp = (gint) button_w[Geom::X]; @@ -294,25 +297,29 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven dragging = true; - /* */ - Geom::Point button_dt(desktop->w2d(button_w)); + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop, true, bc->item); + m.freeSnapReturnByRef(button_dt, Inkscape::SNAPSOURCE_NODE_HANDLE); + m.unSetup(); + bc->center = from_2geom(button_dt); + bc->drag_origin = from_2geom(button_dt); bc->drag_ptB = from_2geom(button_dt); bc->drag_ptC = from_2geom(button_dt); + // This can happen after saving when the last remaining perspective was purged and must be recreated. + if (!cur_persp) { + sp_box3d_context_ensure_persp_in_defs(document); + cur_persp = document->getCurrentPersp3D(); + } + /* Projective preimages of clicked point under current perspective */ - bc->drag_origin_proj = cur_persp->tmat.preimage (from_2geom(button_dt), 0, Proj::Z); + bc->drag_origin_proj = cur_persp->perspective_impl->tmat.preimage (from_2geom(button_dt), 0, Proj::Z); bc->drag_ptB_proj = bc->drag_origin_proj; bc->drag_ptC_proj = bc->drag_origin_proj; bc->drag_ptC_proj.normalize(); bc->drag_ptC_proj[Proj::Z] = 0.25; - /* Snap center */ - SnapManager &m = desktop->namedview->snap_manager; - m.setup(desktop, true, bc->item); - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, button_dt, Inkscape::SNAPSOURCE_HANDLE); - bc->center = from_2geom(button_dt); - sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), ( GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | @@ -342,8 +349,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven SnapManager &m = desktop->namedview->snap_manager; m.setup(desktop, true, bc->item); - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, motion_dt, Inkscape::SNAPSOURCE_HANDLE); - + m.freeSnapReturnByRef(motion_dt, Inkscape::SNAPSOURCE_NODE_HANDLE); bc->ctrl_dragged = event->motion.state & GDK_CONTROL_MASK; if (event->motion.state & GDK_SHIFT_MASK && !bc->extruded && bc->item) { @@ -352,10 +358,10 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven } if (!bc->extruded) { - bc->drag_ptB = from_2geom(motion_dt); - bc->drag_ptC = from_2geom(motion_dt); + bc->drag_ptB = from_2geom(motion_dt); + bc->drag_ptC = from_2geom(motion_dt); - bc->drag_ptB_proj = cur_persp->tmat.preimage (from_2geom(motion_dt), 0, Proj::Z); + bc->drag_ptB_proj = cur_persp->perspective_impl->tmat.preimage (from_2geom(motion_dt), 0, Proj::Z); bc->drag_ptC_proj = bc->drag_ptB_proj; bc->drag_ptC_proj.normalize(); bc->drag_ptC_proj[Proj::Z] = 0.25; @@ -364,25 +370,32 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven // perspective line from drag_ptB to vanishing point Y. if (!bc->ctrl_dragged) { /* snapping */ - Box3D::PerspectiveLine pline (bc->drag_ptB, Proj::Z, SP_ACTIVE_DOCUMENT->current_persp3d); + Box3D::PerspectiveLine pline (bc->drag_ptB, Proj::Z, document->getCurrentPersp3D()); bc->drag_ptC = pline.closest_to (from_2geom(motion_dt)); bc->drag_ptB_proj.normalize(); - bc->drag_ptC_proj = cur_persp->tmat.preimage (bc->drag_ptC, bc->drag_ptB_proj[Proj::X], Proj::X); + bc->drag_ptC_proj = cur_persp->perspective_impl->tmat.preimage (bc->drag_ptC, bc->drag_ptB_proj[Proj::X], Proj::X); } else { bc->drag_ptC = from_2geom(motion_dt); bc->drag_ptB_proj.normalize(); - bc->drag_ptC_proj = cur_persp->tmat.preimage (from_2geom(motion_dt), bc->drag_ptB_proj[Proj::X], Proj::X); + bc->drag_ptC_proj = cur_persp->perspective_impl->tmat.preimage (from_2geom(motion_dt), bc->drag_ptB_proj[Proj::X], Proj::X); } - Geom::Point pt2g = to_2geom(bc->drag_ptC); - m.freeSnapReturnByRef(Inkscape::SnapPreferences::SNAPPOINT_NODE, pt2g, Inkscape::SNAPSOURCE_HANDLE); - bc->drag_ptC = from_2geom(pt2g); + m.freeSnapReturnByRef(bc->drag_ptC, Inkscape::SNAPSOURCE_NODE_HANDLE); } + m.unSetup(); sp_box3d_drag(*bc, event->motion.state); ret = TRUE; + } else if (!sp_event_context_knot_mouseover(bc)) { + SnapManager &m = desktop->namedview->snap_manager; + m.setup(desktop); + + Geom::Point const motion_w(event->motion.x, event->motion.y); + Geom::Point motion_dt(desktop->w2d(motion_w)); + m.preSnap(Inkscape::SnapCandidatePoint(motion_dt, Inkscape::SNAPSOURCE_NODE_HANDLE)); + m.unSetup(); } break; case GDK_BUTTON_RELEASE: @@ -424,43 +437,43 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven break; case GDK_bracketright: - persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::X, -180/snaps, MOD__ALT); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::X, -180/snaps, MOD__ALT); + DocumentUndo::done(document, SP_VERB_CONTEXT_3DBOX, _("Change perspective (angle of PLs)")); ret = true; break; case GDK_bracketleft: - persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::X, 180/snaps, MOD__ALT); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::X, 180/snaps, MOD__ALT); + DocumentUndo::done(document, SP_VERB_CONTEXT_3DBOX, _("Change perspective (angle of PLs)")); ret = true; break; case GDK_parenright: - persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Y, -180/snaps, MOD__ALT); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::Y, -180/snaps, MOD__ALT); + DocumentUndo::done(document, SP_VERB_CONTEXT_3DBOX, _("Change perspective (angle of PLs)")); ret = true; break; case GDK_parenleft: - persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Y, 180/snaps, MOD__ALT); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::Y, 180/snaps, MOD__ALT); + DocumentUndo::done(document, SP_VERB_CONTEXT_3DBOX, _("Change perspective (angle of PLs)")); ret = true; break; case GDK_braceright: - persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Z, -180/snaps, MOD__ALT); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::Z, -180/snaps, MOD__ALT); + DocumentUndo::done(document, SP_VERB_CONTEXT_3DBOX, _("Change perspective (angle of PLs)")); ret = true; break; case GDK_braceleft: - persp3d_rotate_VP (inkscape_active_document()->current_persp3d, Proj::Z, 180/snaps, MOD__ALT); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + persp3d_rotate_VP (document->getCurrentPersp3D(), Proj::Z, 180/snaps, MOD__ALT); + DocumentUndo::done(document, SP_VERB_CONTEXT_3DBOX, _("Change perspective (angle of PLs)")); ret = true; break; @@ -468,7 +481,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven /* TODO: what is this??? case GDK_O: if (MOD__CTRL && MOD__SHIFT) { - Box3D::create_canvas_point(persp3d_get_VP(inkscape_active_document()->current_persp3d, Proj::W).affine(), + Box3D::create_canvas_point(persp3d_get_VP(document()->getCurrentPersp3D(), Proj::W).affine(), 6, 0xff00ff00); } ret = true; @@ -483,6 +496,16 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven } break; + case GDK_p: + case GDK_P: + if (MOD__SHIFT_ONLY) { + if (document->getCurrentPersp3D()) { + persp3d_print_debugging_info (document->getCurrentPersp3D()); + } + ret = true; + } + break; + case GDK_x: case GDK_X: if (MOD__ALT_ONLY) { @@ -552,7 +575,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven static void sp_box3d_drag(Box3DContext &bc, guint /*state*/) { - SPDesktop *desktop = SP_EVENT_CONTEXT(&bc)->desktop; + SPDesktop *desktop = bc.desktop; if (!bc.item) { @@ -560,25 +583,19 @@ static void sp_box3d_drag(Box3DContext &bc, guint /*state*/) return; } - /* Create object */ - 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:box3d"); + // Create object + SPBox3D *box3d = 0; + box3d = SPBox3D::createBox3D((SPItem *)desktop->currentLayer()); - /* Set style */ - sp_desktop_apply_style_tool (desktop, repr, "/tools/shapes/3dbox", false); + // Set style + desktop->applyCurrentOrToolStyle(box3d, "/tools/shapes/3dbox", false); + + bc.item = box3d; - bc.item = (SPItem *) desktop->currentLayer()->appendChildRepr(repr); - Inkscape::GC::release(repr); - Inkscape::XML::Node *repr_side; // TODO: Incorporate this in box3d-side.cpp! for (int i = 0; i < 6; ++i) { - repr_side = xml_doc->createElement("svg:path"); - repr_side->setAttribute("sodipodi:type", "inkscape:box3dside"); - repr->addChild(repr_side, NULL); - - Box3DSide *side = SP_BOX3D_SIDE(inkscape_active_document()->getObjectByRepr (repr_side)); - + Box3DSide *side = Box3DSide::createBox3DSide(box3d); + guint desc = Box3D::int_to_face(i); Box3D::Axis plane = (Box3D::Axis) (desc & 0x7); @@ -587,10 +604,27 @@ static void sp_box3d_drag(Box3DContext &bc, guint /*state*/) side->dir2 = Box3D::extract_second_axis_direction(plane); side->front_or_rear = (Box3D::FrontOrRear) (desc & 0x8); - /* Set style */ - box3d_side_apply_style(side); + // Set style + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + Glib::ustring descr = "/desktop/"; + descr += box3d_side_axes_string(side); + descr += "/style"; + Glib::ustring cur_style = prefs->getString(descr); + + bool use_current = prefs->getBool("/tools/shapes/3dbox/usecurrent", false); + if (use_current && !cur_style.empty()) { + // use last used style + side->setAttribute("style", cur_style.data()); + + } else { + // use default style + GString *pstring = g_string_new(""); + g_string_printf (pstring, "/tools/shapes/3dbox/%s", box3d_side_axes_string(side)); + desktop->applyCurrentOrToolStyle (side, pstring->str, false); + } - SP_OBJECT(side)->updateRepr(); // calls box3d_side_write() and updates, e.g., the axes string description + side->updateRepr(); // calls box3d_side_write() and updates, e.g., the axes string description } box3d_set_z_orders(SP_BOX3D(bc.item)); @@ -598,7 +632,7 @@ static void sp_box3d_drag(Box3DContext &bc, guint /*state*/) // TODO: It would be nice to show the VPs during dragging, but since there is no selection // at this point (only after finishing the box), we must do this "manually" - /**** bc._vpdrag->updateDraggers(); ****/ + /* bc._vpdrag->updateDraggers(); */ sp_canvas_force_full_redraw_after_interruptions(desktop->canvas, 5); } @@ -625,10 +659,14 @@ static void sp_box3d_drag(Box3DContext &bc, guint /*state*/) static void sp_box3d_finish(Box3DContext *bc) { bc->_message_context->clear(); - g_assert (SP_ACTIVE_DOCUMENT->current_persp3d); + bc->ctrl_dragged = false; + bc->extruded = false; if ( bc->item != NULL ) { SPDesktop * desktop = SP_EVENT_CONTEXT_DESKTOP(bc); + SPDocument *doc = sp_desktop_document(desktop); + if (!doc || !doc->getCurrentPersp3D()) + return; SPBox3D *box = SP_BOX3D(bc->item); @@ -642,14 +680,11 @@ static void sp_box3d_finish(Box3DContext *bc) sp_canvas_end_forced_full_redraws(desktop->canvas); sp_desktop_selection(desktop)->set(bc->item); - sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX, _("Create 3D box")); bc->item = NULL; } - - bc->ctrl_dragged = false; - bc->extruded = false; } void sp_box3d_context_update_lines(SPEventContext *ec) { @@ -669,4 +704,4 @@ void sp_box3d_context_update_lines(SPEventContext *ec) { fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :