desktop.cpp revision e77ce9f12f531d4701b0b99809e0a6d8f92c0085
#define __SP_DESKTOP_C__
/** \file
* Editable view implementation
*
* Authors:
* Lauris Kaplinski <lauris@kaplinski.com>
* MenTaLguY <mental@rydia.net>
* bulia byak <buliabyak@users.sf.net>
* Ralf Stephan <ralf@ark.in-berlin.de>
*
* Copyright (C) 2004 MenTaLguY
* Copyright (C) 1999-2002 Lauris Kaplinski
* Copyright (C) 2000-2001 Ximian, Inc.
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
/** \class SPDesktop
* SPDesktop is a subclass of View, implementing an editable document
* canvas. It is extensively used by many UI controls that need certain
* visual representations of their own.
*
* SPDesktop provides a certain set of SPCanvasItems, serving as GUI
* layers of different control objects. The one containing the whole
* document is the drawing layer. In addition to it, there are grid,
* guide, sketch and control layers. The sketch layer is used for
* temporary drawing objects, before the real objects in document are
* created. The control layer contains editing knots, rubberband and
* similar non-document UI objects.
*
* Each SPDesktop is associated with a SPNamedView node of the document
* tree. Currently, all desktops are created from a single main named
* view, but in the future there may be support for different ones.
* SPNamedView serves as an in-document container for desktop-related
* data, like grid and guideline placement, snapping options and so on.
*
* Associated with each SPDesktop are the two most important editing
* related objects - SPSelection and SPEventContext.
*
* Sodipodi keeps track of the active desktop and invokes notification
* signals whenever it changes. UI elements can use these to update their
* display to the selection of the currently active editing window.
* (Lauris Kaplinski)
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "macros.h"
#include "inkscape-private.h"
#include "desktop.h"
#include "desktop-events.h"
#include "desktop-handles.h"
#include "document.h"
#include "message-stack.h"
#include "selection.h"
#include "select-context.h"
#include "sp-namedview.h"
#include "color.h"
#include "sp-item-group.h"
#include "prefs-utils.h"
#include "object-hierarchy.h"
#include "display/canvas-arena.h"
#include "display/nr-arena.h"
#include "display/gnome-canvas-acetate.h"
#include "display/sodipodi-ctrlrect.h"
#include "display/sp-canvas-util.h"
#include "libnr/nr-matrix-div.h"
#include "libnr/nr-rect-ops.h"
#include "ui/dialog/dialog-manager.h"
#include "message-context.h"
#include "layer-manager.h"
// Callback declarations
static gint _arena_handler (SPCanvasArena *arena, NRArenaItem *ai, GdkEvent *event, SPDesktop *desktop);
/**
* Return new desktop object.
* \pre namedview != NULL.
* \pre canvas != NULL.
*/
{
_widget = 0;
event_context = 0;
layer_manager = 0;
_d2w.set_identity();
_w2d.set_identity();
guides_active = false;
zooms_past = NULL;
zooms_future = NULL;
is_fullscreen = false;
gr_point_num = 0;
gr_fill_or_stroke = true;
_active = false;
}
void
{
_guides_message_context = new Inkscape::MessageContext(const_cast<Inkscape::MessageStack*>(messageStack()));
/* Kill flicker */
/* Setup Dialog Manager */
/* Connect document */
/* Setup Canvas */
/* Setup adminstrative layers */
SP_CANVAS_ARENA (drawing)->arena->delta = prefs_get_double_attribute ("options.cursortolerance", "value", 1.0); // default is 1 px
// Start always in normal mode
/* Push select tool to the bottom of stack */
/** \todo
* FIXME: this is the only call to this. Everything else seems to just
* call "set" instead of "push". Can we assume that there is only one
* context ever?
*/
// display rect and zoom are now handled in sp_desktop_widget_realize()
/* the following sets the page shadow on the canvas
It was originally set to 5, which is really cheesy!
It now is an attribute in the document's namedview. If a value of
0 is used, then the constructor for a shadow is not initialized.
*/
}
/* Connect event for page resize */
dkey,
if (ai) {
}
/* Ugly hack */
activate_guides (true);
/* Ugly hack */
/* Set up notification of rebuilding the document, this allows
for saving object related settings in the document. */
// ?
// sp_active_desktop_set (desktop);
this
)
);
this
)
);
this
)
);
this
)
);
/* setup LayerManager */
// (Setting up after the connections are all in place, as it may use some of them)
}
{
while (event_context) {
}
if (_layer_hierarchy) {
delete _layer_hierarchy;
}
if (_inkscape) {
}
if (drawing) {
}
delete _guides_message_context;
}
//--------------------------------------------------------------------
/* Public methods */
void SPDesktop::setDisplayModeNormal()
{
}
void SPDesktop::setDisplayModeOutline()
{
}
/**
* Returns current root (=bottom) layer.
*/
{
}
/**
* Returns current top layer.
*/
{
}
/**
* Sets the current layer of the desktop.
*
* Make \a object the top layer.
*/
g_return_if_fail( currentRoot() == object || (currentRoot() && currentRoot()->isAncestorOf(object)) );
// printf("Set Layer to ID: %s\n", SP_OBJECT_ID(object));
}
/**
* Return layer that contains \a object.
*/
}
return object;
}
/**
* True if object is a layer.
*/
return ( SP_IS_GROUP(object)
}
/**
* True if desktop viewport fully contains \a item's bbox.
*/
{
}
///
}
/**
* Set activate property of desktop; emit signal if changed.
*/
void
{
if (new_active != _active) {
if (new_active) {
} else {
}
}
}
/**
* Set activate status of current desktop's named view.
*/
void
{
}
/**
* Make desktop switch documents.
*/
void
{
/* unselect everything before switching documents */
}
/**
* Make desktop switch event contexts.
*/
void
{
while (event_context) {
ec = event_context;
}
event_context = ec;
}
/**
* Push event context onto desktop's context stack.
*/
void
{
ref = event_context;
}
event_context = ec;
}
/**
* Sets the coordinate status to a given point
*/
void
}
/**
* \see sp_document_item_from_list_at_point_bottom()
*/
SPItem *
{
}
/**
* \see sp_document_item_at_point()
*/
SPItem *
{
}
/**
* \see sp_document_group_at_point()
*/
SPItem *
{
}
/**
* \brief Returns the mouse point in document coordinates; if mouse is
* outside the canvas, returns the center of canvas viewpoint
*/
{
{
return p;
} else {
}
}
/**
* Put current zoom data in history list.
*/
void
{
{
}
}
/**
* Set viewbox.
*/
void
{
// save the zoom
if (log) {
// if we do a logged zoom, our zoom-forward list is invalidated, so delete it
zooms_future = NULL;
}
double newscale;
} else {
}
/* Set zoom factors */
}
/* Calculate top left corner */
/* Scroll */
_widget->updateRulers();
_widget->updateZoom();
}
{
}
/**
* Return viewbox dimensions.
*/
{
}
/**
* Revert back to previous zoom if possible.
*/
void
{
if (zooms_past == NULL) {
return;
}
// push current zoom into forward zooms list
// restore previous zoom
0, false);
// remove the just-added zoom from the past zooms list
}
/**
* Set zoom to next in list.
*/
void
{
if (zooms_future == NULL) {
return;
}
// push current zoom into past zooms list
// restore next zoom
0, false);
// remove the just-used zoom from the zooms_future list
}
/**
* Zoom to point with absolute zoom factor.
*/
void
{
// maximum or minimum zoom reached, but there's no exact equality because of rounding errors;
// this check prevents "sliding" when trying to zoom in at maximum zoom;
/// \todo someone please fix calculations properly and remove this hack
if (fabs(expansion(_d2w) - zoom) < 0.0001*zoom && (fabs(SP_DESKTOP_ZOOM_MAX - zoom) < 0.01 || fabs(SP_DESKTOP_ZOOM_MIN - zoom) < 0.000001))
return;
0.0);
}
/**
* Zoom to center with absolute zoom factor.
*/
void
{
}
/**
* Zoom to point with relative zoom factor.
*/
void
{
}
}
}
}
}
/**
* Zoom to center with relative zoom factor.
*/
void
{
}
/**
* Set display area to origin and current document dimensions.
*/
void
{
return;
}
set_display_area(d, 10);
}
/**
* Set display area to current document width.
*/
void
{
return;
}
set_display_area(d, 10);
}
/**
* Zoom to selection.
*/
void
{
return;
}
set_display_area(d, 10);
}
/**
* Tell widget to let zoom widget grab keyboard focus.
*/
void
{
}
/**
* Zoom to whole drawing.
*/
void
{
/* Note that the second condition here indicates that
** there are no items in the drawing.
*/
return;
}
set_display_area(d, 10);
}
/**
* Scroll canvas by specific coordinate amount.
*/
void
{
_widget->updateRulers();
}
bool
{
gdouble autoscrolldistance = (gdouble) prefs_get_int_attribute_limited ("options.autoscrolldistance", "value", 0, -1000, 10000);
// autoscrolldistance is in screen pixels, but the display area is in document units
else
else
if (autoscrollspeed == 0)
autoscrollspeed = prefs_get_double_attribute_limited ("options.autoscrollspeed", "value", 1, 0, 10);
if (autoscrollspeed != 0)
return true;
}
return false;
}
void
{
_widget->setFullscreen();
}
void
{
_widget->getGeometry (x, y, w, h);
}
void
{
_widget->setPosition (p);
}
void
{
}
void
{
}
void
{
}
bool
{
}
void
{
_widget->toggleRulers();
}
void
{
}
void
{
}
void
{
}
bool
{
}
void
{
}
void
{
}
bool
{
}
void
{
inkscape_subselection_changed (this);
}
void
{
}
//----------------------------------------------------------------------
// Callback implementations. The virtual ones are connected by the view.
void
SPDesktop::onPositionSet (double x, double y)
{
}
void
{
// Nothing called here
}
/**
* Redraw callback; queues Gtk redraw; connected by View.
*/
void
{
if (main) {
}
}
/**
* Associate document with desktop.
*/
/// \todo fixme: refactor SPDesktop::init to use setDocument
void
{
}
if (_layer_hierarchy) {
delete _layer_hierarchy;
}
/// \todo fixme: This condition exists to make sure the code
/// inside is called only once on initialization. But there
/// are surely more safe methods to accomplish this.
if (drawing) {
dkey,
if (ai) {
}
/* Ugly hack */
activate_guides (true);
/* Ugly hack */
}
}
void
{
if (_widget) {
}
}
void
{
}
/**
* Resized callback.
*/
void
{
}
void
{
}
void
{
}
void
{
}
static void
{
/** \todo
* only change the layer for single selections, or what?
* This seems reasonable -- for multiple selections there can be many
* different layers involved.
*/
if (item) {
}
}
}
/**
* Calls event handler of current event context.
* \param arena Unused
* \todo fixme
*/
static gint
{
if (ai) {
} else {
}
}
static void
}
/// Callback
static void
}
/// Callback
static void
{
}
/// Called when document is starting to be rebuilt.
static void
{
// printf("Desktop, starting reconstruction\n");
/*
GSList const * selection_objs = desktop->selection->list();
for (; selection_objs != NULL; selection_objs = selection_objs->next) {
}
*/
// printf("Desktop, starting reconstruction end\n");
}
/// Called when document rebuild is finished.
static void
{
// printf("Desktop, finishing reconstruction\n");
return;
SPObject * newLayer = SP_OBJECT_DOCUMENT(desktop->namedview)->getObjectById(desktop->_reconstruction_old_layer_id);
// printf("Desktop, finishing reconstruction end\n");
return;
}
/**
* Namedview_modified callback.
*/
static void
{
if (flags & SP_OBJECT_MODIFIED_FLAG) {
/* Recalculate snap distances */
/* FIXME: why is the desktop getting involved in setting up something
** that is entirely to do with the namedview?
*/
} else {
}
if (nv->showborder) {
// show
// set color and shadow
if (nv->pageshadow) {
}
// place in the z-order stack
} else {
}
} else {
if (nv->pageshadow) {
}
}
} else {
}
// the background color is light or transparent, use black outline
} else { // use white outline
}
}
}
/**
* Callback to reset snapper's distances.
*/
static void
{
px));
px));
px));
}
{
return _w2d;
}
{
return p * _w2d;
}
{
return p * _d2w;
}
{
return _doc2dt;
}
{
return p * _doc2dt;
}
{
return p / _doc2dt;
}
/**
* Pop event context from desktop's context stack. Never used.
*/
// void
// SPDesktop::pop_event_context (unsigned int key)
// {
// SPEventContext *ec = NULL;
//
// if (event_context && event_context->key == key) {
// g_return_if_fail (event_context);
// g_return_if_fail (event_context->next);
// ec = event_context;
// sp_event_context_deactivate (ec);
// event_context = ec->next;
// sp_event_context_activate (event_context);
// _event_context_changed_signal.emit (this, ec);
// }
//
// SPEventContext *ref = event_context;
// while (ref && ref->next && ref->next->key != key)
// ref = ref->next;
//
// if (ref && ref->next) {
// ec = ref->next;
// ref->next = ec->next;
// }
//
// if (ec) {
// sp_event_context_finish (ec);
// g_object_unref (G_OBJECT (ec));
// }
// }
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :