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.thumbnaillayout.widget;
35
36 import com.google.gwt.dom.client.Element;
37 import com.google.gwt.dom.client.ImageElement;
38 import com.google.gwt.dom.client.Node;
39 import com.google.gwt.dom.client.Style;
40 import com.google.gwt.user.client.DOM;
41 import com.vaadin.client.ComputedStyle;
42
43
44
45
46
47 class ThumbnailsSizeKeeper {
48
49 private static final int MAX_SIZE = 250;
50
51 private int calculatedWidth;
52
53 private int calculatedHeight;
54
55 private int baseWidth;
56
57 private int baseHeight;
58
59 private Element thumbnailParent;
60
61 private float ratio;
62
63 private int unscaledWidth;
64
65 private int unscaledHeight;
66 private int verticalDecorations;
67 private int horizontalDecorations;
68
69 ThumbnailsSizeKeeper(Element thumbnailParent) {
70 this.thumbnailParent = thumbnailParent;
71 }
72
73 void scale(float ratio) {
74 this.ratio = ratio;
75 updateCalculatedOffsetSizes();
76 doUpdateAllThumbnailsSize(calculatedWidth, calculatedHeight);
77 }
78
79 public void scaleToWidth(int width) {
80 int targetWidth = Math.min(width, MAX_SIZE);
81 if (baseWidth < MAX_SIZE) {
82 scale((float)(targetWidth - unscaledWidth) / (MAX_SIZE - baseWidth));
83 }
84 }
85
86 int height() {
87 return this.calculatedHeight + verticalDecorations;
88 }
89
90 int width() {
91 return this.calculatedWidth + horizontalDecorations;
92 }
93
94 boolean updateAllThumbnailsSize(int width, int height) {
95 if (this.baseHeight != height || this.baseWidth != width) {
96 this.baseHeight = height;
97 this.baseWidth = width;
98
99 doUpdateAllThumbnailsSize(width, height);
100 updateCalculatedOffsetSizes();
101 return true;
102 }
103
104 return false;
105 }
106
107 void applySizeToThumbnail(Element thumbnail) {
108 doSetThumbnailSize(scaleDimension(baseWidth, ratio), scaleDimension(baseHeight, ratio), thumbnail);
109 }
110
111 private int scaleDimension(int minValue, double ratio) {
112 if (minValue == MAX_SIZE) {
113 return MAX_SIZE;
114 }
115 return (int) ((MAX_SIZE - minValue) * ratio + minValue);
116 }
117
118 private void doUpdateAllThumbnailsSize(int width, int height) {
119 Node element = thumbnailParent.getFirstChildElement();
120 while (element != null) {
121 doSetThumbnailSize(width, height, Element.as(element));
122 element = element.getNextSibling();
123 }
124 }
125
126 private void doSetThumbnailSize(int width, int height, Element element) {
127 final Style style = element.getStyle();
128 style.setFontSize(width * 0.75d, Style.Unit.PX);
129 style.setWidth(width, Style.Unit.PX);
130 style.setHeight(height, Style.Unit.PX);
131
132 Style imageStyle = element.getElementsByTagName(ImageElement.TAG).getItem(0).getStyle();
133 imageStyle.setProperty("maxWidth", width + "px");
134 imageStyle.setProperty("maxHeight", height + "px");
135 }
136
137 private void updateCalculatedOffsetSizes() {
138 ComputedStyle cs;
139
140 int[] padding;
141 int[] border;
142 int[] margin;
143
144 if (thumbnailParent.getChildCount() > 0) {
145 final Element firstThumbnail = Element.as(thumbnailParent.getFirstChild());
146 cs = new ComputedStyle(firstThumbnail);
147
148 padding = cs.getPadding();
149 border = cs.getBorder();
150 margin = cs.getMargin();
151 } else {
152 final Element stub = Element.as(DOM.createDiv());
153 stub.addClassName("thumbnail");
154 thumbnailParent.appendChild(stub);
155 cs = new ComputedStyle(stub);
156 padding = cs.getPadding();
157 border = cs.getBorder();
158 margin = cs.getMargin();
159
160 thumbnailParent.removeChild(stub);
161 }
162
163
164 horizontalDecorations = padding[1] + padding[3] + border[1] + border[3] + margin[1] + margin[3];
165 verticalDecorations = padding[0] + padding[2] + border[0] + border[2] + margin[0] + margin[2];
166
167 this.unscaledWidth = baseWidth + horizontalDecorations;
168 this.unscaledHeight = baseHeight + verticalDecorations;
169
170 this.calculatedWidth = scaleDimension(baseWidth, ratio);
171 this.calculatedHeight = scaleDimension(baseHeight, ratio);
172
173 }
174
175 float getScaleRatio() {
176 return ratio;
177 }
178
179 int getUnscaledWidth() {
180 return unscaledWidth;
181 }
182
183 int getUnscaledHeight() {
184 return unscaledHeight;
185 }
186 }