[shotwell/wip/gtk4] Fix initial display of image
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [shotwell/wip/gtk4] Fix initial display of image
- Date: Sun, 17 Apr 2022 12:30:44 +0000 (UTC)
commit 9b3827f91a8ee43b81eeebc2ac688bf694f09da5
Author: Jens Georg <mail jensge org>
Date: Fri Apr 15 20:54:57 2022 +0200
Fix initial display of image
src/AppWindow.vala | 392 ----------------------------------------------
src/FullscreenWindow.vala | 275 ++++++++++++++++++++++++++++++++
src/Page.vala | 51 ++----
src/PageWindow.vala | 126 +++++++++++++++
src/PhotoPage.vala | 20 ---
src/SinglePhotoPage.vala | 2 +
src/meson.build | 2 +
7 files changed, 418 insertions(+), 450 deletions(-)
---
diff --git a/src/AppWindow.vala b/src/AppWindow.vala
index 697aedb6..eef1ade5 100644
--- a/src/AppWindow.vala
+++ b/src/AppWindow.vala
@@ -4,398 +4,6 @@
* See the COPYING file in this distribution.
*/
-public class FullscreenWindow : PageWindow {
- public const int TOOLBAR_INVOCATION_MSEC = 250;
- public const int TOOLBAR_DISMISSAL_SEC = 2;
- public const int TOOLBAR_CHECK_DISMISSAL_MSEC = 500;
-
- private Gtk.Overlay overlay = new Gtk.Overlay();
- private Gtk.Box toolbar = null;
- private Gtk.Button close_button = new Gtk.Button();
- private Gtk.ToggleButton pin_button = new Gtk.ToggleButton();
- private bool is_toolbar_shown = false;
- private bool waiting_for_invoke = false;
- private time_t left_toolbar_time = 0;
- private bool switched_to = false;
- private bool is_toolbar_dismissal_enabled;
-
- private const GLib.ActionEntry[] entries = {
- { "LeaveFullscreen", on_close }
- };
-
- public FullscreenWindow(Page page) {
- base ();
-
- set_current_page(page);
-
- this.add_action_entries (entries, this);
- const string[] accels = { "F11", null };
- Application.set_accels_for_action ("win.LeaveFullscreen", accels);
-
- //set_screen(AppWindow.get_instance().get_screen());
-
- // Needed so fullscreen will occur on correct monitor in multi-monitor setups
- Gdk.Rectangle monitor = get_monitor_geometry();
- //move(monitor.x, monitor.y);
-
- //set_border_width(0);
-
- // restore pin state
- is_toolbar_dismissal_enabled = Config.Facade.get_instance().get_pin_toolbar_state();
-
- pin_button.set_icon_name("view-pin-symbolic");
- pin_button.set_label(_("Pin Toolbar"));
- pin_button.set_tooltip_text(_("Pin the toolbar open"));
- pin_button.set_active(!is_toolbar_dismissal_enabled);
- pin_button.clicked.connect(update_toolbar_dismissal);
-
- close_button.set_icon_name("view-restore-symbolic");
- close_button.set_tooltip_text(_("Leave fullscreen"));
- close_button.set_action_name ("win.LeaveFullscreen");
-
- toolbar = page.get_toolbar();
- //toolbar.set_show_arrow(false);
- toolbar.valign = Gtk.Align.END;
- toolbar.halign = Gtk.Align.CENTER;
- //toolbar.expand = false;
- toolbar.opacity = Resources.TRANSIENT_WINDOW_OPACITY;
-
- if (page is SlideshowPage) {
- // slideshow page doesn't own toolbar to hide it, subscribe to signal instead
- ((SlideshowPage) page).hide_toolbar.connect(hide_toolbar);
- } else {
- // only non-slideshow pages should have pin button
- toolbar.append(pin_button);
- }
-
- page.set_cursor_hide_time(TOOLBAR_DISMISSAL_SEC * 1000);
- page.start_cursor_hiding();
-
- toolbar.append(close_button);
-
- set_child(overlay);
- overlay.set_child(page);
- overlay.add_overlay (toolbar);
-
- // call to set_default_size() saves one repaint caused by changing
- // size from default to full screen. In slideshow mode, this change
- // also causes pixbuf cache updates, so it really saves some work.
- set_default_size(monitor.width, monitor.height);
-
- // need to create a Gdk.Window to set masks
- fullscreen();
- show();
-
- // capture motion events to show the toolbar
- //add_events(Gdk.EventMask.POINTER_MOTION_MASK);
-
- // If toolbar is enabled in "normal" ui OR was pinned in
- // fullscreen, start off with toolbar invoked, as a clue for the
- // user. Otherwise leave hidden unless activated by mouse over
- if (Config.Facade.get_instance().get_display_toolbar() ||
- !is_toolbar_dismissal_enabled) {
- invoke_toolbar();
- } else {
- hide_toolbar();
- }
-
- // Toolbar steals keyboard focus from page, put it back again
- page.grab_focus ();
-
- // Do not show menubar in fullscreen
- set_show_menubar (false);
- }
-
- public void disable_toolbar_dismissal() {
- is_toolbar_dismissal_enabled = false;
- }
-
- public void update_toolbar_dismissal() {
- is_toolbar_dismissal_enabled = !pin_button.get_active();
- }
-
- private Gdk.Rectangle get_monitor_geometry() {
- #if 0
- var monitor = get_display().get_monitor_at_window(AppWindow.get_instance().get_window());
- return monitor.get_geometry();
- #endif
-
- return Gdk.Rectangle();
- }
-
- #if 0
- public override bool configure_event(Gdk.EventConfigure event) {
- bool result = base.configure_event(event);
-
- if (!switched_to) {
- get_current_page().switched_to();
- switched_to = true;
- }
-
- return result;
- }
-
- public override bool key_press_event(Gdk.EventKey event) {
- // check for an escape/abort
- if (Gdk.keyval_name(event.keyval) == "Escape") {
- on_close();
-
- return true;
- }
-
- // propagate to this (fullscreen) window respecting "stop propagation" result...
- if (base.key_press_event != null && base.key_press_event(event))
- return true;
-
- // ... then propagate to the underlying window hidden behind this fullscreen one
- return AppWindow.get_instance().key_press_event(event);
- }
- #endif
-
- private void on_close() {
- Config.Facade.get_instance().set_pin_toolbar_state(is_toolbar_dismissal_enabled);
- hide_toolbar();
-
- AppWindow.get_instance().end_fullscreen();
- }
-
- public new void close() {
- on_close();
- }
-
- public override void dispose() {
- Page? page = get_current_page();
- clear_current_page();
-
- if (page != null) {
- page.stop_cursor_hiding();
- page.switching_from();
- }
-
- base.dispose();
- }
-
- public override bool close_request() {
- on_close();
- AppWindow.get_instance().destroy();
-
- return true;
- }
-
- #if 0
- public override bool motion_notify_event(Gdk.EventMotion event) {
- if (!is_toolbar_shown) {
- // if pointer is in toolbar height range without the mouse down (i.e. in the middle of
- // an edit operation) and it stays there the necessary amount of time, invoke the
- // toolbar
- if (!waiting_for_invoke && is_pointer_in_toolbar()) {
- Timeout.add(TOOLBAR_INVOCATION_MSEC, on_check_toolbar_invocation);
- waiting_for_invoke = true;
- }
- }
-
- return (base.motion_notify_event != null) ? base.motion_notify_event(event) : false;
- }
- #endif
-
- private bool is_pointer_in_toolbar() {
- var seat = get_display().get_default_seat();
- if (seat == null) {
- debug("No seat for display");
-
- return false;
- }
-
- #if 0
- int py;
- seat.get_pointer().get_position(null, null, out py);
-
- int wy;
- toolbar.get_window().get_geometry(null, out wy, null, null);
-
- return (py >= wy);
- #endif
- return false;
- }
-
- private bool on_check_toolbar_invocation() {
- waiting_for_invoke = false;
-
- if (is_toolbar_shown)
- return false;
-
- if (!is_pointer_in_toolbar())
- return false;
-
- invoke_toolbar();
-
- return false;
- }
-
- private void invoke_toolbar() {
- toolbar.show();
-
- is_toolbar_shown = true;
-
- Timeout.add(TOOLBAR_CHECK_DISMISSAL_MSEC, on_check_toolbar_dismissal);
- }
-
- private bool on_check_toolbar_dismissal() {
- if (!is_toolbar_shown)
- return false;
-
- // if dismissal is disabled, keep open but keep checking
- if ((!is_toolbar_dismissal_enabled))
- return true;
-
- // if the pointer is in toolbar range, keep it alive, but keep checking
- if (is_pointer_in_toolbar()) {
- left_toolbar_time = 0;
-
- return true;
- }
-
- // if this is the first time noticed, start the timer and keep checking
- if (left_toolbar_time == 0) {
- left_toolbar_time = time_t();
-
- return true;
- }
-
- // see if enough time has elapsed
- time_t now = time_t();
- assert(now >= left_toolbar_time);
-
- if (now - left_toolbar_time < TOOLBAR_DISMISSAL_SEC)
- return true;
-
- hide_toolbar();
-
- return false;
- }
-
- private void hide_toolbar() {
- toolbar.hide();
- is_toolbar_shown = false;
- }
-}
-
-// PageWindow is a Gtk.Window with essential functions for hosting a Page. There may be more than
-// one PageWindow in the system, and closing one does not imply exiting the application.
-//
-// PageWindow offers support for hosting a single Page; multiple Pages must be handled by the
-// subclass. A subclass should set current_page to the user-visible Page for it to receive
-// various notifications. It is the responsibility of the subclass to notify Pages when they're
-// switched to and from, and other aspects of the Page interface.
-public abstract class PageWindow : Gtk.ApplicationWindow {
- private Page current_page = null;
- private int busy_counter = 0;
-
- protected virtual void switched_pages(Page? old_page, Page? new_page) {
- }
-
- protected PageWindow() {
- Object (application: Application.get_instance().get_system_app ());
-
- // the current page needs to know when modifier keys are pressed
- #if 0
- add_events(Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.KEY_RELEASE_MASK
- | Gdk.EventMask.STRUCTURE_MASK);
- #endif
- set_show_menubar (true);
-
- }
-
- public Page? get_current_page() {
- return current_page;
- }
-
- public virtual void set_current_page(Page page) {
- if (current_page != null)
- current_page.clear_container();
-
- Page? old_page = current_page;
- current_page = page;
- current_page.set_container(this);
-
- switched_pages(old_page, page);
- }
-
- public virtual void clear_current_page() {
- if (current_page != null)
- current_page.clear_container();
-
- Page? old_page = current_page;
- current_page = null;
-
- switched_pages(old_page, null);
- }
-
- #if 0
- public override bool key_press_event(Gdk.EventKey event) {
- if (get_focus() is Gtk.Entry && get_focus().key_press_event(event))
- return true;
-
- if (current_page != null && current_page.notify_app_key_pressed(event))
- return true;
-
- return (base.key_press_event != null) ? base.key_press_event(event) : false;
- }
-
- public override bool key_release_event(Gdk.EventKey event) {
- if (get_focus() is Gtk.Entry && get_focus().key_release_event(event))
- return true;
-
- if (current_page != null && current_page.notify_app_key_released(event))
- return true;
-
- return (base.key_release_event != null) ? base.key_release_event(event) : false;
- }
-
- public override bool focus_in_event(Gdk.EventFocus event) {
- if (current_page != null && current_page.notify_app_focus_in(event))
- return true;
-
- return (base.focus_in_event != null) ? base.focus_in_event(event) : false;
- }
-
- public override bool focus_out_event(Gdk.EventFocus event) {
- if (current_page != null && current_page.notify_app_focus_out(event))
- return true;
-
- return (base.focus_out_event != null) ? base.focus_out_event(event) : false;
- }
-
- public override bool configure_event(Gdk.EventConfigure event) {
- if (current_page != null) {
- if (current_page.notify_configure_event(event))
- return true;
- }
-
- return (base.configure_event != null) ? base.configure_event(event) : false;
- }
- #endif
-
- public void set_busy_cursor() {
- if (busy_counter++ > 0)
- return;
-
- set_cursor (new Gdk.Cursor.from_name ("wait", null));
- }
-
- public void set_normal_cursor() {
- if (busy_counter <= 0) {
- busy_counter = 0;
- return;
- } else if (--busy_counter > 0) {
- return;
- }
-
- set_cursor (new Gdk.Cursor.from_name ("default", null));
- }
-
-}
-
// AppWindow is the parent window for most windows in Shotwell (FullscreenWindow is the exception).
// There are multiple types of AppWindows (LibraryWindow, DirectWindow) for different tasks, but only
// one AppWindow may exist per process. Thus, if the user closes an AppWindow, the program exits.
diff --git a/src/FullscreenWindow.vala b/src/FullscreenWindow.vala
new file mode 100644
index 00000000..31870113
--- /dev/null
+++ b/src/FullscreenWindow.vala
@@ -0,0 +1,275 @@
+public class FullscreenWindow : PageWindow {
+ public const int TOOLBAR_INVOCATION_MSEC = 250;
+ public const int TOOLBAR_DISMISSAL_SEC = 2;
+ public const int TOOLBAR_CHECK_DISMISSAL_MSEC = 500;
+
+ private Gtk.Overlay overlay = new Gtk.Overlay();
+ private Gtk.Box toolbar = null;
+ private Gtk.Button close_button = new Gtk.Button();
+ private Gtk.ToggleButton pin_button = new Gtk.ToggleButton();
+ private bool is_toolbar_shown = false;
+ private bool waiting_for_invoke = false;
+ private time_t left_toolbar_time = 0;
+ private bool switched_to = false;
+ private bool is_toolbar_dismissal_enabled;
+
+ private const GLib.ActionEntry[] entries = {
+ { "LeaveFullscreen", on_close }
+ };
+
+ public FullscreenWindow(Page page) {
+ base ();
+
+ set_current_page(page);
+
+ this.add_action_entries (entries, this);
+ const string[] accels = { "F11", null };
+ Application.set_accels_for_action ("win.LeaveFullscreen", accels);
+
+ //set_screen(AppWindow.get_instance().get_screen());
+
+ // Needed so fullscreen will occur on correct monitor in multi-monitor setups
+ Gdk.Rectangle monitor = get_monitor_geometry();
+ //move(monitor.x, monitor.y);
+
+ //set_border_width(0);
+
+ // restore pin state
+ is_toolbar_dismissal_enabled = Config.Facade.get_instance().get_pin_toolbar_state();
+
+ pin_button.set_icon_name("view-pin-symbolic");
+ pin_button.set_label(_("Pin Toolbar"));
+ pin_button.set_tooltip_text(_("Pin the toolbar open"));
+ pin_button.set_active(!is_toolbar_dismissal_enabled);
+ pin_button.clicked.connect(update_toolbar_dismissal);
+
+ close_button.set_icon_name("view-restore-symbolic");
+ close_button.set_tooltip_text(_("Leave fullscreen"));
+ close_button.set_action_name ("win.LeaveFullscreen");
+
+ toolbar = page.get_toolbar();
+ //toolbar.set_show_arrow(false);
+ toolbar.valign = Gtk.Align.END;
+ toolbar.halign = Gtk.Align.CENTER;
+ //toolbar.expand = false;
+ toolbar.opacity = Resources.TRANSIENT_WINDOW_OPACITY;
+
+ if (page is SlideshowPage) {
+ // slideshow page doesn't own toolbar to hide it, subscribe to signal instead
+ ((SlideshowPage) page).hide_toolbar.connect(hide_toolbar);
+ } else {
+ // only non-slideshow pages should have pin button
+ toolbar.append(pin_button);
+ }
+
+ page.set_cursor_hide_time(TOOLBAR_DISMISSAL_SEC * 1000);
+ page.start_cursor_hiding();
+
+ toolbar.append(close_button);
+
+ set_child(overlay);
+ overlay.set_child(page);
+ overlay.add_overlay (toolbar);
+
+ // call to set_default_size() saves one repaint caused by changing
+ // size from default to full screen. In slideshow mode, this change
+ // also causes pixbuf cache updates, so it really saves some work.
+ set_default_size(monitor.width, monitor.height);
+
+ // need to create a Gdk.Window to set masks
+ fullscreen();
+ show();
+
+ // capture motion events to show the toolbar
+ //add_events(Gdk.EventMask.POINTER_MOTION_MASK);
+
+ // If toolbar is enabled in "normal" ui OR was pinned in
+ // fullscreen, start off with toolbar invoked, as a clue for the
+ // user. Otherwise leave hidden unless activated by mouse over
+ if (Config.Facade.get_instance().get_display_toolbar() ||
+ !is_toolbar_dismissal_enabled) {
+ invoke_toolbar();
+ } else {
+ hide_toolbar();
+ }
+
+ // Toolbar steals keyboard focus from page, put it back again
+ page.grab_focus ();
+
+ // Do not show menubar in fullscreen
+ set_show_menubar (false);
+ }
+
+ public void disable_toolbar_dismissal() {
+ is_toolbar_dismissal_enabled = false;
+ }
+
+ public void update_toolbar_dismissal() {
+ is_toolbar_dismissal_enabled = !pin_button.get_active();
+ }
+
+ private Gdk.Rectangle get_monitor_geometry() {
+ #if 0
+ var monitor = get_display().get_monitor_at_window(AppWindow.get_instance().get_window());
+ return monitor.get_geometry();
+ #endif
+
+ return Gdk.Rectangle();
+ }
+
+ public override bool configure_event(int width, int height) {
+ bool result = base.configure_event(width, height);
+
+ if (!switched_to) {
+ get_current_page().switched_to();
+ switched_to = true;
+ }
+
+ return result;
+ }
+
+ #if 0
+ public override bool key_press_event(Gdk.EventKey event) {
+ // check for an escape/abort
+ if (Gdk.keyval_name(event.keyval) == "Escape") {
+ on_close();
+
+ return true;
+ }
+
+ // propagate to this (fullscreen) window respecting "stop propagation" result...
+ if (base.key_press_event != null && base.key_press_event(event))
+ return true;
+
+ // ... then propagate to the underlying window hidden behind this fullscreen one
+ return AppWindow.get_instance().key_press_event(event);
+ }
+ #endif
+
+ private void on_close() {
+ Config.Facade.get_instance().set_pin_toolbar_state(is_toolbar_dismissal_enabled);
+ hide_toolbar();
+
+ AppWindow.get_instance().end_fullscreen();
+ }
+
+ public new void close() {
+ on_close();
+ }
+
+ public override void dispose() {
+ Page? page = get_current_page();
+ clear_current_page();
+
+ if (page != null) {
+ page.stop_cursor_hiding();
+ page.switching_from();
+ }
+
+ base.dispose();
+ }
+
+ public override bool close_request() {
+ on_close();
+ AppWindow.get_instance().destroy();
+
+ return true;
+ }
+
+ #if 0
+ public override bool motion_notify_event(Gdk.EventMotion event) {
+ if (!is_toolbar_shown) {
+ // if pointer is in toolbar height range without the mouse down (i.e. in the middle of
+ // an edit operation) and it stays there the necessary amount of time, invoke the
+ // toolbar
+ if (!waiting_for_invoke && is_pointer_in_toolbar()) {
+ Timeout.add(TOOLBAR_INVOCATION_MSEC, on_check_toolbar_invocation);
+ waiting_for_invoke = true;
+ }
+ }
+
+ return (base.motion_notify_event != null) ? base.motion_notify_event(event) : false;
+ }
+ #endif
+
+ private bool is_pointer_in_toolbar() {
+ var seat = get_display().get_default_seat();
+ if (seat == null) {
+ debug("No seat for display");
+
+ return false;
+ }
+
+ #if 0
+ int py;
+ seat.get_pointer().get_position(null, null, out py);
+
+ int wy;
+ toolbar.get_window().get_geometry(null, out wy, null, null);
+
+ return (py >= wy);
+ #endif
+ return false;
+ }
+
+ private bool on_check_toolbar_invocation() {
+ waiting_for_invoke = false;
+
+ if (is_toolbar_shown)
+ return false;
+
+ if (!is_pointer_in_toolbar())
+ return false;
+
+ invoke_toolbar();
+
+ return false;
+ }
+
+ private void invoke_toolbar() {
+ toolbar.show();
+
+ is_toolbar_shown = true;
+
+ Timeout.add(TOOLBAR_CHECK_DISMISSAL_MSEC, on_check_toolbar_dismissal);
+ }
+
+ private bool on_check_toolbar_dismissal() {
+ if (!is_toolbar_shown)
+ return false;
+
+ // if dismissal is disabled, keep open but keep checking
+ if ((!is_toolbar_dismissal_enabled))
+ return true;
+
+ // if the pointer is in toolbar range, keep it alive, but keep checking
+ if (is_pointer_in_toolbar()) {
+ left_toolbar_time = 0;
+
+ return true;
+ }
+
+ // if this is the first time noticed, start the timer and keep checking
+ if (left_toolbar_time == 0) {
+ left_toolbar_time = time_t();
+
+ return true;
+ }
+
+ // see if enough time has elapsed
+ time_t now = time_t();
+ assert(now >= left_toolbar_time);
+
+ if (now - left_toolbar_time < TOOLBAR_DISMISSAL_SEC)
+ return true;
+
+ hide_toolbar();
+
+ return false;
+ }
+
+ private void hide_toolbar() {
+ toolbar.hide();
+ is_toolbar_shown = false;
+ }
+}
diff --git a/src/Page.vala b/src/Page.vala
index cef3c56f..73184b35 100644
--- a/src/Page.vala
+++ b/src/Page.vala
@@ -971,16 +971,7 @@ public abstract class Page : Gtk.Box {
public bool notify_app_focus_out(Gdk.EventFocus event) {
return false;
}
-
- protected virtual void on_move(Gdk.Rectangle rect) {
- }
-
- protected virtual void on_move_start(Gdk.Rectangle rect) {
- }
-
- protected virtual void on_move_finished(Gdk.Rectangle rect) {
- }
- #endif
+ #endif
protected virtual void on_resize(Gdk.Rectangle rect) {
}
@@ -991,26 +982,19 @@ public abstract class Page : Gtk.Box {
protected virtual void on_resize_finished(Gdk.Rectangle rect) {
}
- #if 0
-
- protected virtual bool on_configure(Gdk.EventConfigure event, Gdk.Rectangle rect) {
+ protected virtual bool on_configure(Gdk.Rectangle rect) {
return false;
}
-
- public bool notify_configure_event(Gdk.EventConfigure event) {
+
+ public bool notify_configure_event(int width, int height) {
Gdk.Rectangle rect = Gdk.Rectangle();
- rect.x = event.x;
- rect.y = event.y;
- rect.width = event.width;
- rect.height = event.height;
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = width;
+ rect.height = height;
// special case events, to report when a configure first starts (and appears to end)
- if (last_configure_ms == 0) {
- if (last_position.x != rect.x || last_position.y != rect.y) {
- on_move_start(rect);
- report_move_finished = true;
- }
-
+ if (last_configure_ms == 0) {
if (last_position.width != rect.width || last_position.height != rect.height) {
on_resize_start(rect);
report_resize_finished = true;
@@ -1020,20 +1004,16 @@ public abstract class Page : Gtk.Box {
// wait time before it's noticed
Timeout.add(CONSIDER_CONFIGURE_HALTED_MSEC / 8, check_configure_halted);
}
-
- if (last_position.x != rect.x || last_position.y != rect.y)
- on_move(rect);
-
+
if (last_position.width != rect.width || last_position.height != rect.height)
on_resize(rect);
last_position = rect;
last_configure_ms = now_ms();
- return on_configure(event, rect);
+ return on_configure(rect);
}
- #endif
-
+
private bool check_configure_halted() {
if (is_destroyed)
return false;
@@ -1043,12 +1023,7 @@ public abstract class Page : Gtk.Box {
Gtk.Allocation allocation;
get_allocation(out allocation);
-
- #if 0
- if (report_move_finished)
- on_move_finished((Gdk.Rectangle) allocation);
- #endif
-
+
if (report_resize_finished)
on_resize_finished((Gdk.Rectangle) allocation);
diff --git a/src/PageWindow.vala b/src/PageWindow.vala
new file mode 100644
index 00000000..e0fa56a1
--- /dev/null
+++ b/src/PageWindow.vala
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+//
+// PageWindow is a Gtk.Window with essential functions for hosting a Page. There may be more than
+// one PageWindow in the system, and closing one does not imply exiting the application.
+//
+// PageWindow offers support for hosting a single Page; multiple Pages must be handled by the
+// subclass. A subclass should set current_page to the user-visible Page for it to receive
+// various notifications. It is the responsibility of the subclass to notify Pages when they're
+// switched to and from, and other aspects of the Page interface.
+public abstract class PageWindow : Gtk.ApplicationWindow {
+ private Page current_page = null;
+ private int busy_counter = 0;
+
+ protected virtual void switched_pages(Page? old_page, Page? new_page) {
+ }
+
+ protected PageWindow() {
+ Object (application: Application.get_instance().get_system_app ());
+
+ // the current page needs to know when modifier keys are pressed
+ #if 0
+ add_events(Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.KEY_RELEASE_MASK
+ | Gdk.EventMask.STRUCTURE_MASK);
+ #endif
+ set_show_menubar (true);
+
+ notify["maximized"].connect(synthesize_configure_event);
+ notify["default-width"].connect(synthesize_configure_event);
+ notify["default-height"].connect(synthesize_configure_event);
+ notify["fullscreened"].connect(synthesize_configure_event);
+ }
+
+ private void synthesize_configure_event() {
+ int width = get_surface().get_width();
+ int height = get_surface().get_height();
+ configure_event(width, height);
+ }
+
+ public virtual bool configure_event(int width, int height) {
+ if (current_page != null) {
+ if (current_page.notify_configure_event(width, height))
+ return true;
+ }
+
+ return false;
+ }
+
+ public Page? get_current_page() {
+ return current_page;
+ }
+
+ public virtual void set_current_page(Page page) {
+ if (current_page != null)
+ current_page.clear_container();
+
+ Page? old_page = current_page;
+ current_page = page;
+ current_page.set_container(this);
+
+ switched_pages(old_page, page);
+ }
+
+ public virtual void clear_current_page() {
+ if (current_page != null)
+ current_page.clear_container();
+
+ Page? old_page = current_page;
+ current_page = null;
+
+ switched_pages(old_page, null);
+ }
+
+ #if 0
+ public override bool key_press_event(Gdk.EventKey event) {
+ if (get_focus() is Gtk.Entry && get_focus().key_press_event(event))
+ return true;
+
+ if (current_page != null && current_page.notify_app_key_pressed(event))
+ return true;
+
+ return (base.key_press_event != null) ? base.key_press_event(event) : false;
+ }
+
+ public override bool key_release_event(Gdk.EventKey event) {
+ if (get_focus() is Gtk.Entry && get_focus().key_release_event(event))
+ return true;
+
+ if (current_page != null && current_page.notify_app_key_released(event))
+ return true;
+
+ return (base.key_release_event != null) ? base.key_release_event(event) : false;
+ }
+
+ public override bool focus_in_event(Gdk.EventFocus event) {
+ if (current_page != null && current_page.notify_app_focus_in(event))
+ return true;
+
+ return (base.focus_in_event != null) ? base.focus_in_event(event) : false;
+ }
+
+ public override bool focus_out_event(Gdk.EventFocus event) {
+ if (current_page != null && current_page.notify_app_focus_out(event))
+ return true;
+
+ return (base.focus_out_event != null) ? base.focus_out_event(event) : false;
+ }
+ #endif
+
+ public void set_busy_cursor() {
+ if (busy_counter++ > 0)
+ return;
+
+ set_cursor (new Gdk.Cursor.from_name ("wait", null));
+ }
+
+ public void set_normal_cursor() {
+ if (busy_counter <= 0) {
+ busy_counter = 0;
+ return;
+ } else if (--busy_counter > 0) {
+ return;
+ }
+
+ set_cursor (new Gdk.Cursor.from_name ("default", null));
+ }
+}
diff --git a/src/PhotoPage.vala b/src/PhotoPage.vala
index 0cd04ae5..38d13e26 100644
--- a/src/PhotoPage.vala
+++ b/src/PhotoPage.vala
@@ -1728,26 +1728,6 @@ public abstract class EditingHostPage : SinglePhotoPage {
}
#if 0
- private void track_tool_window() {
- // if editing tool window is present and the user hasn't touched it, it moves with the window
- if (current_tool != null) {
- EditingTools.EditingToolWindow tool_window = current_tool.get_tool_window();
- if (tool_window != null && !tool_window.has_user_moved())
- place_tool_window();
- }
- }
-
- protected override void on_move(Gdk.Rectangle rect) {
- track_tool_window();
-
- base.on_move(rect);
- }
-
- protected override void on_move_finished(Gdk.Rectangle rect) {
- last_locations.clear();
-
- base.on_move_finished(rect);
- }
private bool on_keyboard_pan_event(Gdk.EventKey event) {
ZoomState current_zoom_state = get_zoom_state();
diff --git a/src/SinglePhotoPage.vala b/src/SinglePhotoPage.vala
index 05872f23..dc40fe5b 100644
--- a/src/SinglePhotoPage.vala
+++ b/src/SinglePhotoPage.vala
@@ -55,6 +55,7 @@ public abstract class SinglePhotoPage : Page {
viewport.notify["default-height"].connect(on_viewport_resize);
viewport.notify["maximized"].connect(on_viewport_resize);
+ canvas.resize.connect(on_viewport_resize);
canvas.set_draw_func(on_canvas_exposed);
set_event_source(canvas);
Config.Facade.get_instance().colors_changed.connect(on_colors_changed);
@@ -287,6 +288,7 @@ public abstract class SinglePhotoPage : Page {
}
private void on_viewport_resize() {
+ print("Viewport resized!");
// do fast repaints while resizing
internal_repaint(true, null);
}
diff --git a/src/meson.build b/src/meson.build
index bac1d984..6f50a098 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -165,6 +165,8 @@ executable(
'import-roll/ImportRollEntry.vala',
'main.vala',
'AppWindow.vala',
+ 'FullscreenWindow.vala',
+ 'PageWindow.vala',
'CollectionPage.vala',
'NaturalCollate.vala',
'Thumbnail.vala',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]