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
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -233,7 +233,7 @@ class DraftBox extends CommentBox {
|
||||
getCommentManager().setUnsaved(this, false);
|
||||
setRangeHighlight(false);
|
||||
clearRange();
|
||||
getGutterWrapper().remove();
|
||||
getMark().remove();
|
||||
getCommentGroup().remove(this);
|
||||
getCm().focus();
|
||||
}
|
||||
|
||||
@@ -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<HTMLPanel, OverviewBar> {}
|
||||
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<GutterWrapper> gutters;
|
||||
private final List<MarkHandle> diff;
|
||||
private final Set<MarkHandle> comments;
|
||||
private CodeMirror cmB;
|
||||
|
||||
private boolean dragging;
|
||||
private int startY;
|
||||
private double ratio;
|
||||
|
||||
OverviewBar() {
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
gutters = new ArrayList<GutterWrapper>();
|
||||
diff = new ArrayList<MarkHandle>();
|
||||
comments = new HashSet<MarkHandle>();
|
||||
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, "<PageUp>");
|
||||
} else {
|
||||
CodeMirror.handleVimKey(cmB, "<PageDown>");
|
||||
}
|
||||
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;
|
||||
if (cmB != null) {
|
||||
mark.position(ratio(cmB.getScrollInfo()));
|
||||
}
|
||||
((HTMLPanel) getWidget()).add(mark);
|
||||
return mark;
|
||||
}
|
||||
|
||||
void adjustGutters(CodeMirror cmB) {
|
||||
this.cmB = cmB;
|
||||
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
|
||||
@Override
|
||||
public void execute() {
|
||||
for (GutterWrapper info : gutters) {
|
||||
adjustGutter(info);
|
||||
void clearDiffMarkers() {
|
||||
for (MarkHandle mark : diff) {
|
||||
mark.removeFromParent();
|
||||
}
|
||||
}
|
||||
});
|
||||
diff.clear();
|
||||
}
|
||||
|
||||
private void adjustGutter(GutterWrapper wrapper) {
|
||||
if (cmB == null) {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
class MarkHandle extends Widget implements ClickHandler {
|
||||
private static final int MIN_HEIGHT = 3;
|
||||
|
||||
void removeGutter(GutterWrapper wrapper) {
|
||||
gutters.remove(wrapper);
|
||||
}
|
||||
private final CodeMirror cm;
|
||||
private final int line;
|
||||
private final int height;
|
||||
private Element edit;
|
||||
|
||||
@SuppressWarnings("incomplete-switch")
|
||||
void clearDiffGutters() {
|
||||
for (Iterator<GutterWrapper> i = gutters.iterator(); i.hasNext();) {
|
||||
GutterWrapper wrapper = i.next();
|
||||
switch (wrapper.type) {
|
||||
case INSERT:
|
||||
case DELETE:
|
||||
case EDIT:
|
||||
wrapper.gutter.removeFromParent();
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,22 +17,27 @@ limitations under the License.
|
||||
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
|
||||
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
|
||||
<ui:style type='com.google.gerrit.client.diff.OverviewBar.Style'>
|
||||
.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;
|
||||
}
|
||||
</ui:style>
|
||||
<g:HTMLPanel/>
|
||||
<g:HTMLPanel styleName='{style.overview}'>
|
||||
<g:Label ui:field='viewport' styleName='{style.viewport}'/>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -17,7 +17,13 @@ limitations under the License.
|
||||
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
|
||||
xmlns:g='urn:import:com.google.gwt.user.client.ui'
|
||||
xmlns:d='urn:import:com.google.gerrit.client.diff'>
|
||||
<g:FlowPanel>
|
||||
<ui:style>
|
||||
.sbs2 {
|
||||
margin-left: -5px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
</ui:style>
|
||||
<g:FlowPanel styleName='{style.sbs2}'>
|
||||
<d:Header ui:field='header'/>
|
||||
<d:DiffTable ui:field='diffTable'/>
|
||||
</g:FlowPanel>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()();
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user