summaryrefslogtreecommitdiffstats
path: root/src/inkscape-window.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/inkscape-window.cpp')
-rw-r--r--src/inkscape-window.cpp194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/inkscape-window.cpp b/src/inkscape-window.cpp
new file mode 100644
index 0000000..6123472
--- /dev/null
+++ b/src/inkscape-window.cpp
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/**
+ * @file
+ * Inkscape - An SVG editor.
+ */
+/*
+ * Authors:
+ * Tavmjong Bah
+ *
+ * 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 "inkscape-window.h"
+#include "inkscape.h" // SP_ACTIVE_DESKTOP
+#include "enums.h" // PREFS_WINDOW_GEOMETRY_NONE
+#include "shortcuts.h"
+#include "inkscape-application.h"
+
+#include "object/sp-namedview.h" // TODO Remove need for this!
+
+#include "ui/drag-and-drop.h" // Move to canvas?
+#include "ui/interface.h" // main menu, sp_ui_close_view()
+
+#include "ui/monitor.h" // get_monitor_geometry_at_point()
+
+#include "ui/desktop/menubar.h"
+
+#include "ui/drag-and-drop.h"
+
+#include "widgets/desktop-widget.h"
+
+InkscapeWindow::InkscapeWindow(SPDocument* document)
+ : _document(document)
+ , _app(nullptr)
+{
+ if (!_document) {
+ std::cerr << "InkscapeWindow::InkscapeWindow: null document!" << std::endl;
+ return;
+ }
+
+ _app = &(ConcreteInkscapeApplication<Gtk::Application>::get_instance());
+ _app->add_window(*this);
+
+ set_resizable(true);
+
+ ink_drag_setup(this);
+
+ // =============== Build interface ===============
+
+ // Main box
+ _mainbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
+ _mainbox->set_name("DesktopMainBox");
+ _mainbox->show();
+ add(*_mainbox);
+
+ // Desktop widget (=> MultiPaned)
+ _desktop_widget = sp_desktop_widget_new(_document);
+ _desktop_widget->window = this;
+ gtk_widget_show(GTK_WIDGET(_desktop_widget));
+ _desktop = _desktop_widget->desktop;
+
+ // Menu bar (must come after desktop widget creation as we need _desktop)
+ // _menubar = build_menubar(_desktop);
+ // _menubar->set_name("MenuBar");
+ // _menubar->show_all();
+
+ // Pallet
+
+ // Status bar
+
+ // _mainbox->pack_start(*_menubar, false, false);
+ gtk_box_pack_start(GTK_BOX(_mainbox->gobj()), GTK_WIDGET(_desktop_widget), true, true, 0); // Can't use Glib::wrap()
+
+ // ================== Callbacks ==================
+ signal_delete_event().connect( sigc::mem_fun(*_desktop, &SPDesktop::onDeleteUI));
+ signal_window_state_event().connect(sigc::mem_fun(*_desktop, &SPDesktop::onWindowStateEvent));
+ signal_focus_in_event().connect( sigc::mem_fun(*_desktop_widget, &SPDesktopWidget::onFocusInEvent));
+
+ // =================== Actions ===================
+
+
+ // ================ Window Options ==============
+ setup_view();
+}
+
+// Change a document, leaving desktop/view the same. (Eventually move all code here.)
+void
+InkscapeWindow::change_document(SPDocument* document)
+{
+ if (!_app) {
+ std::cerr << "Inkscapewindow::change_document: app is nullptr!" << std::endl;
+ return;
+ }
+
+ _document = document;
+ _app->set_active_document(_document);
+
+ setup_view();
+}
+
+// Sets up the window and view according to user preferences and <namedview> of the just loaded document
+void
+InkscapeWindow::setup_view()
+{
+ // Make sure the GdkWindow is fully initialized before resizing/moving
+ // (ensures the monitor it'll be shown on is known)
+ realize();
+
+ // Resize the window to match the document properties
+ sp_namedview_window_from_document(_desktop); // This should probably be a member function here.
+
+ // Must show before setting zoom and view! (crashes otherwise)
+ //
+ // Showing after resizing/moving allows the window manager to correct an invalid size/position of the window
+ // TODO: This does *not* work when called from 'change_document()', i.e. when the window is already visible.
+ // This can result in off-screen windows! We previously worked around this by hiding and re-showing
+ // the window, but a call to hide() causes Inkscape to just exit since the migration to Gtk::Application
+ show();
+
+ sp_namedview_zoom_and_view_from_document(_desktop);
+ sp_namedview_update_layers_from_document(_desktop);
+
+ SPNamedView *nv = _desktop->namedview;
+ if (nv && nv->lockguides) {
+ nv->lockGuides();
+ }
+}
+
+/**
+ * Return true if this is the Cmd-Q shortcut on macOS
+ */
+inline bool is_Cmd_Q(GdkEventKey *event)
+{
+#ifdef GDK_WINDOWING_QUARTZ
+ return (event->keyval == 'q' && event->state == (GDK_MOD2_MASK | GDK_META_MASK));
+#else
+ return false;
+#endif
+}
+
+bool
+InkscapeWindow::on_key_press_event(GdkEventKey* event)
+{
+ // Need to call base class method first or text tool won't work!
+ // Intercept Cmd-Q on macOS to not bypass confirmation dialog
+ bool done = !is_Cmd_Q(event) && Gtk::Window::on_key_press_event(event);
+ if (done) {
+ return true;
+ }
+
+ unsigned shortcut = sp_shortcut_get_for_event(event);
+ return sp_shortcut_invoke (shortcut, _desktop);
+}
+
+bool
+InkscapeWindow::on_focus_in_event(GdkEventFocus* event)
+{
+ if (_app) {
+ _app->set_active_document(_document);
+ _app->set_active_view(_desktop);
+ _app->set_active_selection(_desktop->selection);
+ _app->windows_update(_document);
+ } else {
+ std::cerr << "Inkscapewindow::on_focus_in_event: app is nullptr!" << std::endl;
+ }
+
+ return Gtk::ApplicationWindow::on_focus_in_event(event);
+}
+
+// Called when a window is closed via the 'X' in the window bar.
+bool
+InkscapeWindow::on_delete_event(GdkEventAny* event)
+{
+ if (_app) {
+ _app->destroy_window(this);
+ }
+ return true;
+};
+
+/*
+ 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 :