[gitg] Improve selection to allow rubber band.
- From: Ignacio Casal Quinteiro <icq src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gitg] Improve selection to allow rubber band.
- Date: Wed, 16 Dec 2015 18:05:07 +0000 (UTC)
commit f348fc44dddd24e98b92393b11366bfad08eba3d
Author: Ignacio Casal Quinteiro <icq gnome org>
Date: Wed Dec 16 10:18:38 2015 +0100
Improve selection to allow rubber band.
Still several bugs on this that we need to figure out
libgitg/gitg-diff-view-hunk.vala | 182 +++++++++++++++++++++++++++++++++++--
1 files changed, 172 insertions(+), 10 deletions(-)
---
diff --git a/libgitg/gitg-diff-view-hunk.vala b/libgitg/gitg-diff-view-hunk.vala
index 0e4c4e7..7632d84 100644
--- a/libgitg/gitg-diff-view-hunk.vala
+++ b/libgitg/gitg-diff-view-hunk.vala
@@ -131,6 +131,8 @@ class Gitg.DiffViewHunk : Gtk.Grid
selection_attributes.background = Gdk.RGBA() { red = 168.0 / 255.0, green = 207.0 /
255.0, blue = 214.0 / 255.0, alpha = 1.0 };
d_sourceview_hunk.set_mark_attributes(d_selection_category, selection_attributes, 0);
+ d_sourceview_hunk.button_press_event.connect(button_press_event_on_view);
+ d_sourceview_hunk.motion_notify_event.connect(motion_notify_event_on_view);
d_sourceview_hunk.button_release_event.connect(button_release_event_on_view);
}
@@ -144,7 +146,30 @@ class Gitg.DiffViewHunk : Gtk.Grid
update_top_window_size();
}
- private bool button_release_event_on_view(Gdk.EventButton event)
+ private bool get_line_selected(Gtk.TextIter iter)
+ {
+ var text_view = d_sourceview_hunk as Gtk.TextView;
+ Gtk.TextIter start = iter;
+
+ start.set_line_offset(0);
+ var buffer = text_view.get_buffer() as Gtk.SourceBuffer;
+
+ return buffer.get_source_marks_at_iter(start, d_selection_category) != null;
+ }
+
+ private bool get_line_is_diff(Gtk.TextIter iter)
+ {
+ var text_view = d_sourceview_hunk as Gtk.TextView;
+ Gtk.TextIter start = iter;
+
+ start.set_line_offset(0);
+ var buffer = text_view.get_buffer() as Gtk.SourceBuffer;
+
+ return (buffer.get_source_marks_at_iter(start, "added") != null) ||
+ (buffer.get_source_marks_at_iter(start, "removed") != null);
+ }
+
+ private bool get_iter_from_pointer_position(out Gtk.TextIter iter)
{
var text_view = d_sourceview_hunk as Gtk.TextView;
var win = text_view.get_window(Gtk.TextWindowType.TEXT);
@@ -164,25 +189,162 @@ class Gitg.DiffViewHunk : Gtk.Grid
int win_x, win_y;
text_view.window_to_buffer_coords(Gtk.TextWindowType.TEXT, x, y, out win_x, out win_y);
- Gtk.TextIter iter;
text_view.get_iter_at_location(out iter, win_x, win_y);
- iter.set_line_offset(0);
+ return true;
+ }
+
+ private void select_range(Gtk.TextIter start, Gtk.TextIter end)
+ {
+ var text_view = d_sourceview_hunk as Gtk.TextView;
+ var buffer = text_view.get_buffer() as Gtk.SourceBuffer;
+
+ start.order(end);
+
+ while (start.get_line() <= end.get_line())
+ {
+ start.set_line_offset(0);
+
+ if (get_line_is_diff(start))
+ {
+ buffer.create_source_mark(null, d_selection_category, start);
+ }
+
+ if (!start.forward_line())
+ {
+ break;
+ }
+ }
+ }
+
+ private void deselect_range(Gtk.TextIter start, Gtk.TextIter end)
+ {
+ var text_view = d_sourceview_hunk as Gtk.TextView;
var buffer = text_view.get_buffer() as Gtk.SourceBuffer;
- var marks = buffer.get_source_marks_at_iter(iter, d_selection_category);
- if (marks != null)
+
+ Gtk.TextIter real_start, real_end;
+
+ real_start = start;
+ real_start.set_line_offset(0);
+
+ real_end = end;
+ real_end.forward_to_line_end();
+
+ buffer.remove_source_marks(real_start, real_end, d_selection_category);
+ }
+
+ private bool d_is_selecting;
+ private bool d_is_deselecting;
+ private Gtk.TextMark d_start_selection_mark;
+ private Gtk.TextMark d_end_selection_mark;
+
+ private bool button_press_event_on_view(Gdk.EventButton event)
+ {
+ if (event.button != 1)
+ {
+ return false;
+ }
+
+ Gtk.TextIter iter;
+ if (!get_iter_from_pointer_position(out iter))
+ {
+ return false;
+ }
+
+ if (get_line_selected(iter))
+ {
+ d_is_deselecting = true;
+ deselect_range(iter, iter);
+ }
+ else
+ {
+ d_is_selecting = true;
+ select_range(iter, iter);
+ }
+
+ var text_view = d_sourceview_hunk as Gtk.TextView;
+ var buffer = text_view.get_buffer();
+
+ d_start_selection_mark = buffer.create_mark(null, iter, false);
+ d_end_selection_mark = buffer.create_mark(null, iter, false);
+
+ return false;
+ }
+
+ private bool motion_notify_event_on_view(Gdk.EventMotion event)
+ {
+ if (!d_is_selecting && !d_is_deselecting)
{
- Gtk.TextIter end;
+ return false;
+ }
+
+ Gtk.TextIter iter;
+ if (!get_iter_from_pointer_position(out iter))
+ {
+ return false;
+ }
+
+ var text_view = d_sourceview_hunk as Gtk.TextView;
+ var buffer = text_view.get_buffer();
+
+ Gtk.TextIter start, end, current;
+
+ current = iter;
+
+ buffer.get_iter_at_mark(out start, d_start_selection_mark);
+ start.order(current);
- end = iter;
- end.forward_to_line_end();
- buffer.remove_source_marks(iter, end, d_selection_category);
+ if (d_is_selecting)
+ {
+ select_range(start, current);
}
else
{
- buffer.create_source_mark(null, d_selection_category, iter);
+ deselect_range(start, current);
+ }
+
+ buffer.get_iter_at_mark(out end, d_end_selection_mark);
+ if (!end.in_range(start, current))
+ {
+ start = end;
+ current = iter;
+
+ start.order(current);
+
+ if (d_is_selecting)
+ {
+ deselect_range(start, current);
+ }
+ else
+ {
+ select_range(start, current);
+ }
+ }
+
+ buffer.move_mark(d_end_selection_mark, iter);
+
+ return false;
+ }
+
+ private bool button_release_event_on_view(Gdk.EventButton event)
+ {
+ if (event.button != 1)
+ {
+ return false;
}
+ d_is_selecting = false;
+ d_is_deselecting = false;
+
+ var text_view = d_sourceview_hunk as Gtk.TextView;
+ var buffer = text_view.get_buffer();
+
+ buffer.delete_mark(d_start_selection_mark);
+ d_start_selection_mark = null;
+
+ buffer.delete_mark(d_end_selection_mark);
+ d_end_selection_mark = null;
+
return false;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]