diff --git a/src/desktop.cpp b/src/desktop.cpp
index 668d46b31cfbca8505ba3302202ed1c85df40517..6314621c14e146805075c28fae13c2d916a893df 100644 (file)
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
* John Bintz <jcoswell@coswellproductions.org>
* Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
*
+ * Copyright (C) 2007 Jon A. Cruz
* Copyright (C) 2006-2007 Johan Engelen
* Copyright (C) 2006 John Bintz
* Copyright (C) 2004 MenTaLguY
#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; }}
* \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 ),
+ window_state(0),
+ interaction_disabled_counter( 0 ),
+ waiting_cursor( false ),
+ perspectives (NULL),
+ 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;
- waiting_cursor = false;
- gr_item = NULL;
- gr_point_type = 0;
- gr_point_i = 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<Inkscape::MessageStack*>(messageStack()));
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);
_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;
/* setup LayerManager */
// (Setting up after the connections are all in place, as it may use some of them)
layer_manager = new Inkscape::LayerManager( this );
+
+ grids_visible = true;
+
+ /* Create initial perspective, append it to the list of existing perspectives
+ and make it the current perspective */
+ Box3D::Perspective3D *initial_persp = new Box3D::Perspective3D (
+ // VP in x-direction
+ Box3D::VanishingPoint( NR::Point(-50.0, 600.0),
+ NR::Point( -1.0, 0.0), Box3D::VP_FINITE),
+ // VP in y-direction
+ Box3D::VanishingPoint( NR::Point(500.0,1000.0),
+ NR::Point( 0.0, 1.0), Box3D::VP_INFINITE),
+ // VP in z-direction
+ Box3D::VanishingPoint( NR::Point(700.0, 600.0),
+ NR::Point(sqrt(3.0),1.0), Box3D::VP_FINITE));
+ this->add_perspective (initial_persp);
+ Box3D::Perspective3D::current_perspective = (Box3D::Perspective3D *) perspectives->data;
}
g_list_free (zooms_past);
g_list_free (zooms_future);
+
+ for (GSList *p = this->perspectives; p != NULL; p = p->next) {
+ delete ((Box3D::Perspective3D *) p->data);
+ }
+ g_slist_free (perspectives);
}
SPDesktop::~SPDesktop() {}
set_display_area(a.min()[NR::X], a.min()[NR::Y], a.max()[NR::X], a.max()[NR::Y], b, log);
}
+/**
+ * Add a perspective to the desktop if it doesn't exist yet
+ */
+void
+SPDesktop::add_perspective (Box3D::Perspective3D * const persp)
+{
+ // FIXME: Should we handle the case that the perspectives have equal VPs but are not identical?
+ if (persp == NULL || g_slist_find (this->perspectives, persp)) return;
+ this->perspectives = g_slist_prepend (this->perspectives, persp);
+ persp->desktop = this;
+}
+
+void SPDesktop::remove_perspective (Box3D::Perspective3D * const persp)
+{
+ if (persp == NULL) return;
+
+ if (!g_slist_find (this->perspectives, persp)) {
+ g_warning ("Could not find perspective in current desktop. Not removed.\n");
+ return;
+ }
+
+ this->perspectives = g_slist_remove (this->perspectives, persp);
+}
+
/**
* Return viewbox dimensions.
*/
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;
}
{
NR::Maybe<NR::Rect> const d = selection->bounds();
- if ( !d || d->dimensions()[NR::X] < 0.1 || d->dimensions()[NR::Y] < 0.1) {
+ if ( !d || d->isEmpty(0.1) ) {
return;
}
/* Note that the second condition here indicates that
** there are no items in the drawing.
*/
- if ( !d || d->dimensions()[NR::X] < 1.0 || d->dimensions()[NR::Y] < 1.0 ) {
+ if ( !d || d->isEmpty(1.0) ) {
return;
}
return false;
}
+bool
+SPDesktop::is_iconified()
+{
+ return 0!=(window_state & GDK_WINDOW_STATE_ICONIFIED);
+}
+
+void
+SPDesktop::iconify()
+{
+ _widget->setIconified();
+}
+
+bool
+SPDesktop::is_maximized()
+{
+ return 0!=(window_state & GDK_WINDOW_STATE_MAXIMIZED);
+}
+
+void
+SPDesktop::maximize()
+{
+ _widget->setMaximized();
+}
+
+bool
+SPDesktop::is_fullscreen()
+{
+ return 0!=(window_state & GDK_WINDOW_STATE_FULLSCREEN);
+}
+
void
SPDesktop::fullscreen()
{
_widget->setTransient (p, transient_policy);
}
+Gtk::Window*
+SPDesktop::getToplevel( )
+{
+ return _widget->getWindow();
+}
+
void
SPDesktop::presentWindow()
{
return _widget->shutdown();
}
+bool SPDesktop::onDeleteUI (GdkEventAny*)
+{
+ if(shutdown()) return true;
+ destroyWidget();
+ return false;
+}
+
+/**
+ * onWindowStateEvent
+ *
+ * Called when the window changes its maximize/fullscreen/iconify/pinned state.
+ * Since GTK doesn't have a way to query this state information directly, we
+ * record it for the desktop here, and also possibly trigger a layout.
+ */
+bool
+SPDesktop::onWindowStateEvent (GdkEventWindowState* event)
+{
+ // Record the desktop window's state
+ window_state = event->new_window_state;
+
+ // Layout may differ depending on full-screen mode or not
+ GdkWindowState changed = event->changed_mask;
+ if (changed & (GDK_WINDOW_STATE_FULLSCREEN|GDK_WINDOW_STATE_MAXIMIZED)) {
+ layoutWidget();
+ }
+
+ return false;
+}
+
void
SPDesktop::setToolboxFocusTo (gchar const *label)
{
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, sp_desktop_document(this), Inkscape::GRID_RECTANGULAR);
+ grids_visible = true;
+ sp_canvas_item_show(SP_CANVAS_ITEM(gridgroup));
+ }
+}
+
+
//----------------------------------------------------------------------
// Callback implementations. The virtual ones are connected by the view.
/**
* Associate document with desktop.
*/
-/// \todo fixme: refactor SPDesktop::init to use setDocument
void
SPDesktop::setDocument (SPDocument *doc)
{
_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));
SPNamedView &nv = *desktop->namedview;
- nv.snap_manager.grid.setDistance(sp_convert_distance_full(nv.gridtolerance,
- *nv.gridtoleranceunit,
- px));
- nv.snap_manager.axonomgrid.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));