X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fdesktop.cpp;h=d9f82934c039c13550c69a7dbee1635c0cba5bde;hb=ad4b3133547bb79aa1362ab40512d31267868c82;hp=722aa81e9b61e2bf71324e04ee297eab224bd610;hpb=5c8e50345f9a78a6823dff57ba6b75109f81cd77;p=inkscape.git diff --git a/src/desktop.cpp b/src/desktop.cpp index 722aa81e9..d9f82934c 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -9,7 +9,10 @@ * bulia byak * Ralf Stephan * John Bintz + * Johan Engelen * + * Copyright (C) 2007 Jon A. Cruz + * Copyright (C) 2006-2007 Johan Engelen * Copyright (C) 2006 John Bintz * Copyright (C) 2004 MenTaLguY * Copyright (C) 1999-2002 Lauris Kaplinski @@ -52,6 +55,7 @@ #include #include +#include #include "macros.h" #include "inkscape-private.h" @@ -80,6 +84,9 @@ #include "message-context.h" #include "layer-manager.h" #include "event-log.h" +#include "display/canvas-grid.h" + +#include "display/sp-canvas.h" namespace Inkscape { namespace XML { class Node; }} @@ -99,46 +106,56 @@ static void _update_snap_distances (SPDesktop *desktop); * \pre namedview != NULL. * \pre canvas != NULL. */ -SPDesktop::SPDesktop() -{ - _dlg_mgr = NULL; - _widget = 0; - namedview = NULL; - selection = NULL; - acetate = NULL; - main = NULL; - grid = NULL; - guides = NULL; - drawing = NULL; - sketch = NULL; - controls = NULL; - event_context = 0; - layer_manager = 0; - +SPDesktop::SPDesktop() : + _dlg_mgr( 0 ), + namedview( 0 ), + canvas( 0 ), + selection( 0 ), + event_context( 0 ), + layer_manager( 0 ), + event_log( 0 ), + acetate( 0 ), + main( 0 ), + gridgroup( 0 ), + guides( 0 ), + drawing( 0 ), + sketch( 0 ), + controls( 0 ), + table( 0 ), + page( 0 ), + page_border( 0 ), + current( 0 ), + zooms_past( 0 ), + zooms_future( 0 ), + dkey( 0 ), + number( 0 ), + is_fullscreen( false ), + interaction_disabled_counter( 0 ), + waiting_cursor( false ), + guides_active( false ), + gr_item( 0 ), + gr_point_type( 0 ), + gr_point_i( 0 ), + gr_fill_or_stroke( true ), + _layer_hierarchy( 0 ), + _reconstruction_old_layer_id( 0 ), + _widget( 0 ), + _inkscape( 0 ), + _guides_message_context( 0 ), + _active( false ), + _w2d(), + _d2w(), + _doc2dt( NR::Matrix(NR::scale(1, -1)) ), + grids_visible( true ) +{ _d2w.set_identity(); _w2d.set_identity(); - _doc2dt = NR::Matrix(NR::scale(1, -1)); - - guides_active = false; - - zooms_past = NULL; - zooms_future = NULL; - - is_fullscreen = false; - gr_item = NULL; - gr_point_num = 0; - gr_fill_or_stroke = true; - - _layer_hierarchy = NULL; - _active = false; - - selection = Inkscape::GC::release (new Inkscape::Selection (this)); + selection = Inkscape::GC::release( new Inkscape::Selection(this) ); } void SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas) - { _guides_message_context = new Inkscape::MessageContext(const_cast(messageStack())); @@ -187,11 +204,15 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas) SP_CANVAS_ARENA (drawing)->arena->delta = prefs_get_double_attribute ("options.cursortolerance", "value", 1.0); // default is 1 px - // Start always in normal mode - SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_NORMAL; - canvas->rendermode = RENDERMODE_NORMAL; // canvas needs that for choosing the best buffer size + if (prefs_get_int_attribute("options.startmode", "outline", 0)) { + // Start in outline mode + setDisplayModeOutline(); + } else { + // Start in normal mode, default + setDisplayModeNormal(); + } - grid = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); + gridgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); guides = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); sketch = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); @@ -251,9 +272,7 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas) _reconstruction_finish_connection = document->connectReconstructionFinish(sigc::bind(sigc::ptr_fun(_reconstruction_finish), this)); _reconstruction_old_layer_id = NULL; - - _commit_connection = document->connectCommit(sigc::mem_fun(*this, &SPDesktop::updateNow)); - + // ? // sp_active_desktop_set (desktop); _inkscape = INKSCAPE; @@ -289,9 +308,7 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas) // (Setting up after the connections are all in place, as it may use some of them) layer_manager = new Inkscape::LayerManager( this ); - /* setup EventLog */ - event_log = new Inkscape::EventLog(document); - document->addUndoObserver(*event_log); + grids_visible = true; } @@ -346,14 +363,26 @@ void SPDesktop::setDisplayModeNormal() { SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_NORMAL; canvas->rendermode = RENDERMODE_NORMAL; // canvas needs that for choosing the best buffer size + displayMode = RENDERMODE_NORMAL; sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw + _widget->setTitle(SP_DOCUMENT_NAME(sp_desktop_document(this))); } void SPDesktop::setDisplayModeOutline() { SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_OUTLINE; canvas->rendermode = RENDERMODE_OUTLINE; // canvas needs that for choosing the best buffer size + displayMode = RENDERMODE_OUTLINE; sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw + _widget->setTitle(SP_DOCUMENT_NAME(sp_desktop_document(this))); +} + +void SPDesktop::displayModeToggle() +{ + if (displayMode == RENDERMODE_OUTLINE) + setDisplayModeNormal(); + else + setDisplayModeOutline(); } /** @@ -413,8 +442,12 @@ bool SPDesktop::isLayer(SPObject *object) const { bool SPDesktop::isWithinViewport (SPItem *item) const { NR::Rect const viewport = get_display_area(); - NR::Rect const bbox = sp_item_bbox_desktop(item); - return viewport.contains(bbox); + NR::Maybe const bbox = sp_item_bbox_desktop(item); + if (bbox) { + return viewport.contains(*bbox); + } else { + return true; + } } /// @@ -805,7 +838,7 @@ SPDesktop::zoom_page() NR::Rect d(NR::Point(0, 0), NR::Point(sp_document_width(doc()), sp_document_height(doc()))); - if (d.dimensions()[NR::X] < 1.0 || d.dimensions()[NR::Y] < 1.0) { + if (d.isEmpty(1.0)) { return; } @@ -836,13 +869,13 @@ SPDesktop::zoom_page_width() void SPDesktop::zoom_selection() { - NR::Rect const d = selection->bounds(); + NR::Maybe const d = selection->bounds(); - if (d.dimensions()[NR::X] < 0.1 || d.dimensions()[NR::Y] < 0.1) { + if ( !d || d->isEmpty(0.1) ) { return; } - set_display_area(d, 10); + set_display_area(*d, 10); } /** @@ -864,29 +897,29 @@ SPDesktop::zoom_drawing() SPItem *docitem = SP_ITEM (sp_document_root (doc())); g_return_if_fail (docitem != NULL); - NR::Rect d = sp_item_bbox_desktop(docitem); + NR::Maybe d = sp_item_bbox_desktop(docitem); /* Note that the second condition here indicates that ** there are no items in the drawing. */ - if ( d.dimensions()[NR::X] < 1.0 || d.dimensions()[NR::Y] < 1.0 ) { + if ( !d || d->isEmpty(1.0) ) { return; } - set_display_area(d, 10); + set_display_area(*d, 10); } /** * Scroll canvas by specific coordinate amount. */ void -SPDesktop::scroll_world (double dx, double dy) +SPDesktop::scroll_world (double dx, double dy, bool is_scrolling) { g_assert(_widget); NR::Rect const viewbox = canvas->getViewbox(); - sp_canvas_scroll_to(canvas, viewbox.min()[NR::X] - dx, viewbox.min()[NR::Y] - dy, FALSE); + sp_canvas_scroll_to(canvas, viewbox.min()[NR::X] - dx, viewbox.min()[NR::Y] - dy, FALSE, is_scrolling); _widget->updateRulers(); _widget->updateScrollbars(expansion(_d2w)); @@ -967,6 +1000,11 @@ SPDesktop::setWindowTransient (void *p, int transient_policy) _widget->setTransient (p, transient_policy); } +void SPDesktop::getToplevel( GtkWidget*& toplevel ) +{ + toplevel = GTK_WIDGET( _widget->getWindow() ); +} + void SPDesktop::presentWindow() { @@ -1051,6 +1089,48 @@ void SPDesktop::disableInteraction() _widget->disableInteraction(); } +void SPDesktop::setWaitingCursor() +{ + GdkCursor *waiting = gdk_cursor_new(GDK_WATCH); + gdk_window_set_cursor(GTK_WIDGET(sp_desktop_canvas(this))->window, waiting); + gdk_cursor_unref(waiting); + waiting_cursor = true; + + // Stupidly broken GDK cannot just set the new cursor right now - it needs some main loop iterations for that + // Since setting waiting_cursor is usually immediately followed by some Real Work, we must run the iterations here + // CAUTION: iterations may redraw, and redraw may be interrupted, so you cannot assume that anything is the same + // after the call to setWaitingCursor as it was before + while( Gtk::Main::events_pending() ) + Gtk::Main::iteration(); +} + +void SPDesktop::clearWaitingCursor() +{ + if (waiting_cursor) + sp_event_context_update_cursor(sp_desktop_event_context(this)); +} + +void SPDesktop::toggleGrid() +{ + if (namedview->grids) { + if(gridgroup) { + grids_visible = !grids_visible; + if (grids_visible) { + sp_canvas_item_show(SP_CANVAS_ITEM(gridgroup)); + } else { + sp_canvas_item_hide(SP_CANVAS_ITEM(gridgroup)); + } + } + } else { + //there is no grid present at the moment. add a rectangular grid and make it visible + Inkscape::XML::Node *repr = SP_OBJECT_REPR(namedview); + Inkscape::CanvasGrid::writeNewGridToRepr(repr, Inkscape::GRID_RECTANGULAR); + grids_visible = true; + sp_canvas_item_show(SP_CANVAS_ITEM(gridgroup)); + } +} + + //---------------------------------------------------------------------- // Callback implementations. The virtual ones are connected by the view. @@ -1086,7 +1166,6 @@ SPDesktop::updateCanvasNow() /** * Associate document with desktop. */ -/// \todo fixme: refactor SPDesktop::init to use setDocument void SPDesktop::setDocument (SPDocument *doc) { @@ -1105,14 +1184,19 @@ SPDesktop::setDocument (SPDocument *doc) _layer_hierarchy->connectChanged(sigc::bind(sigc::ptr_fun(_layer_hierarchy_changed), this)); _layer_hierarchy->setTop(SP_DOCUMENT_ROOT(doc)); + /* setup EventLog */ + event_log = new Inkscape::EventLog(doc); + doc->addUndoObserver(*event_log); + _commit_connection.disconnect(); _commit_connection = doc->connectCommit(sigc::mem_fun(*this, &SPDesktop::updateNow)); /// \todo fixme: This condition exists to make sure the code - /// inside is called only once on initialization. But there + /// inside is NOT called on initialization, only on replacement. But there /// are surely more safe methods to accomplish this. + // TODO since the comment had reversed logic, check the intent of this block of code: if (drawing) { - NRArenaItem *ai; + NRArenaItem *ai = 0; namedview = sp_document_namedview (doc, NULL); _modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this)); @@ -1343,9 +1427,9 @@ _namedview_modified (SPObject *obj, guint flags, SPDesktop *desktop) SP_RGBA32_G_U(nv->pagecolor) + SP_RGBA32_B_U(nv->pagecolor)) >= 384) { // the background color is light or transparent, use black outline - SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = 0xff; + SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = prefs_get_int_attribute("options.wireframecolors", "onlight", 0xff); } else { // use white outline - SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = 0xffffffff; + SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = prefs_get_int_attribute("options.wireframecolors", "ondark", 0xffffffff); } } } @@ -1360,9 +1444,14 @@ _update_snap_distances (SPDesktop *desktop) SPNamedView &nv = *desktop->namedview; - nv.snap_manager.grid.setDistance(sp_convert_distance_full(nv.gridtolerance, + //tell all grid snappers + for ( GSList const *l = nv.grids; l != NULL; l = l->next) { + Inkscape::CanvasGrid *grid = (Inkscape::CanvasGrid*) l->data; + grid->snapper->setDistance(sp_convert_distance_full(nv.gridtolerance, *nv.gridtoleranceunit, px)); + } + nv.snap_manager.guide.setDistance(sp_convert_distance_full(nv.guidetolerance, *nv.guidetoleranceunit, px));