Commit e98aeae6 authored by Allison Barlow's avatar Allison Barlow

fixes #1200 Support context menu key, #1204 View original photo should check...

fixes #1200 Support context menu key, #1204 View original photo should check for other modifier keys, and #1311 directories listed as unimported photos.
parent c318b2a0
......@@ -88,7 +88,8 @@ public class ImportManifest {
break;
case ImportResult.USER_ABORT:
aborted.add(batch_result);
if (!query_is_directory(batch_result.file))
aborted.add(batch_result);
break;
case ImportResult.NOT_A_FILE:
......
......@@ -480,7 +480,7 @@ public abstract class CollectionPage : CheckerboardPage {
}
}
protected override bool on_context_invoked(Gtk.Menu context_menu) {
protected override bool on_context_invoked() {
bool selected = get_view().get_selected_count() > 0;
bool revert_possible = can_revert_selected();
......@@ -501,7 +501,7 @@ public abstract class CollectionPage : CheckerboardPage {
get_view().get_selected_count() == 1);
#endif
return true;
return base.on_context_invoked();
}
public override LayoutItem? get_fullscreen_photo() {
......
......@@ -238,13 +238,13 @@ public class EventsDirectoryPage : CheckerboardPage {
LibraryWindow.get_app().switch_to_event(event.event);
}
protected override bool on_context_invoked(Gtk.Menu context_menu) {
protected override bool on_context_invoked() {
set_item_sensitive("/EventsDirectoryContextMenu/ContextRename",
get_view().get_selected_count() == 1);
set_item_sensitive("/EventsDirectoryContextMenu/ContextMerge",
get_view().get_selected_count() > 1);
return true;
return base.on_context_invoked();
}
private EventDirectoryItem? get_fullscreen_item() {
......@@ -392,11 +392,11 @@ public class EventPage : CollectionPage {
base.on_photos_menu();
}
protected override bool on_context_invoked(Gtk.Menu context_menu) {
protected override bool on_context_invoked() {
set_item_sensitive("/CollectionContextMenu/ContextMakePrimary",
get_view().get_selected_count() == 1);
return base.on_context_invoked(context_menu);
return base.on_context_invoked();
}
private void on_make_primary() {
......
......@@ -36,9 +36,9 @@ public abstract class Page : Gtk.ScrolledWindow, SidebarPage {
private bool report_move_finished = false;
private bool report_resize_finished = false;
private Gdk.Point last_down = Gdk.Point();
private bool ctrl_pressed = false;
private bool alt_pressed = false;
private bool shift_pressed = false;
protected bool ctrl_pressed = false;
protected bool alt_pressed = false;
protected bool shift_pressed = false;
public Page(string page_name) {
this.page_name = page_name;
......@@ -47,6 +47,8 @@ public abstract class Page : Gtk.ScrolledWindow, SidebarPage {
last_down = { -1, -1 };
set_flags(Gtk.WidgetFlags.CAN_FOCUS);
popup_menu += on_context_keypress;
}
~Page() {
......@@ -220,15 +222,21 @@ public abstract class Page : Gtk.ScrolledWindow, SidebarPage {
widget.sensitive = sensitive;
}
private virtual void update_modifiers() {
int x, y;
private void get_modifiers(out bool ctrl, out bool alt, out bool shift) {
int x, y;
Gdk.ModifierType mask;
AppWindow.get_instance().window.get_pointer(out x, out y, out mask);
bool ctrl_currently_pressed = (mask & Gdk.ModifierType.CONTROL_MASK) != 0;
bool alt_currently_pressed = (mask & Gdk.ModifierType.MOD1_MASK) != 0;
bool shift_currently_pressed = (mask & Gdk.ModifierType.SHIFT_MASK) != 0;
ctrl = (mask & Gdk.ModifierType.CONTROL_MASK) != 0;
alt = (mask & Gdk.ModifierType.MOD1_MASK) != 0;
shift = (mask & Gdk.ModifierType.SHIFT_MASK) != 0;
}
private virtual void update_modifiers() {
bool ctrl_currently_pressed, alt_currently_pressed, shift_currently_pressed;
get_modifiers(out ctrl_currently_pressed, out alt_currently_pressed,
out shift_currently_pressed);
if (ctrl_pressed && !ctrl_currently_pressed)
on_ctrl_released(null);
else if (!ctrl_pressed && ctrl_currently_pressed)
......@@ -515,21 +523,36 @@ public abstract class Page : Gtk.ScrolledWindow, SidebarPage {
}
public bool notify_app_key_pressed(Gdk.EventKey event) {
bool ctrl_currently_pressed, alt_currently_pressed, shift_currently_pressed;
get_modifiers(out ctrl_currently_pressed, out alt_currently_pressed,
out shift_currently_pressed);
switch (Gdk.keyval_name(event.keyval)) {
case "Control_L":
case "Control_R":
if (!ctrl_currently_pressed || ctrl_pressed)
return false;
ctrl_pressed = true;
return on_ctrl_pressed(event);
case "Meta_L":
case "Meta_R":
case "Alt_L":
case "Alt_R":
if (!alt_currently_pressed || alt_pressed)
return false;
alt_pressed = true;
return on_alt_pressed(event);
case "Shift_L":
case "Shift_R":
if (!shift_currently_pressed || shift_pressed)
return false;
shift_pressed = true;
return on_shift_pressed(event);
......@@ -539,21 +562,36 @@ public abstract class Page : Gtk.ScrolledWindow, SidebarPage {
}
public bool notify_app_key_released(Gdk.EventKey event) {
bool ctrl_currently_pressed, alt_currently_pressed, shift_currently_pressed;
get_modifiers(out ctrl_currently_pressed, out alt_currently_pressed,
out shift_currently_pressed);
switch (Gdk.keyval_name(event.keyval)) {
case "Control_L":
case "Control_R":
if (ctrl_currently_pressed || !ctrl_pressed)
return false;
ctrl_pressed = false;
return on_ctrl_released(event);
case "Meta_L":
case "Meta_R":
case "Alt_L":
case "Alt_R":
if (alt_currently_pressed || !alt_pressed)
return false;
alt_pressed = false;
return on_alt_released(event);
case "Shift_L":
case "Shift_R":
if (shift_currently_pressed || !shift_pressed)
return false;
shift_pressed = false;
return on_shift_released(event);
......@@ -664,6 +702,33 @@ public abstract class Page : Gtk.ScrolledWindow, SidebarPage {
return on_motion(event, x, y, mask);
}
protected virtual bool on_context_keypress() {
return false;
}
protected virtual bool on_context_buttonpress(Gdk.EventButton event) {
return false;
}
protected virtual bool on_context_invoked() {
return true;
}
protected bool popup_context_menu(Gtk.Menu? context_menu,
Gdk.EventButton? event = null) {
on_context_invoked();
if (context_menu == null)
return false;
if (event == null)
context_menu.popup(null, null, null, 0, Gtk.get_current_event_time());
else
context_menu.popup(null, null, null, event.button, event.time);
return true;
}
}
public abstract class CheckerboardPage : Page {
......@@ -722,11 +787,11 @@ public abstract class CheckerboardPage : Page {
return page_context_menu;
}
protected virtual void on_item_activated(LayoutItem item) {
protected override bool on_context_keypress() {
return popup_context_menu(get_context_menu());
}
protected virtual bool on_context_invoked(Gtk.Menu context_menu) {
return true;
protected virtual void on_item_activated(LayoutItem item) {
}
public CheckerboardLayout get_checkerboard_layout() {
......@@ -1001,7 +1066,7 @@ public abstract class CheckerboardPage : Page {
if (context_menu == null)
return false;
if (!on_context_invoked(context_menu))
if (!on_context_invoked())
return false;
context_menu.popup(null, null, null, event.button, event.time);
......@@ -1517,5 +1582,9 @@ public abstract class SinglePhotoPage : Page {
new_drawable(canvas_gc, pixmap);
}
protected override bool on_context_keypress() {
return popup_context_menu(get_page_context_menu());
}
}
......@@ -534,28 +534,51 @@ public abstract class EditingHostPage : SinglePhotoPage {
private override bool on_shift_pressed(Gdk.EventKey? event) {
// show quick compare of original only if no tool is in use, the original pixbuf is handy
if (current_tool == null) {
Gdk.Pixbuf original = original_cache.get_ready_pixbuf(get_photo());
if (original != null) {
// store what's currently displayed only for the duration of the shift pressing
swapped = get_unscaled_pixbuf();
set_pixbuf(original, get_photo().get_original_dimensions());
}
if (current_tool == null && !ctrl_pressed && !alt_pressed) {
swap_in_original();
}
return base.on_shift_pressed(event);
}
private override bool on_shift_released(Gdk.EventKey? event) {
if (current_tool == null && swapped != null) {
if (current_tool == null)
swap_out_original();
return base.on_shift_released(event);
}
private override bool on_alt_pressed(Gdk.EventKey? event) {
if (current_tool == null)
swap_out_original();
return base.on_alt_pressed(event);
}
private override bool on_alt_released(Gdk.EventKey? event) {
if (current_tool == null && shift_pressed && !ctrl_pressed)
swap_in_original();
return base.on_alt_released(event);
}
private void swap_in_original() {
Gdk.Pixbuf original = original_cache.get_ready_pixbuf(get_photo());
if (original != null) {
// store what's currently displayed only for the duration of the shift pressing
swapped = get_unscaled_pixbuf();
set_pixbuf(original, get_photo().get_original_dimensions());
}
}
private void swap_out_original() {
if (swapped != null) {
set_pixbuf(swapped, get_photo().get_dimensions());
// only store swapped once; it'll be set the next on_shift_pressed
swapped = null;
}
return base.on_shift_released(event);
}
private void activate_tool(EditingTool tool) {
......@@ -764,7 +787,7 @@ public abstract class EditingHostPage : SinglePhotoPage {
}
private override bool on_right_click(Gdk.EventButton event) {
return on_context_menu(event);
return on_context_buttonpress(event);
}
private void on_photo_altered(DataObject object) {
......@@ -798,10 +821,6 @@ public abstract class EditingHostPage : SinglePhotoPage {
return false;
}
private virtual bool on_context_menu(Gdk.EventButton event) {
return false;
}
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) {
......@@ -960,6 +979,9 @@ public abstract class EditingHostPage : SinglePhotoPage {
rotate_button.clicked -= on_rotate_clockwise;
rotate_button.clicked += on_rotate_counterclockwise;
if (current_tool == null)
swap_out_original();
return base.on_ctrl_pressed(event);
}
......@@ -969,6 +991,9 @@ public abstract class EditingHostPage : SinglePhotoPage {
rotate_button.set_tooltip_text(Resources.ROTATE_CW_TOOLTIP);
rotate_button.clicked -= on_rotate_counterclockwise;
rotate_button.clicked += on_rotate_clockwise;
if (current_tool == null && shift_pressed && !alt_pressed)
swap_in_original();
return base.on_ctrl_released(event);
}
......@@ -1336,7 +1361,7 @@ public class LibraryPhotoPage : EditingHostPage {
return false;
}
private override bool on_context_menu(Gdk.EventButton event) {
private override bool on_context_invoked() {
if (!has_photo())
return false;
......@@ -1350,7 +1375,17 @@ public class LibraryPhotoPage : EditingHostPage {
set_item_sensitive("/PhotoContextMenu/ContextSetBackground", false);
#endif
context_menu.popup(null, null, null, event.button, event.time);
return base.on_context_invoked();
}
private override bool on_context_buttonpress(Gdk.EventButton event) {
popup_context_menu(context_menu, event);
return true;
}
private override bool on_context_keypress() {
popup_context_menu(context_menu);
return true;
}
......@@ -1795,7 +1830,7 @@ public class DirectPhotoPage : EditingHostPage {
base.set_missing_photo_sensitivities(sensitivity);
}
private override bool on_context_menu(Gdk.EventButton event) {
private override bool on_context_invoked() {
if (get_photo() == null)
return false;
......@@ -1804,10 +1839,8 @@ public class DirectPhotoPage : EditingHostPage {
is_rotate_available(get_photo()));
set_item_sensitive("/DirectContextMenu/ContextEnhance", is_enhance_available(get_photo()));
set_item_sensitive("/DirectContextMenu/ContextRevert", get_photo().has_transformations());
context_menu.popup(null, null, null, event.button, event.time);
return true;
return base.on_context_invoked();
}
private bool check_ok_to_close_photo(TransformablePhoto photo) {
......
......@@ -38,7 +38,6 @@ public interface SidebarPage : Object {
public class Sidebar : Gtk.TreeView {
private Gtk.TreeStore store = new Gtk.TreeStore(2, typeof(string), typeof(SidebarPage));
private Gtk.Menu context_menu = null;
private Gtk.TreePath current_path = null;
public signal void drop_received(Gdk.DragContext context, int x, int y, Gtk.SelectionData selection_data, uint info, uint time, SidebarPage? page);
......@@ -72,6 +71,8 @@ public class Sidebar : Gtk.TreeView {
selection.set_select_function(on_selection, null);
enable_model_drag_dest(LibraryWindow.DEST_TARGET_ENTRIES, Gdk.DragAction.ASK);
popup_menu += on_context_menu_keypress;
}
public void place_cursor(SidebarPage page) {
......@@ -309,9 +310,36 @@ public class Sidebar : Gtk.TreeView {
return path;
}
private bool popup_context_menu(Gtk.Menu? context_menu, Gdk.EventButton? event = null) {
// TODO: share this code with Page, possibly through a contextable interface
if (context_menu == null)
return false;
if (event == null)
context_menu.popup(null, null, null, 0, Gtk.get_current_event_time());
else
context_menu.popup(null, null, null, event.button, event.time);
return true;
}
private bool on_context_menu_keypress() {
Gtk.TreePath path = get_selection().get_selected_rows(null).data;
Gtk.Menu context_menu = get_context_menu(path);
scroll_to_cell(path, null, false, 0, 0);
popup_context_menu(context_menu);
return true;
}
protected Gtk.Menu? get_context_menu(Gdk.EventButton event) {
SidebarPage page = locate_page(get_path_from_event(event));
protected Gtk.Menu? get_context_menu(Gtk.TreePath path) {
SidebarPage page = locate_page(path);
return (page != null) ? page.get_page_context_menu() : null;
}
......@@ -320,11 +348,7 @@ public class Sidebar : Gtk.TreeView {
if (event.button == 3 && event.type == Gdk.EventType.BUTTON_PRESS) {
// single right click
context_menu = get_context_menu(event);
if (context_menu == null)
return false;
context_menu.popup(null, null, null, event.button, event.time);
popup_context_menu(get_context_menu(get_path_from_event(event)), event);
} else if (event.button == 1 && event.type == Gdk.EventType.2BUTTON_PRESS) {
// double left click
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment