1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.vaadin.gwt.client.layout.lazylayout.widget;
35
36 import com.google.gwt.dom.client.Element;
37 import com.google.gwt.dom.client.Node;
38 import com.google.gwt.dom.client.Style;
39 import com.google.gwt.user.client.DOM;
40 import com.vaadin.client.ComputedStyle;
41
42
43
44
45
46
47 public class ThumbnailsSizeKeeper {
48
49 private static final int MAX_WIDTH = 260;
50 private static final int MAX_HEIGHT = 208;
51
52 private int calculatedWidth;
53
54 private int calculatedHeight;
55
56 private int baseWidth;
57
58 private int baseHeight;
59
60 private Element elementsParent;
61
62 private float ratio;
63
64 private int unscaledWidth;
65
66 private int unscaledHeight;
67 private int verticalDecorations;
68 private int horizontalDecorations;
69
70 ThumbnailsSizeKeeper(Element elementsParent) {
71 this.elementsParent = elementsParent;
72 }
73
74 public void scale(float ratio) {
75 this.ratio = ratio;
76 updateCalculatedOffsetSizes();
77 doUpdateAllElementsSize(calculatedWidth, calculatedHeight);
78 }
79
80 void scaleToWidth(int width) {
81 scale((float)(width - unscaledWidth) / (maxWidth() - baseWidth));
82 }
83
84 int height() {
85 return this.calculatedHeight;
86 }
87
88 int width() {
89 return this.calculatedWidth;
90 }
91
92
93
94
95 int maxWidth() {
96 int tiles = (int) Math.round((double) this.elementsParent.getOffsetWidth() / MAX_WIDTH);
97 return elementsParent.getOffsetWidth() / tiles;
98 }
99
100 boolean updateAllElementsSize(int width, int height) {
101 if (this.baseHeight != height || this.baseWidth != width) {
102 this.baseHeight = height;
103 this.baseWidth = width;
104
105 doUpdateAllElementsSize(width, height);
106 updateCalculatedOffsetSizes();
107 return true;
108 }
109
110 return false;
111 }
112
113 void applySizeToElement(Element element) {
114 int scaledWidth = scaleWidth(baseWidth, ratio);
115 doSetElementSize(scaledWidth, (int) Math.round((double) scaledWidth * MAX_HEIGHT / MAX_WIDTH), element);
116 }
117
118 private int scaleWidth(int minValue, double ratio) {
119 long scaledWidth = Math.round((maxWidth() - minValue) * ratio + minValue);
120 return (int) Math.min(scaledWidth, maxWidth());
121 }
122
123 private void doUpdateAllElementsSize(int width, int height) {
124 Node element = elementsParent.getFirstChildElement();
125 while (element != null) {
126 doSetElementSize(width, height, Element.as(element));
127 element = element.getNextSibling();
128 }
129 }
130
131 private void doSetElementSize(int width, int height, Element element) {
132 final Style style = element.getStyle();
133 style.setFontSize(width * 0.75d, Style.Unit.PX);
134 style.setWidth(width, Style.Unit.PX);
135 style.setHeight(height, Style.Unit.PX);
136
137 addOrRemoveClass(height <= 155, "caption-hidden", element);
138 }
139
140 private void addOrRemoveClass(boolean addClass, String className, Element element) {
141 if (addClass) {
142 element.addClassName(className);
143 } else {
144 element.removeClassName(className);
145 }
146 }
147
148 private void updateCalculatedOffsetSizes() {
149 ComputedStyle cs;
150
151 int[] padding;
152 int[] border;
153 int[] margin;
154
155 if (elementsParent.getChildCount() > 0) {
156 final Element firstElement = Element.as(elementsParent.getFirstChild());
157 cs = new ComputedStyle(firstElement);
158
159 padding = cs.getPadding();
160 border = cs.getBorder();
161 margin = cs.getMargin();
162 } else {
163 final Element stub = Element.as(DOM.createDiv());
164 stub.addClassName("thumbnail");
165 elementsParent.appendChild(stub);
166 cs = new ComputedStyle(stub);
167 padding = cs.getPadding();
168 border = cs.getBorder();
169 margin = cs.getMargin();
170
171 elementsParent.removeChild(stub);
172 }
173
174 horizontalDecorations = padding[1] + padding[3] + border[1] + border[3] + margin[1] + margin[3];
175 verticalDecorations = padding[0] + padding[2] + border[0] + border[2] + margin[0] + margin[2];
176
177 this.unscaledWidth = baseWidth + horizontalDecorations;
178 this.unscaledHeight = baseHeight + verticalDecorations;
179
180 this.calculatedWidth = scaleWidth(baseWidth, ratio);
181 this.calculatedHeight = (int) Math.round((double) this.calculatedWidth * MAX_HEIGHT / MAX_WIDTH);
182
183 }
184
185 public float getScaleRatio() {
186 return ratio;
187 }
188
189 public int getUnscaledWidth() {
190 return unscaledWidth;
191 }
192
193 public int getUnscaledHeight() {
194 return unscaledHeight;
195 }
196
197 void setElementsParent(Element elementsParent) {
198 this.elementsParent = elementsParent;
199 }
200 }