[shotwell/wip/gtk4: 35/88] Fix zoomed panning and context menus
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [shotwell/wip/gtk4: 35/88] Fix zoomed panning and context menus
- Date: Mon, 30 May 2022 17:34:43 +0000 (UTC)
commit e4e8049adc86c27697f972f7fc86479a2102f3ad
Author: Jens Georg <mail jensge org>
Date: Sun Apr 10 00:17:47 2022 +0200
Fix zoomed panning and context menus
src/CheckerboardPage.vala | 22 ++++-----
src/MediaPage.vala | 10 ++--
src/Page.vala | 99 ++++++++++++++------------------------
src/PhotoPage.vala | 104 ++++++++++++++++++++++------------------
src/SinglePhotoPage.vala | 10 +---
src/direct/DirectPhotoPage.vala | 15 ++----
src/sidebar/Tree.vala | 4 +-
src/tags/TagsBranch.vala | 16 +------
src/util/ui.vala | 17 +++++++
9 files changed, 131 insertions(+), 166 deletions(-)
---
diff --git a/src/CheckerboardPage.vala b/src/CheckerboardPage.vala
index a1750580..2bb3e5f9 100644
--- a/src/CheckerboardPage.vala
+++ b/src/CheckerboardPage.vala
@@ -89,9 +89,7 @@ public abstract class CheckerboardPage : Page {
private Gtk.PopoverMenu item_context_menu;
public virtual Gtk.PopoverMenu? get_item_context_menu() {
if (item_context_menu == null) {
- var model = this.builder.get_object (item_context_menu_path)
- as GLib.MenuModel;
- item_context_menu = new Gtk.PopoverMenu.from_model (model);
+ item_context_menu = get_popover_menu_from_builder (this.builder, item_context_menu_path, this);
}
return item_context_menu;
@@ -103,9 +101,7 @@ public abstract class CheckerboardPage : Page {
return null;
if (page_context_menu == null) {
- var model = this.builder.get_object (page_context_menu_path)
- as GLib.MenuModel;
- page_context_menu = new Gtk.PopoverMenu.from_model (model);
+ page_context_menu = get_popover_menu_from_builder (this.builder, page_context_menu_path, this);
}
return page_context_menu;
@@ -473,17 +469,16 @@ public abstract class CheckerboardPage : Page {
return true;
}
-#if 0
- protected override bool on_right_click(Gdk.EventButton event) {
+ protected override bool on_right_click(Gtk.EventController event, int press, double x, double y) {
// only interested in single-clicks for now
- if (event.type != Gdk.EventType.BUTTON_PRESS)
+ if (press != 1)
return false;
// get what's right-clicked upon
- CheckerboardItem item = get_item_at_pixel(event.x, event.y);
+ CheckerboardItem item = get_item_at_pixel(x, y);
if (item != null) {
// mask out the modifiers we're interested in
- switch (event.state & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK)) {
+ switch (event.get_current_event_state() & (Gdk.ModifierType.CONTROL_MASK |
Gdk.ModifierType.SHIFT_MASK)) {
case Gdk.ModifierType.CONTROL_MASK:
// chosen item is toggled
Marker marker = get_view().mark(item);
@@ -514,10 +509,9 @@ public abstract class CheckerboardPage : Page {
get_view().unselect_all();
}
- Gtk.Menu context_menu = get_context_menu();
- return popup_context_menu(context_menu, event);
+ Gtk.PopoverMenu context_menu = get_context_menu();
+ return popup_context_menu(context_menu, x, y);
}
- #endif
protected virtual bool on_mouse_over(CheckerboardItem? item, int x, int y, Gdk.ModifierType mask) {
if (item != null)
diff --git a/src/MediaPage.vala b/src/MediaPage.vala
index 37e1c792..04c65acb 100644
--- a/src/MediaPage.vala
+++ b/src/MediaPage.vala
@@ -379,9 +379,8 @@ public abstract class MediaPage : CheckerboardPage {
return new ZoomSliderAssembly();
}
-#if 0
- protected override bool on_mousewheel_up(Gdk.EventScroll event) {
- if ((event.state & Gdk.ModifierType.CONTROL_MASK) != 0) {
+ protected override bool on_mousewheel_up(Gtk.EventControllerScroll event) {
+ if ((event.get_current_event_state() & Gdk.ModifierType.CONTROL_MASK) != 0) {
increase_zoom_level();
return true;
} else {
@@ -389,15 +388,14 @@ public abstract class MediaPage : CheckerboardPage {
}
}
- protected override bool on_mousewheel_down(Gdk.EventScroll event) {
- if ((event.state & Gdk.ModifierType.CONTROL_MASK) != 0) {
+ protected override bool on_mousewheel_down(Gtk.EventControllerScroll event) {
+ if ((event.get_current_event_state() & Gdk.ModifierType.CONTROL_MASK) != 0) {
decrease_zoom_level();
return true;
} else {
return base.on_mousewheel_down(event);
}
}
- #endif
private void on_send_to() {
DesktopIntegration.send_to((Gee.Collection<MediaSource>) get_view().get_selected_sources());
diff --git a/src/Page.vala b/src/Page.vala
index 5919629e..348c6291 100644
--- a/src/Page.vala
+++ b/src/Page.vala
@@ -90,6 +90,7 @@ public abstract class Page : Gtk.Box {
// Event controllers
private Gtk.GestureClick clicks;
private Gtk.EventControllerMotion motion;
+ private Gtk.EventControllerScroll scroll;
protected Page(string page_name) {
Object (orientation: Gtk.Orientation.HORIZONTAL);
@@ -185,6 +186,8 @@ public abstract class Page : Gtk.Box {
clicks.set_name ("CheckerboardPage click source");
clicks.set_button (0); // Listen to all buttons
clicks.set_exclusive (true); // TODO: Need to be true or false?
+ clicks.pressed.connect (on_button_pressed_internal);
+ clicks.released.connect (on_button_released_internal);
event_source.add_controller (clicks);
motion = new Gtk.EventControllerMotion ();
@@ -193,8 +196,10 @@ public abstract class Page : Gtk.Box {
motion.leave.connect(on_leave_notify_event);
event_source.add_controller (motion);
- clicks.pressed.connect (on_button_pressed_internal);
- clicks.released.connect (on_button_released_internal);
+ scroll = new Gtk.EventControllerScroll(Gtk.EventControllerScrollFlags.BOTH_AXES
+ | Gtk.EventControllerScrollFlags.DISCRETE);
+ scroll.scroll.connect(on_mousewheel_internal);
+ event_source.add_controller(scroll);
#if 0
// interested in mouse button and motion events on the event source
@@ -202,11 +207,6 @@ public abstract class Page : Gtk.Box {
| Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.POINTER_MOTION_HINT_MASK
| Gdk.EventMask.BUTTON_MOTION_MASK | Gdk.EventMask.LEAVE_NOTIFY_MASK
| Gdk.EventMask.SCROLL_MASK | Gdk.EventMask.SMOOTH_SCROLL_MASK);
- event_source.button_press_event.connect(on_button_pressed_internal);
- event_source.button_release_event.connect(on_button_released_internal);
- event_source.motion_notify_event.connect(on_motion_internal);
- event_source.leave_notify_event.connect(on_leave_notify_event);
- event_source.scroll_event.connect(on_mousewheel_internal);
event_source.realize.connect(on_event_source_realize);
#endif
}
@@ -219,16 +219,13 @@ public abstract class Page : Gtk.Box {
clicks = null;
event_source.remove_controller (motion);
motion = null;
+ event_source.remove_controller (scroll);
+ scroll = null;
#if 0
- event_source.button_press_event.disconnect(on_button_pressed_internal);
- event_source.button_release_event.disconnect(on_button_released_internal);
- event_source.motion_notify_event.disconnect(on_motion_internal);
- event_source.leave_notify_event.disconnect(on_leave_notify_event);
- event_source.scroll_event.disconnect(on_mousewheel_internal);
- event_source = null;
#endif
+ event_source = null;
}
public Gtk.Widget? get_event_source() {
@@ -937,16 +934,19 @@ public abstract class Page : Gtk.Box {
protected virtual void on_move_finished(Gdk.Rectangle rect) {
}
+ #endif
protected virtual void on_resize(Gdk.Rectangle rect) {
}
protected virtual void on_resize_start(Gdk.Rectangle rect) {
}
-
+
protected virtual void on_resize_finished(Gdk.Rectangle rect) {
}
-
+
+ #if 0
+
protected virtual bool on_configure(Gdk.EventConfigure event, Gdk.Rectangle rect) {
return false;
}
@@ -1001,10 +1001,10 @@ public abstract class Page : Gtk.Box {
#if 0
if (report_move_finished)
on_move_finished((Gdk.Rectangle) allocation);
+ #endif
if (report_resize_finished)
on_resize_finished((Gdk.Rectangle) allocation);
- #endif
last_configure_ms = 0;
report_move_finished = false;
@@ -1028,87 +1028,58 @@ public abstract class Page : Gtk.Box {
// todo: stop propagation?
}
- #if 0
- private bool on_mousewheel_internal(Gdk.EventScroll event) {
- switch (event.direction) {
- case Gdk.ScrollDirection.UP:
- return on_mousewheel_up(event);
-
- case Gdk.ScrollDirection.DOWN:
- return on_mousewheel_down(event);
-
- case Gdk.ScrollDirection.LEFT:
- return on_mousewheel_left(event);
-
- case Gdk.ScrollDirection.RIGHT:
- return on_mousewheel_right(event);
-
- case Gdk.ScrollDirection.SMOOTH:
- {
- double dx, dy;
- event.get_scroll_deltas(out dx, out dy);
-
- if (dy <= -1.0)
- return on_mousewheel_up(event);
- else if (dy >= 1.0)
- return on_mousewheel_down(event);
- else if (dx <= -1.0)
- return on_mousewheel_left(event);
- else if (dx >= 1.0)
- return on_mousewheel_right(event);
- else
- return true;
- }
-
- default:
- return false;
- }
+ private bool on_mousewheel_internal(Gtk.EventControllerScroll event, double dx, double dy) {
+ if (dy <= -1.0)
+ return on_mousewheel_up(event);
+ else if (dy >= 1.0)
+ return on_mousewheel_down(event);
+ else if (dx <= -1.0)
+ return on_mousewheel_left(event);
+ else if (dx >= 1.0)
+ return on_mousewheel_right(event);
+ else
+ return false;
}
- protected virtual bool on_mousewheel_up(Gdk.EventScroll event) {
+ protected virtual bool on_mousewheel_up(Gtk.EventControllerScroll event) {
return false;
}
- protected virtual bool on_mousewheel_down(Gdk.EventScroll event) {
+ protected virtual bool on_mousewheel_down(Gtk.EventControllerScroll event) {
return false;
}
- protected virtual bool on_mousewheel_left(Gdk.EventScroll event) {
+ protected virtual bool on_mousewheel_left(Gtk.EventControllerScroll event) {
return false;
}
- protected virtual bool on_mousewheel_right(Gdk.EventScroll event) {
+ protected virtual bool on_mousewheel_right(Gtk.EventControllerScroll event) {
return false;
}
- #endif
protected virtual bool on_context_keypress() {
return false;
}
- #if 0
- protected virtual bool on_context_buttonpress(Gdk.EventButton event) {
+ protected virtual bool on_context_buttonpress(Gtk.EventController event, double x, double y) {
return false;
}
- #endif
protected virtual bool on_context_invoked() {
return true;
}
-#if 0
- protected bool popup_context_menu(Gtk.Menu? context_menu,
- Gdk.EventButton? event = null) {
+ protected bool popup_context_menu(Gtk.PopoverMenu? context_menu, double x, double y) {
if (context_menu == null || !on_context_invoked())
return false;
- context_menu.popup_at_pointer(event);
+ context_menu.set_pointing_to ({(int)x, (int)y, 1, 1});
+ context_menu.popup();
return true;
}
- #endif
#if 0
diff --git a/src/PhotoPage.vala b/src/PhotoPage.vala
index a18340e6..b9046b41 100644
--- a/src/PhotoPage.vala
+++ b/src/PhotoPage.vala
@@ -608,11 +608,13 @@ public abstract class EditingHostPage : SinglePhotoPage {
}
#endif
-# if 0
- private Gdk.Point get_cursor_wrt_viewport(Gdk.EventScroll event) {
+ private Gdk.Point get_cursor_wrt_viewport(Gtk.EventControllerScroll event) {
Gdk.Point cursor_wrt_canvas = {0};
- cursor_wrt_canvas.x = (int) event.x;
- cursor_wrt_canvas.y = (int) event.y;
+ double x;
+ double y;
+ event.get_current_event().get_position(out x, out y);
+ cursor_wrt_canvas.x = (int) x;
+ cursor_wrt_canvas.y = (int) y;
Gdk.Rectangle viewport_wrt_canvas = get_zoom_state().get_viewing_rectangle_wrt_screen();
Gdk.Point result = {0};
@@ -624,7 +626,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
return result;
}
- private Gdk.Point get_cursor_wrt_viewport_center(Gdk.EventScroll event) {
+ private Gdk.Point get_cursor_wrt_viewport_center(Gtk.EventControllerScroll event) {
Gdk.Point cursor_wrt_viewport = get_cursor_wrt_viewport(event);
Gdk.Rectangle viewport_wrt_canvas = get_zoom_state().get_viewing_rectangle_wrt_screen();
@@ -635,7 +637,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
return subtract_points(cursor_wrt_viewport, viewport_center);
}
- private Gdk.Point get_iso_pixel_under_cursor(Gdk.EventScroll event) {
+ private Gdk.Point get_iso_pixel_under_cursor(Gtk.EventControllerScroll event) {
Gdk.Point viewport_center_iso = scale_point(get_zoom_state().get_viewport_center(),
1.0 / get_zoom_state().get_zoom_factor());
@@ -644,7 +646,6 @@ public abstract class EditingHostPage : SinglePhotoPage {
return add_points(viewport_center_iso, cursor_wrt_center_iso);
}
- #endif
private double snap_interpolation_factor(double interp) {
if (interp < 0.03)
@@ -659,8 +660,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
return snap_interpolation_factor(get_zoom_state().get_interpolation_factor() + adjustment);
}
-#if 0
- private void zoom_about_event_cursor_point(Gdk.EventScroll event, double zoom_increment) {
+ private void zoom_about_event_cursor_point(Gtk.EventControllerScroll event, double zoom_increment) {
if (photo_missing)
return;
@@ -693,7 +693,6 @@ public abstract class EditingHostPage : SinglePhotoPage {
update_cursor_for_zoom_context();
}
- #endif
protected void snap_zoom_to_min() {
zoom_slider.set_value(0.0);
@@ -753,8 +752,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
return zoom_buffer;
}
- #if 0
- protected override bool on_mousewheel_up(Gdk.EventScroll event) {
+ protected override bool on_mousewheel_up(Gtk.EventControllerScroll event) {
if (get_zoom_state().is_max() || !zoom_slider.get_sensitive())
return false;
@@ -762,14 +760,13 @@ public abstract class EditingHostPage : SinglePhotoPage {
return true;
}
- protected override bool on_mousewheel_down(Gdk.EventScroll event) {
+ protected override bool on_mousewheel_down(Gtk.EventControllerScroll event) {
if (get_zoom_state().is_min() || !zoom_slider.get_sensitive())
return false;
zoom_about_event_cursor_point(event, -ZOOM_INCREMENT_SIZE);
return true;
}
- #endif
protected override void restore_zoom_state() {
base.restore_zoom_state();
@@ -1322,11 +1319,11 @@ public abstract class EditingHostPage : SinglePhotoPage {
return false;
}
- #if 0
+
protected override void on_resize(Gdk.Rectangle rect) {
base.on_resize(rect);
- track_tool_window();
+ //track_tool_window();
}
protected override void on_resize_finished(Gdk.Rectangle rect) {
@@ -1338,7 +1335,6 @@ public abstract class EditingHostPage : SinglePhotoPage {
update_pixbuf();
}
- #endif
private void on_viewport_resized() {
// this means the viewport (the display area) has changed, but not necessarily the
@@ -1553,33 +1549,38 @@ public abstract class EditingHostPage : SinglePhotoPage {
if (command != null)
get_command_manager().execute(command);
}
+ #endif
// This virtual method is called only when the user double-clicks on the page and no tool
// is active
- protected virtual bool on_double_click(Gdk.EventButton event) {
+ protected virtual bool on_double_click(Gtk.EventController event, double x, double y) {
return false;
}
// Return true to block the DnD handler from activating a drag
- protected override bool on_left_click(Gdk.EventButton event) {
+ protected override bool on_left_click(Gtk.EventController event, int press, double x, double y) {
// report double-click if no tool is active, otherwise all double-clicks are eaten
+ #if 0
if (event.type == Gdk.EventType.2BUTTON_PRESS)
return (current_tool == null) ? on_double_click(event) : false;
+ #else
+ if (press == 2) {
+ on_double_click (event, x, y);
+ }
+ #endif
- int x = (int) event.x;
- int y = (int) event.y;
-
// if no editing tool, then determine whether we should start a pan operation over the
// zoomed photo or fall through to the default DnD behavior if we're not zoomed
- if ((current_tool == null) && (zoom_slider.get_value() != 0.0)) {
- zoom_pan_start_point.x = (int) event.x;
- zoom_pan_start_point.y = (int) event.y;
+ if (/*(current_tool == null) && */(zoom_slider.get_value() != 0.0)) {
+ zoom_pan_start_point.x = (int) x;
+ zoom_pan_start_point.y = (int) y;
is_pan_in_progress = true;
suspend_cursor_hiding();
return true;
}
+#if 0
// default behavior when photo isn't zoomed -- return false to start DnD operation
if (current_tool == null) {
return false;
@@ -1594,13 +1595,16 @@ public abstract class EditingHostPage : SinglePhotoPage {
// block DnD handlers if tool is enabled
return true;
+#else
+ return false;
+#endif
}
- protected override bool on_left_released(Gdk.EventButton event) {
+ protected override bool on_left_released(Gtk.EventController event, int press, double x, double y) {
if (is_pan_in_progress) {
Gdk.Point viewport_center = get_zoom_state().get_viewport_center();
- int delta_x = ((int) event.x) - zoom_pan_start_point.x;
- int delta_y = ((int) event.y) - zoom_pan_start_point.y;
+ int delta_x = ((int) x) - zoom_pan_start_point.x;
+ int delta_y = ((int) y) - zoom_pan_start_point.y;
viewport_center.x -= delta_x;
viewport_center.y -= delta_y;
@@ -1612,6 +1616,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
restore_cursor_hiding();
}
+#if 0
// report all releases, as it's possible the user click and dragged from inside the
// pixbuf to the gutters
if (current_tool == null)
@@ -1621,14 +1626,20 @@ public abstract class EditingHostPage : SinglePhotoPage {
if (current_tool.get_tool_window() != null)
current_tool.get_tool_window().present();
+#endif
return false;
}
- protected override bool on_right_click(Gdk.EventButton event) {
- return on_context_buttonpress(event);
+ protected override bool on_right_click(Gtk.EventController event, int press, double x, double y) {
+ if (press != 1) return false;
+ var sequence = ((Gtk.GestureSingle)event).get_current_sequence();
+ var last_event = ((Gtk.Gesture)event).get_last_event(sequence);
+
+ if (!last_event.triggers_context_menu()) return false;
+
+ return on_context_buttonpress(event, x, y);
}
- #endif
private void on_photos_altered(Gee.Map<DataObject, Alteration> map) {
if (!map.has_key(get_photo()))
@@ -1674,8 +1685,8 @@ public abstract class EditingHostPage : SinglePhotoPage {
}
// Return true to block the DnD handler from activating a drag
- #if 0
- protected override bool on_motion(Gdk.EventMotion event, int x, int y, Gdk.ModifierType mask) {
+ protected override bool on_motion(Gtk.EventControllerMotion event, double x, double y, Gdk.ModifierType
mask) {
+ #if 0
if (current_tool != null) {
current_tool.on_motion(x, y, mask);
@@ -1684,12 +1695,13 @@ public abstract class EditingHostPage : SinglePhotoPage {
return true;
}
+ #endif
update_cursor_for_zoom_context();
if (is_pan_in_progress) {
- int delta_x = ((int) event.x) - zoom_pan_start_point.x;
- int delta_y = ((int) event.y) - zoom_pan_start_point.y;
+ int delta_x = (int)x - zoom_pan_start_point.x;
+ int delta_y = (int)y - zoom_pan_start_point.y;
Gdk.Point viewport_center = get_zoom_state().get_viewport_center();
viewport_center.x -= delta_x;
@@ -1704,13 +1716,16 @@ public abstract class EditingHostPage : SinglePhotoPage {
return base.on_motion(event, x, y, mask);
}
- protected override bool on_leave_notify_event() {
+ protected override void on_leave_notify_event(Gtk.EventControllerMotion event) {
+ #if 0
if (current_tool != null)
return current_tool.on_leave_notify_event();
+ #endif
- return base.on_leave_notify_event();
+ base.on_leave_notify_event(event);
}
+ #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) {
@@ -2876,26 +2891,23 @@ public class LibraryPhotoPage : EditingHostPage {
return base.on_left_released(event);
}
+ #endif
- private Gtk.Menu context_menu;
+ private Gtk.PopoverMenu context_menu;
- private Gtk.Menu get_context_menu() {
+ private Gtk.PopoverMenu get_context_menu() {
if (context_menu == null) {
- var model = this.builder.get_object ("PhotoContextMenu")
- as GLib.MenuModel;
- context_menu = new Gtk.Menu.from_model (model);
- context_menu.attach_to_widget (this, null);
+ context_menu = get_popover_menu_from_builder (this.builder, "PhotoContextMenu", this);
}
return this.context_menu;
}
- protected override bool on_context_buttonpress(Gdk.EventButton event) {
- popup_context_menu(get_context_menu(), event);
+ protected override bool on_context_buttonpress(Gtk.EventController event, double x, double y) {
+ popup_context_menu(get_context_menu(), x, y);
return true;
}
- #endif
protected override bool on_context_keypress() {
//popup_context_menu(get_context_menu());
diff --git a/src/SinglePhotoPage.vala b/src/SinglePhotoPage.vala
index 15093be4..8e716b13 100644
--- a/src/SinglePhotoPage.vala
+++ b/src/SinglePhotoPage.vala
@@ -51,7 +51,6 @@ public abstract class SinglePhotoPage : Page {
scrolled.set_child(viewport);
-#if 0
canvas.add_events(Gdk.EventMask.EXPOSURE_MASK | Gdk.EventMask.STRUCTURE_MASK
| Gdk.EventMask.SUBSTRUCTURE_MASK);
@@ -294,17 +293,14 @@ public abstract class SinglePhotoPage : Page {
internal_repaint(true, null);
}
-#if 0
-// TODO
protected override void on_resize_finished(Gdk.Rectangle rect) {
base.on_resize_finished(rect);
// when the resize is completed, do a high-quality repaint
repaint();
}
- #endif
- private bool on_canvas_exposed(Cairo.Context exposed_ctx) {
+ private void on_canvas_exposed(Gtk.DrawingArea da, Cairo.Context exposed_ctx, int width, int height) {
// draw pixmap onto canvas unless it's not been instantiated, in which case draw black
// (so either old image or contents of another page is not left on screen)
if (pixmap != null)
@@ -314,8 +310,6 @@ public abstract class SinglePhotoPage : Page {
exposed_ctx.rectangle(0, 0, get_allocated_width(), get_allocated_height());
exposed_ctx.paint();
-
- return true;
}
protected virtual void new_surface(Cairo.Context ctx, Dimensions ctx_dim) {
@@ -473,7 +467,7 @@ public abstract class SinglePhotoPage : Page {
protected override bool on_context_keypress() {
//return popup_context_menu(get_page_context_menu());
- return true;
+ return false;
}
protected virtual void on_previous_photo() {
diff --git a/src/direct/DirectPhotoPage.vala b/src/direct/DirectPhotoPage.vala
index 09f2ab64..d510a291 100644
--- a/src/direct/DirectPhotoPage.vala
+++ b/src/direct/DirectPhotoPage.vala
@@ -145,26 +145,21 @@ public class DirectPhotoPage : EditingHostPage {
return get_photo().get_file();
}
-#if 0
- protected override bool on_context_buttonpress(Gdk.EventButton event) {
- popup_context_menu(get_context_menu(), event);
+ protected override bool on_context_buttonpress(Gtk.EventController event, double x, double y) {
+ popup_context_menu(get_context_menu(), x, y);
return true;
}
- private Gtk.Menu context_menu;
+ private Gtk.PopoverMenu context_menu;
- private Gtk.Menu get_context_menu() {
+ private Gtk.PopoverMenu get_context_menu() {
if (context_menu == null) {
- var model = this.builder.get_object ("DirectContextMenu")
- as GLib.MenuModel;
- context_menu = new Gtk.Menu.from_model (model);
- context_menu.attach_to_widget (this, null);
+ context_menu = get_popover_menu_from_builder (this.builder, "DirectContextMenu", this);
}
return this.context_menu;
}
- #endif
private void update_zoom_menu_item_sensitivity() {
set_action_sensitive("IncreaseSize", !get_zoom_state().is_max() && !get_photo_missing());
diff --git a/src/sidebar/Tree.vala b/src/sidebar/Tree.vala
index abc02ea4..c0875ac9 100644
--- a/src/sidebar/Tree.vala
+++ b/src/sidebar/Tree.vala
@@ -201,9 +201,7 @@ public class Sidebar.Tree : Gtk.TreeView {
private void setup_default_context_menu() {
try {
- this.builder.add_from_resource(Resources.get_ui("sidebar_default_context.ui"));
- var model = builder.get_object ("popup-menu") as GLib.MenuModel;
- this.default_context_menu = new Gtk.PopoverMenu.from_model (model);
+ this.default_context_menu = get_popover_menu_from_builder(builder, "popup-menu", this);
var group = new GLib.SimpleActionGroup ();
group.add_action_entries (entries, this);
this.insert_action_group ("sidebar", group);
diff --git a/src/tags/TagsBranch.vala b/src/tags/TagsBranch.vala
index 12056b08..ef6f10de 100644
--- a/src/tags/TagsBranch.vala
+++ b/src/tags/TagsBranch.vala
@@ -124,25 +124,11 @@ public class Tags.Branch : Sidebar.Branch {
public class Tags.Header : Sidebar.Header, Sidebar.InternalDropTargetEntry,
Sidebar.Contextable {
- private Gtk.Builder builder;
private Gtk.PopoverMenu? context_menu = null;
public Header() {
base (_("Tags"), _("Organize and browse your photo’s tags"));
- setup_context_menu();
- }
-
- private void setup_context_menu() {
- this.builder = new Gtk.Builder ();
- try {
- this.builder.add_from_resource(Resources.get_ui("tag_sidebar_context.ui"));
- var model = builder.get_object ("popup-menu") as GLib.MenuModel;
- this.context_menu = new Gtk.PopoverMenu.from_model (model);
- } catch (Error error) {
- AppWindow.error_message("Error loading UI resource: %s".printf(
- error.message));
- Application.get_instance().panic();
- }
+ this.context_menu = get_popover_menu_from_resource(Resources.get_ui("tag_sidebar_context.ui"),
"popup-menu", null);
}
public bool internal_drop_received(Gee.List<MediaSource> media) {
diff --git a/src/util/ui.vala b/src/util/ui.vala
index 00a485cf..e5a0657c 100644
--- a/src/util/ui.vala
+++ b/src/util/ui.vala
@@ -59,6 +59,23 @@ public Gdk.Rectangle get_adjustment_page(Gtk.Adjustment hadj, Gtk.Adjustment vad
return rect;
}
+Gtk.PopoverMenu get_popover_menu_from_resource(string path, string id, Gtk.Widget? parent) {
+ var builder = new Gtk.Builder.from_resource(path);
+ return get_popover_menu_from_builder(builder, id, parent);
+}
+
+Gtk.PopoverMenu get_popover_menu_from_builder(Gtk.Builder builder, string id, Gtk.Widget? parent) {
+ var model = builder.get_object (id) as GLib.MenuModel;
+ var popover = new Gtk.PopoverMenu.from_model (model);
+ if (parent != null) {
+ popover.set_parent (parent);
+ }
+ popover.set_has_arrow(false);
+
+ return popover;
+}
+
+
// Verifies that only the mask bits are set in the modifier field, disregarding mouse and
// key modifiers that are not normally of concern (i.e. Num Lock, Caps Lock, etc.). Mask can be
// one or more bits set, but should only consist of these values:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]