diff options
| author | MenTaLguY <mental@rydia.net> | 2006-01-16 02:36:01 +0000 |
|---|---|---|
| committer | mental <mental@users.sourceforge.net> | 2006-01-16 02:36:01 +0000 |
| commit | 179fa413b047bede6e32109e2ce82437c5fb8d34 (patch) | |
| tree | a5a6ac2c1708bd02288fbd8edb2ff500ff2e0916 /src/svg-view.cpp | |
| download | inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.tar.gz inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.zip | |
moving trunk for module inkscape
(bzr r1)
Diffstat (limited to 'src/svg-view.cpp')
| -rw-r--r-- | src/svg-view.cpp | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/src/svg-view.cpp b/src/svg-view.cpp new file mode 100644 index 000000000..6d408e79c --- /dev/null +++ b/src/svg-view.cpp @@ -0,0 +1,230 @@ +#define __SP_SVG_VIEW_C__ + +/** \file + * Functions and callbacks for generic SVG view and widget + * + * Authors: + * Lauris Kaplinski <lauris@kaplinski.com> + * Ralf Stephan <ralf@ark.in-berlin.de> + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/canvas-arena.h" +#include "display/display-forward.h" +#include "document.h" +#include "sp-item.h" +#include "svg-view.h" + + +/** + * Constructs new SPSVGView object and returns pointer to it. + */ +SPSVGView::SPSVGView (SPCanvasGroup *parent) +{ + _hscale = 1.0; + _vscale = 1.0; + _rescale = FALSE; + _keepaspect = FALSE; + _width = 0.0; + _height = 0.0; + + _dkey = 0; + _drawing = 0; + _parent = parent; +} + +SPSVGView::~SPSVGView() +{ + if (doc() && _drawing) + { + sp_item_invoke_hide (SP_ITEM (sp_document_root (doc())), _dkey); + _drawing = NULL; + } +} + +/** + * Rescales SPSVGView to given proportions. + */ +void +SPSVGView::setScale (gdouble hscale, gdouble vscale) +{ + if (!_rescale && ((hscale != _hscale) || (vscale != _vscale))) { + _hscale = hscale; + _vscale = vscale; + doRescale (true); + } +} + +/** + * Rescales SPSVGView and keeps aspect ratio. + */ +void +SPSVGView::setRescale +(bool rescale, bool keepaspect, gdouble width, gdouble height) +{ + g_return_if_fail (!rescale || (width >= 0.0)); + g_return_if_fail (!rescale || (height >= 0.0)); + + _rescale = rescale; + _keepaspect = keepaspect; + _width = width; + _height = height; + + doRescale (true); +} + +/** + * Helper function that sets rescale ratio and emits resize event. + */ +void +SPSVGView::doRescale (bool event) +{ + if (!doc()) return; + if (sp_document_width (doc()) < 1e-9) return; + if (sp_document_height (doc()) < 1e-9) return; + + if (_rescale) { + _hscale = _width / sp_document_width (doc()); + _vscale = _height / sp_document_height (doc()); + if (_keepaspect) { + if (_hscale > _vscale) { + _hscale = _vscale; + } else { + _vscale = _hscale; + } + } + } + + if (_drawing) { + sp_canvas_item_affine_absolute (_drawing, NR::Matrix(NR::scale(_hscale, _vscale))); + } + + if (event) { + emitResized (sp_document_width (doc()) * _hscale, + sp_document_height (doc()) * _vscale); + } +} + +void +SPSVGView::mouseover() +{ + GdkCursor *cursor = gdk_cursor_new(GDK_HAND2); + gdk_window_set_cursor(GTK_WIDGET(SP_CANVAS_ITEM(_drawing)->canvas)->window, cursor); + gdk_cursor_destroy(cursor); +} + +void +SPSVGView::mouseout() +{ + gdk_window_set_cursor(GTK_WIDGET(SP_CANVAS_ITEM(_drawing)->canvas)->window, NULL); +} + +//---------------------------------------------------------------- +/** + * Callback connected with arena_event. + */ +/// \todo fixme. +static gint +arena_handler (SPCanvasArena *arena, NRArenaItem *ai, GdkEvent *event, SPSVGView *svgview) +{ + static gdouble x, y; + static gboolean active = FALSE; + SPEvent spev; + + SPItem *spitem = (ai) ? (SPItem*)NR_ARENA_ITEM_GET_DATA (ai) : NULL; + + switch (event->type) { + case GDK_BUTTON_PRESS: + if (event->button.button == 1) { + active = TRUE; + x = event->button.x; + y = event->button.y; + } + break; + case GDK_BUTTON_RELEASE: + if (event->button.button == 1) { + if (active && (event->button.x == x) && (event->button.y == y)) { + spev.type = SP_EVENT_ACTIVATE; + sp_item_event (spitem, &spev); + } + } + active = FALSE; + break; + case GDK_MOTION_NOTIFY: + active = FALSE; + break; + case GDK_ENTER_NOTIFY: + spev.type = SP_EVENT_MOUSEOVER; + spev.data = svgview; + sp_item_event (spitem, &spev); + break; + case GDK_LEAVE_NOTIFY: + spev.type = SP_EVENT_MOUSEOUT; + spev.data = svgview; + sp_item_event (spitem, &spev); + break; + default: + break; + } + + return TRUE; +} + +/** + * Callback connected with set_document signal. + */ +void +SPSVGView::setDocument (SPDocument *document) +{ + if (doc()) { + sp_item_invoke_hide (SP_ITEM (sp_document_root (doc())), _dkey); + } + + if (!_drawing) { + _drawing = sp_canvas_item_new (_parent, SP_TYPE_CANVAS_ARENA, NULL); + g_signal_connect (G_OBJECT (_drawing), "arena_event", G_CALLBACK (arena_handler), this); + } + + if (document) { + NRArenaItem *ai = sp_item_invoke_show ( + SP_ITEM (sp_document_root (document)), + SP_CANVAS_ARENA (_drawing)->arena, + _dkey, + SP_ITEM_SHOW_DISPLAY); + + if (ai) { + nr_arena_item_add_child (SP_CANVAS_ARENA (_drawing)->root, ai, NULL); + nr_arena_item_unref (ai); + } + + doRescale (!_rescale); + } + + View::setDocument (document); +} + +/** + * Callback connected with document_resized signal. + */ +void +SPSVGView::onDocumentResized (gdouble width, gdouble height) +{ + setScale (width, height); + doRescale (!_rescale); +} + + +/* + 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 : |
