From 13f9a60c3e46b36a62d040e9f9870ddaf85e6cfb Mon Sep 17 00:00:00 2001 From: Shawn Pearce Date: Mon, 13 Jan 2014 17:35:26 -0800 Subject: [PATCH] SideBySide2: Replace system scrollbar with one on the overview Draw the viewport as a semi-transparent box on top of the overview bar on the right side of SideBySide2. This allows the reader to see how much of the visible file content is currently displayed. Handle drag events on this box and translate them into scroll events on the CM3 instances. This allows the reader to grab the viewport representation with the mouse and move it over another section. Make the height of each edit insert, delete or edit region related to the number of lines impacted. Regions that touch more lines will take up more vertical space on the overview bar. Remove the scrollbar from the B CM3. Rely on keyboard up/down, page up/down, mouse wheel, and dragging the viewport widget placed in the overview bar area. Change-Id: Ica0355a4b5f4a350b2db6c8557186fbb4758a24f --- .../gerrit/client/diff/ChunkManager.java | 10 +- .../google/gerrit/client/diff/CommentBox.java | 15 +- .../gerrit/client/diff/CommentManager.java | 12 +- .../gerrit/client/diff/DiffTable.ui.xml | 12 +- .../google/gerrit/client/diff/DraftBox.java | 2 +- .../gerrit/client/diff/OverviewBar.java | 265 +++++++++++------- .../gerrit/client/diff/OverviewBar.ui.xml | 35 ++- .../client/diff/ScrollSynchronizer.java | 3 + .../gerrit/client/diff/SideBySide2.java | 25 +- .../gerrit/client/diff/SideBySide2.ui.xml | 8 +- .../google/gerrit/client/diff/SkipBar.java | 3 + .../gerrit/client/diff/SkipManager.java | 5 + .../java/net/codemirror/lib/CodeMirror.java | 8 - .../java/net/codemirror/lib/ScrollInfo.java | 19 +- 14 files changed, 257 insertions(+), 165 deletions(-) diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/ChunkManager.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/ChunkManager.java index de5e308146..65b37318b7 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/ChunkManager.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/ChunkManager.java @@ -14,6 +14,10 @@ package com.google.gerrit.client.diff; +import static com.google.gerrit.client.diff.OverviewBar.MarkType.DELETE; +import static com.google.gerrit.client.diff.OverviewBar.MarkType.EDIT; +import static com.google.gerrit.client.diff.OverviewBar.MarkType.INSERT; + import com.google.gerrit.client.diff.DiffInfo.Region; import com.google.gerrit.client.diff.DiffInfo.Span; import com.google.gerrit.client.rpc.Natives; @@ -143,11 +147,11 @@ class ChunkManager { private void addGutterTag(Region region, int startA, int startB) { if (region.a() == null) { - sidePanel.addGutter(cmB, startB, OverviewBar.GutterType.INSERT); + sidePanel.add(cmB, startB, region.b().length(), INSERT); } else if (region.b() == null) { - sidePanel.addGutter(cmA, startA, OverviewBar.GutterType.DELETE); + sidePanel.add(cmA, startA, region.a().length(), DELETE); } else { - sidePanel.addGutter(cmB, startB, OverviewBar.GutterType.EDIT); + sidePanel.add(cmB, startB, region.b().length(), EDIT); } } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentBox.java index 0a6ee1af96..1d7452085c 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentBox.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentBox.java @@ -15,7 +15,6 @@ package com.google.gerrit.client.diff; import com.google.gerrit.client.changes.CommentInfo; -import com.google.gerrit.client.diff.OverviewBar.GutterWrapper; import com.google.gwt.event.dom.client.MouseOutEvent; import com.google.gwt.event.dom.client.MouseOutHandler; import com.google.gwt.event.dom.client.MouseOverEvent; @@ -34,7 +33,7 @@ abstract class CommentBox extends Composite { } private final CommentGroup group; - private GutterWrapper gutterWrapper; + private OverviewBar.MarkHandle mark; private FromTo fromTo; private TextMarker rangeMarker; private TextMarker rangeHighlightMarker; @@ -80,8 +79,12 @@ abstract class CommentBox extends Composite { return group.getCommentManager(); } - void setGutterWrapper(GutterWrapper wrapper) { - gutterWrapper = wrapper; + OverviewBar.MarkHandle getMark() { + return mark; + } + + void setMark(OverviewBar.MarkHandle mh) { + mark = mh; } void setRangeHighlight(boolean highlight) { @@ -106,10 +109,6 @@ abstract class CommentBox extends Composite { } } - GutterWrapper getGutterWrapper() { - return gutterWrapper; - } - CodeMirror getCm() { return group.getCm(); } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentManager.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentManager.java index 6531e385ef..517b5ff34f 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentManager.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/CommentManager.java @@ -157,10 +157,10 @@ class CommentManager { getPatchSetIdFromSide(side), info); group.add(box); - box.setGutterWrapper(host.diffTable.overview.addGutter( + box.setMark(host.diffTable.overview.add( host.getCmFromSide(side), - Math.max(0, info.line() - 1), - OverviewBar.GutterType.COMMENT)); + Math.max(0, info.line() - 1), 1, + OverviewBar.MarkType.COMMENT)); published.put(info.id(), box); } } @@ -220,10 +220,10 @@ class CommentManager { } group.add(box); - box.setGutterWrapper(host.diffTable.overview.addGutter( + box.setMark(host.diffTable.overview.add( host.getCmFromSide(side), - Math.max(0, info.line() - 1), - OverviewBar.GutterType.DRAFT)); + Math.max(0, info.line() - 1), 1, + OverviewBar.MarkType.DRAFT)); return box; } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml index 9a90569856..2c201a7a57 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffTable.ui.xml @@ -58,11 +58,15 @@ limitations under the License. } .table td { padding: 0 } .a, .b { width: 50% } - .overview { width: 10px } - /* Hide left side scrollbar, right side controls both views. */ - .a .CodeMirror-scroll { padding-right: 0; } - .a .CodeMirror-vscrollbar { display: none !important; } + .overview { + width: 10px; + vertical-align: top; + } + + /* Hide scrollbars, OverviewBar controls both views. */ + .difftable .CodeMirror-scroll { padding-right: 0; } + .difftable .CodeMirror-vscrollbar { display: none !important; } .showLineNumbers .b { border-left: none; } .b { border-left: 1px solid #ddd; } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DraftBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DraftBox.java index e4202fcb8f..edc79a5e92 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DraftBox.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DraftBox.java @@ -233,7 +233,7 @@ class DraftBox extends CommentBox { getCommentManager().setUnsaved(this, false); setRangeHighlight(false); clearRange(); - getGutterWrapper().remove(); + getMark().remove(); getCommentGroup().remove(this); getCm().focus(); } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/OverviewBar.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/OverviewBar.java index b21a65a49d..a5df39ef9c 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/OverviewBar.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/OverviewBar.java @@ -15,28 +15,34 @@ package com.google.gerrit.client.diff; import com.google.gwt.core.client.GWT; -import com.google.gwt.core.client.Scheduler; -import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; -import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.event.dom.client.MouseDownEvent; +import com.google.gwt.event.dom.client.MouseMoveEvent; +import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.resources.client.CssResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; +import com.google.gwt.uibinder.client.UiHandler; +import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.Widget; import net.codemirror.lib.CodeMirror; import net.codemirror.lib.LineCharacter; +import net.codemirror.lib.ScrollInfo; import java.util.ArrayList; -import java.util.Iterator; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** Displays overview of all edits and comments in this file. */ -class OverviewBar extends Composite { +class OverviewBar extends Composite implements ClickHandler { interface Binder extends UiBinder {} private static final Binder uiBinder = GWT.create(Binder.class); @@ -47,136 +53,199 @@ class OverviewBar extends Composite { String draft(); String insert(); String delete(); + String viewportDrag(); } - enum GutterType { + enum MarkType { COMMENT, DRAFT, INSERT, DELETE, EDIT } - @UiField - Style style; + @UiField Style style; + @UiField Label viewport; - private List gutters; + private final List diff; + private final Set comments; private CodeMirror cmB; + private boolean dragging; + private int startY; + private double ratio; + OverviewBar() { initWidget(uiBinder.createAndBindUi(this)); - gutters = new ArrayList(); + diff = new ArrayList(); + comments = new HashSet(); + addDomHandler(this, ClickEvent.getType()); } - GutterWrapper addGutter(CodeMirror cm, int line, GutterType type) { - Label gutter = new Label(); - GutterWrapper info = new GutterWrapper(this, gutter, cm, line, type); - adjustGutter(info); - gutter.addStyleName(style.gutter()); + void init(CodeMirror cmB) { + this.cmB = cmB; + } + + void refresh() { + update(cmB.getScrollInfo()); + } + + void update(ScrollInfo si) { + double viewHeight = si.getClientHeight(); + double r = ratio(si); + + com.google.gwt.dom.client.Style style = viewport.getElement().getStyle(); + style.setTop(si.getTop() * r, Unit.PX); + style.setHeight(Math.max(10, viewHeight * r), Unit.PX); + getElement().getStyle().setHeight(viewHeight, Unit.PX); + + for (MarkHandle info : diff) { + info.position(r); + } + for (MarkHandle info : comments) { + info.position(r); + } + } + + @Override + protected void onUnload() { + super.onUnload(); + if (dragging) { + DOM.releaseCapture(viewport.getElement()); + } + } + + @Override + public void onClick(ClickEvent e) { + if (e.getY() < viewport.getElement().getOffsetTop()) { + CodeMirror.handleVimKey(cmB, ""); + } else { + CodeMirror.handleVimKey(cmB, ""); + } + cmB.focus(); + } + + @UiHandler("viewport") + void onMouseDown(MouseDownEvent e) { + if (cmB != null) { + dragging = true; + ratio = ratio(cmB.getScrollInfo()); + startY = e.getY(); + viewport.addStyleName(style.viewportDrag()); + DOM.setCapture(viewport.getElement()); + e.preventDefault(); + e.stopPropagation(); + } + } + + @UiHandler("viewport") + void onMouseMove(MouseMoveEvent e) { + if (dragging) { + int y = e.getRelativeY(getElement()) - startY; + cmB.scrollToY(Math.max(0, y / ratio)); + e.preventDefault(); + e.stopPropagation(); + } + } + + @UiHandler("viewport") + void onMouseUp(MouseUpEvent e) { + if (dragging) { + dragging = false; + DOM.releaseCapture(viewport.getElement()); + viewport.removeStyleName(style.viewportDrag()); + e.preventDefault(); + e.stopPropagation(); + } + } + + private double ratio(ScrollInfo si) { + double barHeight = si.getClientHeight(); + double contentHeight = si.getHeight(); + return barHeight / contentHeight; + } + + MarkHandle add(CodeMirror cm, int line, int height, MarkType type) { + MarkHandle mark = new MarkHandle(cm, line, height); switch (type) { case COMMENT: - gutter.addStyleName(style.comment()); + mark.addStyleName(style.comment()); + comments.add(mark); break; case DRAFT: - gutter.addStyleName(style.draft()); - gutter.setText("*"); + mark.addStyleName(style.draft()); + mark.getElement().setInnerText("*"); + comments.add(mark); break; case INSERT: - gutter.addStyleName(style.insert()); + mark.addStyleName(style.insert()); + diff.add(mark); break; case DELETE: - gutter.addStyleName(style.delete()); + mark.addStyleName(style.delete()); + diff.add(mark); break; case EDIT: - gutter.addStyleName(style.insert()); - Label labelLeft = new Label(); - labelLeft.addStyleName(style.halfGutter()); - gutter.getElement().appendChild(labelLeft.getElement()); + mark.edit = DOM.createDiv(); + mark.edit.setClassName(style.halfGutter()); + mark.getElement().appendChild(mark.edit); + mark.addStyleName(style.insert()); + diff.add(mark); + break; } - ((HTMLPanel) getWidget()).add(gutter); - gutters.add(info); - return info; - } - - void adjustGutters(CodeMirror cmB) { - this.cmB = cmB; - Scheduler.get().scheduleDeferred(new ScheduledCommand() { - @Override - public void execute() { - for (GutterWrapper info : gutters) { - adjustGutter(info); - } - } - }); - } - - private void adjustGutter(GutterWrapper wrapper) { - if (cmB == null) { - return; + if (cmB != null) { + mark.position(ratio(cmB.getScrollInfo())); } - final CodeMirror cm = wrapper.cm; - final int line = wrapper.line; - Label gutter = wrapper.gutter; - final double height = cm.heightAtLine(line, "local"); - final double scrollbarHeight = cmB.getScrollbarV().getClientHeight(); - double top = height / cmB.getSizer().getClientHeight() * - scrollbarHeight + - cmB.getScrollbarV().getAbsoluteTop(); - if (top == 0) { - top = -10; + ((HTMLPanel) getWidget()).add(mark); + return mark; + } + + void clearDiffMarkers() { + for (MarkHandle mark : diff) { + mark.removeFromParent(); } - gutter.getElement().getStyle().setTop(top, Unit.PX); - wrapper.replaceClickHandler(new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - cm.setCursor(LineCharacter.create(line)); - cm.scrollToY(height - 0.5 * scrollbarHeight); - cm.focus(); - } - }); + diff.clear(); } - void removeGutter(GutterWrapper wrapper) { - gutters.remove(wrapper); - } + class MarkHandle extends Widget implements ClickHandler { + private static final int MIN_HEIGHT = 3; - @SuppressWarnings("incomplete-switch") - void clearDiffGutters() { - for (Iterator i = gutters.iterator(); i.hasNext();) { - GutterWrapper wrapper = i.next(); - switch (wrapper.type) { - case INSERT: - case DELETE: - case EDIT: - wrapper.gutter.removeFromParent(); - i.remove(); - } - } - } + private final CodeMirror cm; + private final int line; + private final int height; + private Element edit; - static class GutterWrapper { - private OverviewBar host; - private Label gutter; - private CodeMirror cm; - private int line; - private HandlerRegistration regClick; - private GutterType type; - - GutterWrapper(OverviewBar host, Label anchor, CodeMirror cm, int line, - GutterType type) { - this.host = host; - this.gutter = anchor; + MarkHandle(CodeMirror cm, int line, int height) { this.cm = cm; this.line = line; - this.type = type; + this.height = height; + + setElement(DOM.createDiv()); + setStyleName(style.gutter()); + addDomHandler(this, ClickEvent.getType()); } - private void replaceClickHandler(ClickHandler newHandler) { - if (regClick != null) { - regClick.removeHandler(); + void position(double ratio) { + double y = cm.heightAtLine(line, "local"); + getElement().getStyle().setTop(y * ratio, Unit.PX); + if (height > 1) { + double e = cm.heightAtLine(line + height, "local"); + double h = Math.max(MIN_HEIGHT, (e - y) * ratio); + getElement().getStyle().setHeight(h, Unit.PX); + if (edit != null) { + edit.getStyle().setHeight(h, Unit.PX); + } } - regClick = gutter.addClickHandler(newHandler); + } + + @Override + public void onClick(ClickEvent event) { + double y = cm.heightAtLine(line, "local"); + double viewport = cm.getScrollInfo().getClientHeight(); + cm.setCursor(LineCharacter.create(line)); + cm.scrollToY(y - 0.5 * viewport); + cm.focus(); } void remove() { - gutter.removeFromParent(); - host.removeGutter(this); + removeFromParent(); + comments.remove(this); } } } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/OverviewBar.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/OverviewBar.ui.xml index bc693f55b4..a56c3da859 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/OverviewBar.ui.xml +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/OverviewBar.ui.xml @@ -17,22 +17,27 @@ limitations under the License. + .overview { + position: relative; + } .gutter { cursor: pointer; - position: fixed; + position: absolute; height: 3px; - width: 10px; - border: 1px solid black; + width: 6px; + border: 1px solid grey; + margin-left: 1px; } .halfGutter { cursor: pointer; - position: fixed; + position: absolute; height: 3px; - width: 5px; + width: 3px; background-color: #faa; } .comment, .draft { - background-color: #e5ecf9; + background-color: #fcfa96; + z-index: 2; } .draft { text-align: center; @@ -47,6 +52,20 @@ limitations under the License. .insert { background-color: #9f9; } + .viewport { + position: absolute; + background-color: rgba(128, 128, 128, 0.50); + border: 1px solid #444; + width: 8px; + cursor: default; + z-index: 3; + border-radius: 4px; + } + .viewportDrag { + cursor: move; + } - - \ No newline at end of file + + + + diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/ScrollSynchronizer.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/ScrollSynchronizer.java index 85f2c9348f..ba742025a9 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/ScrollSynchronizer.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/ScrollSynchronizer.java @@ -22,6 +22,7 @@ import net.codemirror.lib.ScrollInfo; class ScrollSynchronizer { private DiffTable diffTable; private LineMapper mapper; + private OverviewBar overview; private ScrollCallback active; ScrollSynchronizer(DiffTable diffTable, @@ -29,6 +30,7 @@ class ScrollSynchronizer { LineMapper mapper) { this.diffTable = diffTable; this.mapper = mapper; + this.overview = diffTable.overview; cmA.on("scroll", new ScrollCallback(cmA, cmB, DisplaySide.A)); cmB.on("scroll", new ScrollCallback(cmB, cmA, DisplaySide.B)); @@ -73,6 +75,7 @@ class ScrollSynchronizer { if (active == this) { ScrollInfo si = src.getScrollInfo(); updateScreenHeader(si); + overview.update(si); dst.scrollTo(si.getLeft(), align(si.getTop())); state = 0; } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java index ebc767b56b..59523551e8 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java @@ -64,7 +64,6 @@ import net.codemirror.lib.CodeMirror.BeforeSelectionChangeHandler; import net.codemirror.lib.CodeMirror.GutterClickHandler; import net.codemirror.lib.CodeMirror.LineClassWhere; import net.codemirror.lib.CodeMirror.LineHandle; -import net.codemirror.lib.CodeMirror.Viewport; import net.codemirror.lib.Configuration; import net.codemirror.lib.KeyMap; import net.codemirror.lib.LineCharacter; @@ -228,7 +227,7 @@ public class SideBySide2 extends Screen { } }); setLineLength(prefs.lineLength()); - diffTable.overview.adjustGutters(cmB); + diffTable.overview.refresh(); if (startLine == 0 && diff.meta_b() != null) { DiffChunkInfo d = chunkManager.getFirst(); @@ -294,7 +293,6 @@ public class SideBySide2 extends Screen { cm.on("beforeSelectionChange", onSelectionChange(cm)); cm.on("cursorActivity", updateActiveLine(cm)); cm.on("gutterClick", onGutterClick(cm)); - cm.on("viewportChange", adjustGutters(cm)); cm.on("focus", updateActiveLine(cm)); cm.addKeyMap(KeyMap.create() .on("'a'", upToChange(true)) @@ -466,6 +464,7 @@ public class SideBySide2 extends Screen { cmA = newCM(diff.meta_a(), diff.text_a(), DisplaySide.A, diffTable.cmA); cmB = newCM(diff.meta_b(), diff.text_b(), DisplaySide.B, diffTable.cmB); + diffTable.overview.init(cmB); chunkManager = new ChunkManager(this, cmA, cmB, diffTable.overview); skipManager = new SkipManager(this, commentManager); @@ -606,6 +605,7 @@ public class SideBySide2 extends Screen { public void run() { skipManager.removeAll(); skipManager.render(context, diff); + diffTable.overview.refresh(); } }); } @@ -636,21 +636,6 @@ public class SideBySide2 extends Screen { } } - private Runnable adjustGutters(final CodeMirror cm) { - return new Runnable() { - @Override - public void run() { - Viewport fromTo = cm.getViewport(); - int size = fromTo.getTo() - fromTo.getFrom() + 1; - if (cm.getOldViewportSize() == size) { - return; - } - cm.setOldViewportSize(size); - diffTable.overview.adjustGutters(cmB); - } - }; - } - private Runnable updateActiveLine(final CodeMirror cm) { final CodeMirror other = otherCm(cm); return new Runnable() { @@ -789,7 +774,7 @@ public class SideBySide2 extends Screen { int height = getCodeMirrorHeight(); cmA.setHeight(height); cmB.setHeight(height); - diffTable.overview.adjustGutters(cmB); + diffTable.overview.refresh(); } private int getCodeMirrorHeight() { @@ -886,7 +871,7 @@ public class SideBySide2 extends Screen { public void run() { skipManager.removeAll(); chunkManager.reset(); - diffTable.overview.clearDiffGutters(); + diffTable.overview.clearDiffMarkers(); setShowIntraline(prefs.intralineDifference()); render(diff); skipManager.render(prefs.context(), diff); diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.ui.xml index 1bc707a3a5..8c26873403 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.ui.xml +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.ui.xml @@ -17,7 +17,13 @@ limitations under the License. - + + .sbs2 { + margin-left: -5px; + margin-right: -5px; + } + + diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SkipBar.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SkipBar.java index 265bb3e78b..351f02680b 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SkipBar.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SkipBar.java @@ -132,6 +132,7 @@ class SkipBar extends Composite { void expandBefore(int cnt) { expandSideBefore(cnt); otherBar.expandSideBefore(cnt); + manager.getOverviewBar().refresh(); } private void expandSideBefore(int cnt) { @@ -183,6 +184,7 @@ class SkipBar extends Composite { expandSideAll(); otherBar.expandSideAll(); manager.remove(this, otherBar); + manager.getOverviewBar().refresh(); } @UiHandler("upArrow") @@ -195,6 +197,7 @@ class SkipBar extends Composite { void onExpandAfter(ClickEvent e) { expandAfter(); otherBar.expandAfter(); + manager.getOverviewBar().refresh(); cm.focus(); } } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SkipManager.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SkipManager.java index 1e8c1ca20a..d55f625f01 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SkipManager.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SkipManager.java @@ -38,6 +38,10 @@ class SkipManager { this.commentManager = commentManager; } + OverviewBar getOverviewBar() { + return host.diffTable.overview; + } + void render(int context, DiffInfo diff) { if (context == AccountDiffPreference.WHOLE_FILE_CONTEXT) { return; @@ -106,6 +110,7 @@ class SkipManager { for (SkipBar bar : skipBars) { bar.expandSideAll(); } + getOverviewBar().refresh(); skipBars = null; line0 = null; } diff --git a/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java b/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java index 16150752c1..c0247c6618 100644 --- a/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java +++ b/gerrit-gwtui/src/main/java/net/codemirror/lib/CodeMirror.java @@ -168,14 +168,6 @@ public class CodeMirror extends JavaScriptObject { return this.getViewport(); }-*/; - public final native int getOldViewportSize() /*-{ - return this.state.oldViewportSize || 0; - }-*/; - - public final native void setOldViewportSize(int lines) /*-{ - this.state.oldViewportSize = lines; - }-*/; - public final native void operation(Runnable thunk) /*-{ this.operation(function() { thunk.@java.lang.Runnable::run()(); diff --git a/gerrit-gwtui/src/main/java/net/codemirror/lib/ScrollInfo.java b/gerrit-gwtui/src/main/java/net/codemirror/lib/ScrollInfo.java index 06394166cb..096f1adcf8 100644 --- a/gerrit-gwtui/src/main/java/net/codemirror/lib/ScrollInfo.java +++ b/gerrit-gwtui/src/main/java/net/codemirror/lib/ScrollInfo.java @@ -16,19 +16,22 @@ package net.codemirror.lib; import com.google.gwt.core.client.JavaScriptObject; -/** {left, top, width, height, clientWidth, clientHeight} objects returned by - * getScrollInfo(). */ +/** Returned by {@link CodeMirror#getScrollInfo()}. */ public class ScrollInfo extends JavaScriptObject { - public static ScrollInfo create() { - return createObject().cast(); - } - public final native double getLeft() /*-{ return this.left; }-*/; public final native double getTop() /*-{ return this.top; }-*/; - public final native double getWidth() /*-{ return this.width; }-*/; + + /** + * Pixel height of the full content being scrolled. This may only be an + * estimate given by CodeMirror. Line widgets further down in the document may + * not be measured, so line heights can be incorrect until drawn. + */ public final native double getHeight() /*-{ return this.height; }-*/; - public final native double getClientWidth() /*-{ return this.clientWidth; }-*/; + public final native double getWidth() /*-{ return this.width; }-*/; + + /** Visible height of the viewport, excluding scrollbars. */ public final native double getClientHeight() /*-{ return this.clientHeight; }-*/; + public final native double getClientWidth() /*-{ return this.clientWidth; }-*/; protected ScrollInfo() { }