[meld] filediff, misc: Align syncpoints at top/bottom better (bgo#780608)
- From: Kai Willadsen <kaiw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [meld] filediff, misc: Align syncpoints at top/bottom better (bgo#780608)
- Date: Tue, 25 Apr 2017 01:57:44 +0000 (UTC)
commit 6b71cde5cf0455c1d7cbd6750ab4f39d1b730a46
Author: Kai Willadsen <kai willadsen gmail com>
Date: Tue Apr 25 11:29:58 2017 +1000
filediff, misc: Align syncpoints at top/bottom better (bgo#780608)
The issue here addressed by this change is that when we get scroll near
the top or bottom of a pane, and the corresponding pane that gets its
scroll set has more lines in the top-/bottom-most chunk, we won't ever
scroll the whole dependent chunk in to view.
For example, in a situation where we're scrolling to the bottom of a
comparison in the left pane, with the right pane being set by this
sync, and we have an end-of-file that looks like:
viewport left right
| x x
| x x
| x x
| a b
_ EOF b
b
EOF
the last two lines of b will often not be scrolled into view. The reason
here is that the way we decide how to align the right pane is to find
the middle of the left pane, figure out what chunk is there, find the
corresponding chunk in the right pane and then try to align those lines.
This means that the start and end of a file are aligned according to
whatever chunk is half way up the page. This is fine and good, except
that if e.g., the first `x` above is in the middle of the screen,
there's no way that you can scroll the left pane down far enough to be
able to see the bottom of the right pane.
The fix here is that we adjust the syncpoint that we use according to
where we are in the document. If we're showing the first half page, we
scale our syncpoint to be toward the top of the page; if we're showing
the last half page we scale the syncpoint towards the bottom. For most
normal documents, the majority of the document will have a syncpoint
of 0.5 (the middle of the screen) which is what we've always used.
meld/filediff.py | 6 +++---
meld/misc.py | 29 +++++++++++++++++++++++++++++
2 files changed, 32 insertions(+), 3 deletions(-)
---
diff --git a/meld/filediff.py b/meld/filediff.py
index 10d3e19..8e4b6e5 100644
--- a/meld/filediff.py
+++ b/meld/filediff.py
@@ -1670,11 +1670,11 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
@with_scroll_lock('_sync_vscroll_lock')
def _sync_vscroll(self, adjustment, master):
- SYNCPOINT = 0.5
+ syncpoint = misc.calc_syncpoint(adjustment)
# Middle of the screen, in buffer coords
middle_y = (
- adjustment.get_value() + adjustment.get_page_size() * SYNCPOINT)
+ adjustment.get_value() + adjustment.get_page_size() * syncpoint)
# Find the target line. This is a float because, especially for
# wrapped lines, the sync point may be half way through a line.
@@ -1725,8 +1725,8 @@ class FileDiff(melddoc.MeldDoc, gnomeglade.Component):
other_line = obegin + fraction * (oend - obegin)
it = self.textbuffer[i].get_iter_at_line(int(other_line))
val, height = self.textview[i].get_line_yrange(it)
- val -= adj.get_page_size() * SYNCPOINT
val += (other_line - int(other_line)) * height
+ val -= adj.get_page_size() * syncpoint
val = min(max(val, adj.get_lower()),
adj.get_upper() - adj.get_page_size())
val = math.floor(val)
diff --git a/meld/misc.py b/meld/misc.py
index ef329cb..b8b102f 100644
--- a/meld/misc.py
+++ b/meld/misc.py
@@ -514,3 +514,32 @@ def apply_text_filters(txt, regexes, apply_fn=None):
offset = end
result_txts.append(txt[offset:])
return empty_string.join(result_txts)
+
+
+def calc_syncpoint(adj):
+ """Calculate a cross-pane adjustment synchronisation point
+
+ Our normal syncpoint is the middle of the screen. If the
+ current position is within the first half screen of a
+ document, we scale the sync point linearly back to 0.0 (top
+ of the screen); if it's the the last half screen, we again
+ scale linearly to 1.0.
+
+ The overall effect of this is to make sure that the top and
+ bottom parts of documents with different lengths and chunk
+ offsets correctly scroll into view.
+ """
+
+ current = adj.get_value()
+ half_a_screen = adj.get_page_size() / 2
+
+ syncpoint = 0.0
+ # How far through the first half-screen our adjustment is
+ top_val = adj.get_lower()
+ first_scale = (current - top_val) / half_a_screen
+ syncpoint += 0.5 * min(1, first_scale)
+ # How far through the last half-screen our adjustment is
+ bottom_val = adj.get_upper() - 1.5 * adj.get_page_size()
+ last_scale = (current - bottom_val) / half_a_screen
+ syncpoint += 0.5 * max(0, last_scale)
+ return syncpoint
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]