1 | import {BeanStub} from "../context/beanStub";
|
2 | import {Autowired, Bean, PostConstruct} from "../context/context";
|
3 | import {EventService} from "../eventService";
|
4 | import {Events} from "../eventKeys";
|
5 | import {GridPanel} from "../gridPanel/gridPanel";
|
6 | import {_} from "../utils";
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | @Bean('heightScaler')
|
14 | export class HeightScaler extends BeanStub {
|
15 |
|
16 | @Autowired('eventService') private eventService: EventService;
|
17 |
|
18 | private gridPanel: GridPanel;
|
19 |
|
20 | private maxDivHeight: number;
|
21 |
|
22 |
|
23 |
|
24 |
|
25 | private scaling: boolean;
|
26 |
|
27 | private modelHeight: number;
|
28 | private uiContainerHeight: number;
|
29 | private pixelsToShave: number;
|
30 |
|
31 |
|
32 | private offset: number;
|
33 |
|
34 |
|
35 | private scrollY = 0;
|
36 |
|
37 | private uiBodyHeight = 0;
|
38 |
|
39 |
|
40 | private maxScrollY: number;
|
41 |
|
42 |
|
43 | private scrollBarWidth: number;
|
44 |
|
45 | @PostConstruct
|
46 | private postConstruct(): void {
|
47 | this.addDestroyableEventListener(this.eventService, Events.EVENT_BODY_HEIGHT_CHANGED, this.update.bind(this));
|
48 | this.scrollBarWidth = _.getScrollbarWidth();
|
49 | this.maxDivHeight = _.getMaxDivHeight();
|
50 | }
|
51 |
|
52 | public registerGridComp(gridPanel: GridPanel): void {
|
53 | this.gridPanel = gridPanel;
|
54 | }
|
55 |
|
56 | public isScaling(): boolean {
|
57 | return this.scaling;
|
58 | }
|
59 |
|
60 | public getOffset(): number {
|
61 | return this.offset;
|
62 | }
|
63 |
|
64 | public update(): void {
|
65 | if (!this.scaling) { return; }
|
66 |
|
67 | let newScrollY = this.gridPanel.getVScrollPosition().top;
|
68 | let newBodyHeight = this.getUiBodyHeight();
|
69 |
|
70 | let atLeastOneChanged = newScrollY!==this.scrollY || newBodyHeight!==this.uiBodyHeight;
|
71 | if (atLeastOneChanged) {
|
72 | this.scrollY = newScrollY;
|
73 | this.uiBodyHeight = newBodyHeight;
|
74 | this.calculateOffset();
|
75 | }
|
76 | }
|
77 |
|
78 | private calculateOffset(): void {
|
79 | this.uiContainerHeight = this.maxDivHeight;
|
80 | this.pixelsToShave = this.modelHeight - this.uiContainerHeight;
|
81 |
|
82 | this.maxScrollY = this.uiContainerHeight - this.uiBodyHeight;
|
83 | let scrollPercent = this.scrollY / this.maxScrollY;
|
84 |
|
85 | this.setOffset(scrollPercent * this.pixelsToShave);
|
86 | }
|
87 |
|
88 | private clearOffset(): void {
|
89 | this.uiContainerHeight = this.modelHeight;
|
90 | this.pixelsToShave = 0;
|
91 |
|
92 | this.setOffset(0);
|
93 | }
|
94 |
|
95 | private setOffset(newOffset: number): void {
|
96 |
|
97 | let newOffsetFloor = typeof newOffset === 'number' ? Math.floor(newOffset) : null;
|
98 | if (this.offset!==newOffsetFloor) {
|
99 | this.offset = newOffsetFloor;
|
100 | this.eventService.dispatchEvent({type: Events.EVENT_HEIGHT_SCALE_CHANGED});
|
101 | }
|
102 | }
|
103 |
|
104 | public setModelHeight(modelHeight: number): void {
|
105 | this.modelHeight = modelHeight;
|
106 | this.scaling = this.maxDivHeight > 0 && modelHeight > this.maxDivHeight;
|
107 | if (this.scaling) {
|
108 | this.calculateOffset();
|
109 | } else {
|
110 | this.clearOffset();
|
111 | }
|
112 | }
|
113 |
|
114 | public getUiContainerHeight(): number {
|
115 | return this.uiContainerHeight;
|
116 | }
|
117 |
|
118 | public getRealPixelPosition(modelPixel: number): number {
|
119 | let uiPixel = modelPixel - this.offset;
|
120 | return uiPixel;
|
121 | }
|
122 |
|
123 | private getUiBodyHeight(): number {
|
124 | let pos = this.gridPanel.getVScrollPosition();
|
125 | let bodyHeight = pos.bottom - pos.top;
|
126 | if (this.gridPanel.isHorizontalScrollShowing()) {
|
127 | bodyHeight -= this.scrollBarWidth;
|
128 | }
|
129 | return bodyHeight;
|
130 | }
|
131 |
|
132 | public getScrollPositionForPixel(rowTop: number): number {
|
133 | if (this.pixelsToShave<=0) {
|
134 | return rowTop;
|
135 | } else {
|
136 | let modelMaxScroll = this.modelHeight - this.getUiBodyHeight();
|
137 | let scrollPercent = rowTop / modelMaxScroll;
|
138 | let scrollPixel = this.maxScrollY * scrollPercent;
|
139 | return scrollPixel;
|
140 | }
|
141 | }
|
142 | } |
\ | No newline at end of file |