diff --git a/src/Autocompletion.vala b/src/Autocompletion.vala index d5086b2..5af88b0 100644 --- a/src/Autocompletion.vala +++ b/src/Autocompletion.vala @@ -49,6 +49,9 @@ public class Autocompletion : Object { scrollable_list_view.set_filter_function(filter_function); scrollable_list_view.set_sort_function(sort_function); + scrollable_list_view.item_hovered.connect(on_item_hovered); + scrollable_list_view.item_clicked.connect(on_item_clicked); + scrollable_list_view.item_double_clicked.connect(on_item_double_clicked); on_settings_changed(null); Settings.get_default().changed.connect(on_settings_changed); @@ -212,6 +215,20 @@ public class Autocompletion : Object { stage.set_background_color(Settings.get_default().foreground_color); } + private void on_item_hovered(int index) { + select_entry(index); + } + + private void on_item_clicked(int index) { + select_command(scrollable_list_view.get_item(index).text); + } + + private void on_item_double_clicked(int index) { + run_command(scrollable_list_view.get_item(index).text); + } + + public signal void run_command(string command); + public signal void select_command(string command); private class AutocompletionEntry : Object { diff --git a/src/FinalTerm.vala b/src/FinalTerm.vala index 505d5d8..33240cf 100644 --- a/src/FinalTerm.vala +++ b/src/FinalTerm.vala @@ -106,6 +106,8 @@ public class FinalTerm : Gtk.Application { im_context.preedit_end.connect(on_preedit_end); main_window.key_press_event.connect(on_key_press_event); main_window.key_release_event.connect(on_key_release_event); + autocompletion.run_command.connect(on_autocomplete_run_command); + autocompletion.select_command.connect(on_autocomplete_select_command); } protected override void activate() { @@ -243,6 +245,14 @@ public class FinalTerm : Gtk.Application { return true; } + private void on_autocomplete_run_command(string command) { + active_terminal_widget.run_shell_command(command); + } + + private void on_autocomplete_select_command(string command) { + active_terminal_widget.set_shell_command(command); + } + private bool on_key_release_event(Gdk.EventKey event) { return im_context.filter_keypress(event); } diff --git a/src/ScrollableListView.vala b/src/ScrollableListView.vala index 0bc8f9c..717e2c4 100644 --- a/src/ScrollableListView.vala +++ b/src/ScrollableListView.vala @@ -27,6 +27,8 @@ public class ScrollableListView : Clutter.Actor { private Clutter.Model list_model; + private bool process_click = false; + public ScrollableListView(NotifyingList list, Type item_type, Type item_view_type, string item_property_name) { scroll_view = new Mx.ScrollView(); add(scroll_view); @@ -54,6 +56,8 @@ public class ScrollableListView : Clutter.Actor { list_view.add_attribute(item_property_name, 0); scroll_view.add(list_view); + scroll_view.motion_event.connect(on_motion_event); + scroll_view.button_press_event.connect(on_button_press_event);; // Synchronize model with list foreach (var item in list) { @@ -143,11 +147,63 @@ public class ScrollableListView : Clutter.Actor { scroll_view.ensure_visible(geometry); } + public int get_item_by_y(int y) { + var index = -1; + var height = 0; + for (int i = 0; i < get_number_of_items(); i++) { + var allocation_box = get_item_view(i).get_allocation_box(); + height += (int)allocation_box.get_height(); + if ((int)y < height) { + index = i; + break; + } + } + return index; + } + private void on_settings_changed(string? key) { scroll_view.style = Settings.get_default().theme.style; list_view.style = Settings.get_default().theme.style; } + private bool on_motion_event(Clutter.MotionEvent event) { + var index = get_item_by_y((int)event.y); + if (index >= 0) { + item_hovered(index); + } + + return true; + } + + private bool on_button_press_event(Clutter.ButtonEvent event) { + int index = get_item_by_y((int)event.y); + process_click = false; + + if (index >= 0) { + if (event.click_count == 1) { + process_click = true; + ScrollableListView instance = this; + // Button press event fires twice on double click + // because of this the processing of the first click should be delayed + // if the second click has happened in the meantime process_click would be false + // TODO: look for a better solution + Timeout.add(Clutter.Settings.get_default().double_click_time + 50, () => { + if (instance.process_click) { + instance.item_clicked(index); + } + return false; + }, Priority.DEFAULT); + } else if (event.click_count > 1) { + item_double_clicked(index); + } + } + + return true; + } + + public signal void item_hovered(int index); + public signal void item_clicked(int index); + public signal void item_double_clicked(int index); private class ItemViewFactory : Object, Mx.ItemFactory { diff --git a/src/Terminal.vala b/src/Terminal.vala index ff58dec..a958300 100644 --- a/src/Terminal.vala +++ b/src/Terminal.vala @@ -120,7 +120,7 @@ public class Terminal : Object { } private void on_output_command_updated(string command) { - message(_("Command updated: '%s'"), command); + // message(_("Command updated: '%s'"), command); var stripped_command = command.strip(); if (stripped_command == "") {