devexpress-richedit
Version:
DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.
107 lines (106 loc) • 5.1 kB
JavaScript
import { DocumentLayoutDetailsLevel } from '../layout/document-layout-details-level';
import { MouseHandler } from '../mouse-handler/mouse-handler/mouse-handler';
import { RelativePosition } from '../scroll/model-states';
import { MixedSize } from '../utils/mixed-size';
import { ModelChangeType } from '../model/changes/enums';
export class CanvasScrollManager {
updateScrollTimeoutId = null;
waitForDblClickTimeoutId = null;
horizontalRuler;
viewManager;
get canvas() { return this.viewManager.canvas; }
get sizes() { return this.viewManager.sizes; }
constructor(viewManager, horizontalRuler) {
this.viewManager = viewManager;
this.horizontalRuler = horizontalRuler;
}
dispose() {
clearTimeout(this.updateScrollTimeoutId);
clearTimeout(this.waitForDblClickTimeoutId);
}
modelChanged(change) {
if (change.type == ModelChangeType.ZoomLevelChanged)
this.updateScrollVisibility();
}
get scrollTop() { return this.canvas.scrollTop; }
set scrollTop(val) { this.canvas.scrollTop = val; }
setScrollEnabled(enabled) {
if (enabled)
this.canvas.style.overflow = "";
else
this.canvas.style.overflow = "hidden";
this.updateScrollVisibility();
}
updateScrollVisibility() {
const prevScrollYVisibility = this.sizes.scrollYVisible;
this.sizes.updateScrollVisibility(this.canvas);
if (prevScrollYVisibility !== this.sizes.scrollYVisible && this.horizontalRuler)
this.horizontalRuler.adjust();
}
scrollToX(canvasState) {
const position = canvasState.lp;
const relativePosition = canvasState.relativePosition;
const zoomLevel = this.viewManager.zoomLevel;
const page = this.viewManager.layout.pages[position.pageIndex];
let y = MixedSize.fromLayout(this.sizes.getPageOffsetY(page)).useScale(zoomLevel);
let height = new MixedSize().useScale(zoomLevel);
if (position.detailsLevel >= DocumentLayoutDetailsLevel.PageArea) {
y.addLayoutSize(position.pageArea.y);
if (position.detailsLevel >= DocumentLayoutDetailsLevel.Column) {
y.addLayoutSize(position.column.y);
if (position.detailsLevel >= DocumentLayoutDetailsLevel.Row) {
y.addLayoutSize(position.row.y);
if (relativePosition === RelativePosition.Bottom)
y.addLayoutSize(position.row.height);
else if (relativePosition === RelativePosition.Inside)
height.clear().addLayoutSize(position.row.height);
}
else if (relativePosition === RelativePosition.Bottom)
y.addLayoutSize(position.column.height);
else if (relativePosition === RelativePosition.Inside)
height.clear().addLayoutSize(position.column.height);
}
else if (relativePosition === RelativePosition.Bottom)
y.addLayoutSize(position.pageArea.height);
else if (relativePosition === RelativePosition.Inside)
height.clear().addLayoutSize(position.pageArea.height);
}
else if (relativePosition === RelativePosition.Bottom)
y.addLayoutSize(position.page.height);
else if (relativePosition === RelativePosition.Inside)
height.clear().addLayoutSize(position.page.height);
if (relativePosition === RelativePosition.Bottom)
y.subtractUISize(this.sizes.getVisibleAreaHeight(false));
y.addLayoutSize(canvasState.getVerticalOffset(this.sizes));
if (relativePosition === RelativePosition.Inside) {
let scrollTop = this.canvas.scrollTop;
const scrollVisibleAreaHeight = this.sizes.getVisibleAreaHeight(false);
if (y.UISize < scrollTop)
this.canvas.scrollTop = y.UISize;
else if (y.UISize + height.UISize > scrollVisibleAreaHeight + scrollTop)
this.canvas.scrollTop = y.UISize + height.UISize - scrollVisibleAreaHeight;
}
else
this.canvas.scrollTop = y.UISize;
}
NotifyScrollPositionChanged(canvasState) {
if (this.updateScrollTimeoutId) {
clearTimeout(this.updateScrollTimeoutId);
this.updateScrollTimeoutId = null;
}
if (this.waitForDblClickTimeoutId > 0) {
this.updateScrollTimeoutId = setTimeout(() => {
this.scrollToX(canvasState);
}, MouseHandler.WAIT_FOR_DBLCLICK_INTERVAL);
}
else
this.scrollToX(canvasState);
}
waitForDblClick() {
if (this.waitForDblClickTimeoutId)
clearTimeout(this.waitForDblClickTimeoutId);
this.waitForDblClickTimeoutId = setTimeout(() => {
this.waitForDblClickTimeoutId = null;
}, MouseHandler.WAIT_FOR_DBLCLICK_INTERVAL);
}
}