diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:29:01 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:29:01 +0000 |
commit | 35a96bde514a8897f6f0fcc41c5833bf63df2e2a (patch) | |
tree | 657d15a03cc46bd099fc2c6546a7a4ad43815d9f /src/ui/view | |
parent | Initial commit. (diff) | |
download | inkscape-35a96bde514a8897f6f0fcc41c5833bf63df2e2a.tar.xz inkscape-35a96bde514a8897f6f0fcc41c5833bf63df2e2a.zip |
Adding upstream version 1.0.2.upstream/1.0.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/ui/view')
-rw-r--r-- | src/ui/view/README | 51 | ||||
-rw-r--r-- | src/ui/view/edit-widget-interface.h | 178 | ||||
-rw-r--r-- | src/ui/view/svg-view-widget.cpp | 266 | ||||
-rw-r--r-- | src/ui/view/svg-view-widget.h | 89 | ||||
-rw-r--r-- | src/ui/view/view-widget.cpp | 102 | ||||
-rw-r--r-- | src/ui/view/view-widget.h | 107 | ||||
-rw-r--r-- | src/ui/view/view.cpp | 138 | ||||
-rw-r--r-- | src/ui/view/view.h | 148 |
8 files changed, 1079 insertions, 0 deletions
diff --git a/src/ui/view/README b/src/ui/view/README new file mode 100644 index 0000000..9316f8b --- /dev/null +++ b/src/ui/view/README @@ -0,0 +1,51 @@ + +This directory contains the class Inkscape::UI::View::View and related items. + +View is an abstract base class for all UI document views. Documents +can be displayed by more than one window, each having its own view +(e.g. zoom level, selection, etc.). + +View is the base class for: + +* SPDesktop +* SVGView REMOVED + +SPViewWidget is the base for: + +* SPDocumentWidget +* SPSVGViewWidget REMOVED + +SPSVGViewWidget has been replaced by SVGViewWidget, see below. + + +SPViewWidget: + Contains a GtkEventBox and holds a View. + +SPDesktopWidget: + Contains: + VBox + HBox + GtkGrid + GtkPaned + GtkGrid + SPCanvas + Plus lots of other junk. + + +SVGViewWidget: + Used many places as a convenient way to show an SVG (file dialog, Inkview). + Derived, rather uselessly, from Gtk::Scrollbar. + It no longer is dependent on View (and really doesn't belong here anymore). + + It contains: SPCanvas + +To do: + + +* Convert everything to C++. +* Evaluate moving SPDesktopWidget down the widget stack. + It doesn't use the EventBox of SPViewWidget! + +A DesktopViewWidget should contain: + DesktopView (aka SPDesktop) + SPCanvas diff --git a/src/ui/view/edit-widget-interface.h b/src/ui/view/edit-widget-interface.h new file mode 100644 index 0000000..eb3e33b --- /dev/null +++ b/src/ui/view/edit-widget-interface.h @@ -0,0 +1,178 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Authors: + * Ralf Stephan <ralf@ark.in-berlin.de> + * John Bintz <jcoswell@coswellproductions.org> + * + * Copyright (C) 2006 John Bintz + * Copyright (C) 2005 Ralf Stephan + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_UI_VIEW_EDIT_WIDGET_IFACE_H +#define INKSCAPE_UI_VIEW_EDIT_WIDGET_IFACE_H + +#include "message.h" +#include <2geom/point.h> + +namespace Gtk { + class Toolbar; + class Window; +} + +namespace Glib { +class ustring; +} + +namespace Inkscape { namespace UI { namespace Widget { class Dock; } } } + +namespace Inkscape { +namespace UI { +namespace View { + +/** + * Abstract base class for all EditWidget implementations. + */ +struct EditWidgetInterface +{ + EditWidgetInterface() = default; + virtual ~EditWidgetInterface() = default; + + /// Returns pointer to window UI object as void* + virtual Gtk::Window *getWindow() = 0; + + /// Set the widget's title + virtual void setTitle (gchar const*) = 0; + + /// Show all parts of widget the user wants to see. + virtual void layout() = 0; + + /// Present widget to user + virtual void present() = 0; + + /// Returns geometry of widget + virtual void getGeometry (gint &x, gint &y, gint &w, gint &h) = 0; + + /// Change the widget's size + virtual void setSize (gint w, gint h) = 0; + + /// Move widget to specified position + virtual void setPosition (Geom::Point p) = 0; + + /// Transientize widget + virtual void setTransient (void*, int) = 0; + + /// Return mouse position in widget + virtual Geom::Point getPointer() = 0; + + /// Make widget iconified + virtual void setIconified() = 0; + + /// Make widget maximized on screen + virtual void setMaximized() = 0; + + /// Make widget fill screen and show it if possible. + virtual void setFullscreen() = 0; + + /// Shuts down the desktop object for the view being closed. It checks + /// to see if the document has been edited, and if so prompts the user + /// to save, discard, or cancel. Returns TRUE if the shutdown operation + /// is cancelled or if the save is cancelled or fails, FALSE otherwise. + virtual bool shutdown() = 0; + + /// Destroy and delete widget. + virtual void destroy() = 0; + + + /// Store window position to prefs + virtual void storeDesktopPosition() = 0; + + /// Queue a redraw request with the canvas + virtual void requestCanvasUpdate() = 0; + + /// Force a redraw of the canvas + virtual void requestCanvasUpdateAndWait() = 0; + + /// Enable interaction on this desktop + virtual void enableInteraction() = 0; + + /// Disable interaction on this desktop + virtual void disableInteraction() = 0; + + /// Update the "active desktop" indicator + virtual void activateDesktop() = 0; + + /// Update the "inactive desktop" indicator + virtual void deactivateDesktop() = 0; + + /// Update rulers from current values + virtual void updateRulers() = 0; + + /// Update scrollbars from current values + virtual void updateScrollbars (double scale) = 0; + + /// Toggle rulers on/off and set preference value accordingly + virtual void toggleRulers() = 0; + + /// Toggle scrollbars on/off and set preference value accordingly + virtual void toggleScrollbars() = 0; + + /// Toggle CMS on/off and set preference value accordingly + virtual void toggleColorProfAdjust() = 0; + + /// Is CMS on/off + virtual bool colorProfAdjustEnabled() = 0; + + /// Temporarily block signals and update zoom display + virtual void updateZoom() = 0; + + /// The zoom display will get the keyboard focus. + virtual void letZoomGrabFocus() = 0; + + /// Temporarily block signals and update rotation display + virtual void updateRotation() = 0; + + virtual Gtk::Toolbar* get_toolbar_by_name(const Glib::ustring&) = 0; + + /// In auxiliary toolbox, set focus to widget having specific id + virtual void setToolboxFocusTo (const gchar *) = 0; + + /// In auxiliary toolbox, set value of adjustment with specific id + virtual void setToolboxAdjustmentValue (const gchar *, double) = 0; + + /// In auxiliary toolbox, return true if specific togglebutton is active + virtual bool isToolboxButtonActive (gchar const*) = 0; + + /// Set the coordinate display + virtual void setCoordinateStatus (Geom::Point p) = 0; + + /// Message widget will get no content + virtual void setMessage (Inkscape::MessageType type, gchar const* msg) = 0; + + + /** Show an info dialog with the given message */ + virtual bool showInfoDialog( Glib::ustring const &message ) = 0; + + /// Open yes/no dialog with warning text and confirmation question. + virtual bool warnDialog (Glib::ustring const &) = 0; + + virtual Inkscape::UI::Widget::Dock* getDock () = 0; +}; + +} // namespace View +} // namespace UI +} // namespace Inkscape + +#endif // INKSCAPE_UI_VIEW_EDIT_WIDGET_IFACE_H + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/view/svg-view-widget.cpp b/src/ui/view/svg-view-widget.cpp new file mode 100644 index 0000000..c349b5a --- /dev/null +++ b/src/ui/view/svg-view-widget.cpp @@ -0,0 +1,266 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** + * @file + * A light-weight widget containing an SPCanvas for rendering an SVG. + */ +/* + * Authors: + * Tavmjong Bah <tavmjong@free.fr> + * + * Includes code moved from svg-view.cpp authored by: + * MenTaLGuy + * Ralf Stephan <ralf@ark.in-berlin.de> + * Jon A. Cruz <jon@joncruz.org> + * + * Copyright (C) 2018 Authors + * + * The contents of this file may be used under the GNU General Public License Version 2 or later. + * Read the file 'COPYING' for more information. + * + */ + +#include <iostream> + +#include "svg-view-widget.h" + +#include "document.h" + +#include "2geom/transforms.h" + +#include "display/sp-canvas.h" +#include "display/sp-canvas-group.h" +#include "display/sp-canvas-item.h" +#include "display/canvas-arena.h" + +#include "object/sp-item.h" +#include "object/sp-root.h" + +#include "util/units.h" + +namespace Inkscape { +namespace UI { +namespace View { + +/** + * Callback connected with arena_event. + */ +// This hasn't worked since at least 0.48. It should result in a cursor change over <a></a> links. +// There should be a better way of doing this. See note in canvas-arena.cpp. +static gint arena_handler(SPCanvasArena */*arena*/, Inkscape::DrawingItem *ai, + GdkEvent *event, SVGViewWidget *svgview) +{ + static gdouble x, y; + static gboolean active = FALSE; + SPEvent spev; + + SPItem *spitem = (ai) ? ai->getItem() : nullptr; + + 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 = SPEvent::ACTIVATE; + if ( spitem != nullptr ) + { + spitem->emitEvent (spev); + } + } + } + active = FALSE; + break; + case GDK_MOTION_NOTIFY: + active = FALSE; + break; + case GDK_ENTER_NOTIFY: + spev.type = SPEvent::MOUSEOVER; + spev.view = svgview; + if ( spitem != nullptr ) + { + spitem->emitEvent (spev); + } + break; + case GDK_LEAVE_NOTIFY: + spev.type = SPEvent::MOUSEOUT; + spev.view = svgview; + if ( spitem != nullptr ) + { + spitem->emitEvent (spev); + } + break; + default: + break; + } + + return TRUE; +} + + +/** + * A light-weight widget containing an SPCanvas for rendering an SVG. + * It's derived from a Gtk::ScrolledWindow like the previous C version, but that doesn't seem to be + * too useful. + */ +SVGViewWidget::SVGViewWidget(SPDocument* document) + : _document(nullptr) + , _dkey(0) + , _parent(nullptr) + , _drawing(nullptr) + , _hscale(1.0) + , _vscale(1.0) + , _rescale(false) + , _keepaspect(false) + , _width(0.0) + , _height(0.0) +{ + _canvas = SPCanvas::createAA(); + add(*Glib::wrap(_canvas)); + + SPCanvasItem* item = + sp_canvas_item_new(SP_CANVAS(_canvas)->getRoot(), SP_TYPE_CANVAS_GROUP, nullptr); + _parent = SP_CANVAS_GROUP(item); + + _drawing = sp_canvas_item_new (_parent, SP_TYPE_CANVAS_ARENA, nullptr); + g_signal_connect (G_OBJECT (_drawing), "arena_event", G_CALLBACK (arena_handler), this); + + setDocument(document); + + signal_size_allocate().connect(sigc::mem_fun(*this, &SVGViewWidget::size_allocate)); +} + +SVGViewWidget::~SVGViewWidget() +{ + if (_document) { + _document = nullptr; + } +} + +void +SVGViewWidget::setDocument(SPDocument* document) +{ + // Clear old document + if (_document) { + _document->getRoot()->invoke_hide(_dkey); // Removed from display tree + } + + // Add new document + if (document) { + _document = document; + + Inkscape::DrawingItem *ai = document->getRoot()->invoke_show( + SP_CANVAS_ARENA (_drawing)->drawing, + _dkey, + SP_ITEM_SHOW_DISPLAY); + + if (ai) { + SP_CANVAS_ARENA (_drawing)->drawing.root()->prependChild(ai); + } + + doRescale (); + } +} + +void +SVGViewWidget::setResize(int width, int height) +{ + // Triggers size_allocation which calls SVGViewWidget::size_allocate. + set_size_request(width, height); + queue_resize(); +} + +void +SVGViewWidget::size_allocate(Gtk::Allocation& allocation) +{ + double width = allocation.get_width(); + double height = allocation.get_height(); + + if (width < 0.0 || height < 0.0) { + std::cerr << "SVGViewWidget::size_allocate: negative dimensions!" << std::endl; + return; + } + + _rescale = true; + _keepaspect = true; + _width = width; + _height = height; + + doRescale (); +} + +void +SVGViewWidget::doRescale() +{ + if (!_document) { + std::cerr << "SVGViewWidget::doRescale: No document!" << std::endl; + return; + } + + if (_document->getWidth().value("px") < 1e-9) { + std::cerr << "SVGViewWidget::doRescale: Width too small!" << std::endl; + return; + } + + if (_document->getHeight().value("px") < 1e-9) { + std::cerr << "SVGViewWidget::doRescale: Height too small!" << std::endl; + return; + } + + double x_offset = 0.0; + double y_offset = 0.0; + if (_rescale) { + _hscale = _width / _document->getWidth().value("px"); + _vscale = _height / _document->getHeight().value("px"); + if (_keepaspect) { + if (_hscale > _vscale) { + _hscale = _vscale; + x_offset = (_width - _document->getWidth().value("px") * _vscale)/2.0; + } else { + _vscale = _hscale; + y_offset = (_height - _document->getHeight().value("px") * _hscale)/2.0; + } + } + } + + if (_drawing) { + sp_canvas_item_affine_absolute (_drawing, Geom::Scale(_hscale, _vscale) * Geom::Translate(x_offset, y_offset)); + } +} + +void +SVGViewWidget::mouseover() +{ + GdkDisplay *display = gdk_display_get_default(); + GdkCursor *cursor = gdk_cursor_new_for_display(display, GDK_HAND2); + GdkWindow *window = gtk_widget_get_window (GTK_WIDGET(SP_CANVAS_ITEM(_drawing)->canvas)); + gdk_window_set_cursor(window, cursor); + g_object_unref(cursor); +} + +void +SVGViewWidget::mouseout() +{ + GdkWindow *window = gtk_widget_get_window (GTK_WIDGET(SP_CANVAS_ITEM(_drawing)->canvas)); + gdk_window_set_cursor(window, nullptr); +} + +} // Namespace View +} // Namespace UI +} // Namespace Inkscape + +/* + 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:fileencoding=utf-8 : diff --git a/src/ui/view/svg-view-widget.h b/src/ui/view/svg-view-widget.h new file mode 100644 index 0000000..644c879 --- /dev/null +++ b/src/ui/view/svg-view-widget.h @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** + * @file + * A light-weight widget containing an SPCanvas with for rendering an SVG. + */ +/* + * Authors: + * Tavmjong Bah <tavmjong@free.fr> + * + * Copyright (C) 2018 Authors + * + * The contents of this file may be used under the GNU General Public License Version 2 or later. + * Read the file 'COPYING' for more information. + * + */ + +#ifndef INKSCAPE_UI_SVG_VIEW_WIDGET_VARIATIONS_H +#define INKSCAPE_UI_SVG_VIEW_WIDGET_VARIATIONS_H + + +#include <gtkmm.h> + +class SPDocument; +class SPCanvasGroup; +class SPCanvasItem; + +namespace Inkscape { +namespace UI { +namespace View { + +/** + * A light-weight widget containing an SPCanvas for rendering an SVG. + */ +class SVGViewWidget : public Gtk::ScrolledWindow { + +public: + SVGViewWidget(SPDocument* document); + ~SVGViewWidget() override; + void setDocument( SPDocument* document); + void setResize( int width, int height); + +private: + void size_allocate(Gtk::Allocation& allocation); + + GtkWidget* _canvas; + +// From SVGView --------------------------------- + +public: + SPDocument* _document; + unsigned int _dkey; + SPCanvasGroup *_parent; + SPCanvasItem *_drawing; + double _hscale; ///< horizontal scale + double _vscale; ///< vertical scale + bool _rescale; ///< whether to rescale automatically + bool _keepaspect; + double _width; + double _height; + + /** + * Helper function that sets rescale ratio. + */ + void doRescale(); + + /** + * Change cursor (used for links). + */ + void mouseover(); + void mouseout(); + +}; + +} // Namespace View +} // Namespace UI +} // Namespace Inkscape + +#endif // INKSCAPE_UI_SVG_VIEW_WIDGET + +/* + 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:fileencoding=utf-8 : diff --git a/src/ui/view/view-widget.cpp b/src/ui/view/view-widget.cpp new file mode 100644 index 0000000..ce9745d --- /dev/null +++ b/src/ui/view/view-widget.cpp @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * 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 v2+, read the file 'COPYING' for more information. + */ + +#include "view.h" +#include "view-widget.h" + +//using namespace Inkscape::UI::View; + +// SPViewWidget +static void sp_view_widget_dispose(GObject *object); + +G_DEFINE_TYPE(SPViewWidget, sp_view_widget, GTK_TYPE_EVENT_BOX); + +/** + * Callback to initialize the SPViewWidget vtable. + */ +static void sp_view_widget_class_init(SPViewWidgetClass *vwc) +{ + GObjectClass *object_class = G_OBJECT_CLASS(vwc); + + object_class->dispose = sp_view_widget_dispose; +} + +/** + * Callback to initialize the SPViewWidget. + */ +static void sp_view_widget_init(SPViewWidget *vw) +{ + vw->view = nullptr; +} + +/** + * Callback to disconnect from view and destroy SPViewWidget. + * + * Apparently, this gets only called when a desktop is closed, but then twice! + */ +static void sp_view_widget_dispose(GObject *object) +{ + SPViewWidget *vw = SP_VIEW_WIDGET(object); + + if (vw->view) { + vw->view->close(); + Inkscape::GC::release(vw->view); + vw->view = nullptr; + } + + if (G_OBJECT_CLASS(sp_view_widget_parent_class)->dispose) { + G_OBJECT_CLASS(sp_view_widget_parent_class)->dispose(object); + } + + Inkscape::GC::request_early_collection(); +} + +void sp_view_widget_set_view(SPViewWidget *vw, Inkscape::UI::View::View *view) +{ + g_return_if_fail(vw != nullptr); + g_return_if_fail(SP_IS_VIEW_WIDGET(vw)); + g_return_if_fail(view != nullptr); + + g_return_if_fail(vw->view == nullptr); + + vw->view = view; + Inkscape::GC::anchor(view); + + if (((SPViewWidgetClass *) G_OBJECT_GET_CLASS(vw))->set_view) { + ((SPViewWidgetClass *) G_OBJECT_GET_CLASS(vw))->set_view(vw, view); + } +} + +bool sp_view_widget_shutdown(SPViewWidget *vw) +{ + g_return_val_if_fail(vw != nullptr, TRUE); + g_return_val_if_fail(SP_IS_VIEW_WIDGET(vw), TRUE); + + if (((SPViewWidgetClass *) G_OBJECT_GET_CLASS(vw))->shutdown) { + return ((SPViewWidgetClass *) G_OBJECT_GET_CLASS(vw))->shutdown(vw); + } + + return FALSE; +} + + + +/* + 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 : diff --git a/src/ui/view/view-widget.h b/src/ui/view/view-widget.h new file mode 100644 index 0000000..0296ac6 --- /dev/null +++ b/src/ui/view/view-widget.h @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef INKSCAPE_UI_VIEW_VIEWWIDGET_H +#define INKSCAPE_UI_VIEW_VIEWWIDGET_H + +/* + * 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 v2+, read the file 'COPYING' for more information. + */ + +#include <gtk/gtk.h> + + +namespace Inkscape { +namespace UI { +namespace View { +class View; +} // namespace View +} // namespace UI +} // namespace Inkscape + +class SPViewWidget; +class SPNamedView; + +#define SP_TYPE_VIEW_WIDGET (sp_view_widget_get_type ()) +#define SP_VIEW_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_VIEW_WIDGET, SPViewWidget)) +#define SP_VIEW_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_VIEW_WIDGET, SPViewWidgetClass)) +#define SP_IS_VIEW_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_VIEW_WIDGET)) +#define SP_IS_VIEW_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_VIEW_WIDGET)) +#define SP_VIEW_WIDGET_VIEW(w) (SP_VIEW_WIDGET (w)->view) +#define SP_VIEW_WIDGET_DOCUMENT(w) (SP_VIEW_WIDGET (w)->view ? ((SPViewWidget *) (w))->view->doc : NULL) + +/** + * Registers the SPViewWidget class with Glib and returns its type number. + */ +GType sp_view_widget_get_type(); + +/** + * Connects widget to view's 'resized' signal and calls virtual set_view() + * function. + */ +void sp_view_widget_set_view(SPViewWidget *vw, Inkscape::UI::View::View *view); + +/** + * Allows presenting 'save changes' dialog, FALSE - continue, TRUE - cancel. + * Calls the virtual shutdown() function of the SPViewWidget. + */ +bool sp_view_widget_shutdown(SPViewWidget *vw); + +/** + * SPViewWidget is a GUI widget that contain a single View. It is also + * an abstract base class with little functionality of its own. + */ +class SPViewWidget { + public: + GtkEventBox eventbox; // NOT USED! + + Inkscape::UI::View::View *view; + + // C++ Wrappers + GType getType() const { + return sp_view_widget_get_type(); + } + + void setView(Inkscape::UI::View::View *view) { + sp_view_widget_set_view(this, view); + } + + gboolean shutdown() { + return sp_view_widget_shutdown(this); + } + +// void resized (double x, double y) = 0; +}; + +/** + * The Glib-style vtable for the SPViewWidget class. + */ +class SPViewWidgetClass { + public: + GtkEventBoxClass parent_class; + + /* Virtual method to set/change/remove view */ + void (* set_view) (SPViewWidget *vw, Inkscape::UI::View::View *view); + /// Virtual method about view size change + void (* view_resized) (SPViewWidget *vw, Inkscape::UI::View::View *view, gdouble width, gdouble height); + + gboolean (* shutdown) (SPViewWidget *vw); +}; + +#endif + +/* + 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 : diff --git a/src/ui/view/view.cpp b/src/ui/view/view.cpp new file mode 100644 index 0000000..3b2b7f2 --- /dev/null +++ b/src/ui/view/view.cpp @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Authors: + * Lauris Kaplinski <lauris@kaplinski.com> + * Ralf Stephan <ralf@ark.in-berlin.de> + * Jon A. Cruz <jon@joncruz.org> + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include <2geom/point.h> +#include <memory> +#include "document.h" +#include "view.h" +#include "message-stack.h" +#include "message-context.h" +#include "verbs.h" +#include "inkscape.h" + +namespace Inkscape { +namespace UI { +namespace View { + +static void +_onResized (double x, double y, View* v) +{ + v->onResized (x,y); +} + +static void +_onRedrawRequested (View* v) +{ + v->onRedrawRequested(); +} + +static void +_onStatusMessage (Inkscape::MessageType type, gchar const *message, View* v) +{ + v->onStatusMessage (type, message); +} + +static void +_onDocumentURISet (gchar const* uri, View* v) +{ + v->onDocumentURISet (uri); +} + +static void +_onDocumentResized (double x, double y, View* v) +{ + v->onDocumentResized (x,y); +} + +//-------------------------------------------------------------------- +View::View() +: _doc(nullptr) +{ + _message_stack = std::make_shared<Inkscape::MessageStack>(); + _tips_message_context = std::unique_ptr<Inkscape::MessageContext>(new Inkscape::MessageContext(_message_stack)); + + _resized_connection = _resized_signal.connect (sigc::bind (sigc::ptr_fun (&_onResized), this)); + _redraw_requested_connection = _redraw_requested_signal.connect (sigc::bind (sigc::ptr_fun (&_onRedrawRequested), this)); + + _message_changed_connection = _message_stack->connectChanged (sigc::bind (sigc::ptr_fun (&_onStatusMessage), this)); +} + +View::~View() +{ + _close(); +} + +void View::_close() { + _message_changed_connection.disconnect(); + + _tips_message_context = nullptr; + + _message_stack = nullptr; + + if (_doc) { + _document_uri_set_connection.disconnect(); + _document_resized_connection.disconnect(); + if (INKSCAPE.remove_document(_doc)) { + // this was the last view of this document, so delete it + // delete _doc; Delete now handled in Inkscape::Application + } + _doc = nullptr; + } + + Inkscape::Verb::delete_all_view (this); +} + +void View::emitResized (double width, double height) +{ + _resized_signal.emit (width, height); +} + +void View::requestRedraw() +{ + _redraw_requested_signal.emit(); +} + +void View::setDocument(SPDocument *doc) { + g_return_if_fail(doc != nullptr); + + if (_doc) { + _document_uri_set_connection.disconnect(); + _document_resized_connection.disconnect(); + if (INKSCAPE.remove_document(_doc)) { + // this was the last view of this document, so delete it + // delete _doc; Delete now handled in Inkscape::Application + } + } + + INKSCAPE.add_document(doc); + + _doc = doc; + _document_uri_set_connection = + _doc->connectURISet(sigc::bind(sigc::ptr_fun(&_onDocumentURISet), this)); + _document_resized_connection = + _doc->connectResized(sigc::bind(sigc::ptr_fun(&_onDocumentResized), this)); + _document_uri_set_signal.emit( _doc->getDocumentURI() ); +} + +}}} + +/* + 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 : diff --git a/src/ui/view/view.h b/src/ui/view/view.h new file mode 100644 index 0000000..3acfd2c --- /dev/null +++ b/src/ui/view/view.h @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef INKSCAPE_UI_VIEW_VIEW_H +#define INKSCAPE_UI_VIEW_VIEW_H +/* + * 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 v2+, read the file 'COPYING' for more information. + */ + +#include <gdk/gdk.h> +#include <cstddef> +#include <memory> +#include <sigc++/connection.h> +#include "message.h" +#include "inkgc/gc-managed.h" +#include "gc-finalized.h" +#include "gc-anchored.h" +#include <2geom/forward.h> + +/** + * Iterates until true or returns false. + * When used as signal accumulator, stops emission if one slot returns true. + */ +struct StopOnTrue { + typedef bool result_type; + + template<typename T_iterator> + result_type operator()(T_iterator first, T_iterator last) const{ + for (; first != last; ++first) + if (*first) return true; + return false; + } +}; + +/** + * Iterates until nonzero or returns 0. + * When used as signal accumulator, stops emission if one slot returns nonzero. + */ +struct StopOnNonZero { + typedef int result_type; + + template<typename T_iterator> + result_type operator()(T_iterator first, T_iterator last) const{ + for (; first != last; ++first) + if (*first) return *first; + return 0; + } +}; + +class SPDocument; + +namespace Inkscape { + class MessageContext; + class MessageStack; + namespace UI { + namespace View { + +/** + * View is an abstract base class of all UI document views. This + * includes both the editing window and the SVG preview, but does not + * include the non-UI RGBA buffer-based Inkscape::Drawing nor the XML editor or + * similar views. The View base class has very little functionality of + * its own. + */ +class View : public GC::Managed<>, + public GC::Finalized, + public GC::Anchored +{ +public: + + View(); + + /** + * Deletes and nulls all View message stacks and disconnects it from signals. + */ + ~View() override; + + void close() { _close(); } + + /// Returns a pointer to the view's document. + SPDocument *doc() const + { return _doc; } + /// Returns a pointer to the view's message stack. + std::shared_ptr<Inkscape::MessageStack> messageStack() const + { return _message_stack; } + /// Returns a pointer to the view's tipsMessageContext. + Inkscape::MessageContext *tipsMessageContext() const + { return _tips_message_context.get(); } + + void emitResized(gdouble width, gdouble height); + void requestRedraw(); + + virtual void onResized (double, double) {}; + virtual void onRedrawRequested() {}; + virtual void onStatusMessage (Inkscape::MessageType type, gchar const *message) {}; + virtual void onDocumentURISet (gchar const* uri) {}; + virtual void onDocumentResized (double, double) {}; + virtual bool shutdown() { return false; }; + +protected: + SPDocument *_doc; + std::shared_ptr<Inkscape::MessageStack> _message_stack; + std::unique_ptr<Inkscape::MessageContext> _tips_message_context; + + virtual void _close(); + + /** + * Disconnects the view from the document signals, connects the view + * to a new one, and emits the _document_set_signal on the view. + * + * This is code common to all subclasses and called from their + * setDocument() methods after they are done. + * + * @param doc The new document to connect the view to. + */ + virtual void setDocument(SPDocument *doc); + + sigc::signal<void,double,double> _resized_signal; + sigc::signal<void,gchar const*> _document_uri_set_signal; + sigc::signal<void> _redraw_requested_signal; + +private: + sigc::connection _resized_connection; + sigc::connection _redraw_requested_connection; + sigc::connection _message_changed_connection; // foreign + sigc::connection _document_uri_set_connection; // foreign + sigc::connection _document_resized_connection; // foreign +}; + +}}} + +#endif // INKSCAPE_UI_VIEW_VIEW_H + +/* + 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 : |