|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 /** Helpers for controls embedded in forms or setting item lists */ |
|
20 |
|
21 var DRAW_BOUNDING_RECTS = false; |
|
22 |
|
23 include("formLibrary.js") |
|
24 include("settingsListLibrary.js") |
|
25 include("transient/popupDialogLibrary.js") |
|
26 |
|
27 /** |
|
28 * Implement IVisualAppearance routines with form/setting item support. |
|
29 * This automatically handles reducing the content area for |
|
30 * a component when it is displayed in a form/setting item list |
|
31 * and returning a preferred size. |
|
32 * |
|
33 * @param prototype the prototype to modify<p> |
|
34 * This must provide these routines: <br> |
|
35 * <p> |
|
36 * drawContent(instance, laf, graphics, rect) <br> |
|
37 * Draw content into 'rect' (x, y are 0 and GC is shifted) <br> |
|
38 *<p> |
|
39 * getContentSize(instance, laf, size) <br> |
|
40 * Get the required size of the content, given the nominal constraints |
|
41 * in 'size'. For instance, a text field may increase the height |
|
42 * due to wrapping.<p> |
|
43 * The content bounds calculation is usually independent of whether the |
|
44 * parent is a form, unless the rendering is significantly |
|
45 * different. The calculation <i>is</i> different for a setting |
|
46 * item list, which uses a different font. Returns a Point. <br> |
|
47 */ |
|
48 function setupEmbeddedRendering(prototype) { |
|
49 prototype.draw = function(instance, laf, graphics) { |
|
50 var properties = instance.properties; |
|
51 if (isForm(instance.parent)) { |
|
52 var rects = getFormItemRectangles(instance, laf); |
|
53 var promptRect = rects[FORM_PROMPT_RECT_INDEX]; |
|
54 var contentRect = rects[FORM_CONTENT_RECT_INDEX]; |
|
55 |
|
56 drawFormPrompt(prototype, instance, laf, graphics, rects); |
|
57 if (DRAW_BOUNDING_RECTS) { |
|
58 graphics.setForeground(Colors.getColor(255, 0, 0)); |
|
59 graphics.setXORMode(true); |
|
60 graphics.drawRectangle(promptRect.x, promptRect.y, promptRect.width-1, promptRect.height-1 ); |
|
61 graphics.setXORMode(false); |
|
62 } |
|
63 |
|
64 var oldX = graphics.getOffX(); |
|
65 var oldY = graphics.getOffY(); |
|
66 graphics.setOffX(contentRect.x); |
|
67 graphics.setOffY(contentRect.y); |
|
68 contentRect.x = 0; |
|
69 contentRect.y = 0; |
|
70 this.drawContent(instance, laf, graphics, contentRect); |
|
71 |
|
72 if (DRAW_BOUNDING_RECTS) { |
|
73 graphics.setForeground(Colors.getColor(255, 0, 0)); |
|
74 graphics.setXORMode(true); |
|
75 graphics.drawRectangle(contentRect.x, contentRect.y, contentRect.width-1, contentRect.height-1 ); |
|
76 graphics.setXORMode(false); |
|
77 } |
|
78 |
|
79 graphics.setOffX(oldX); |
|
80 graphics.setOffY(oldY); |
|
81 |
|
82 } else if (isSettingItemList(instance.parent)) { |
|
83 |
|
84 var rects = getSettingItemRectangles(instance, laf); |
|
85 var numberRect = rects[SIL_NUMBER_RECT_INDEX]; |
|
86 var titleRect = rects[SIL_TITLE_RECT_INDEX]; |
|
87 var contentRect = rects[SIL_CONTENT_RECT_INDEX]; |
|
88 |
|
89 drawSettingItemPrompt(prototype, instance, laf, graphics, rects); |
|
90 if (DRAW_BOUNDING_RECTS) { |
|
91 graphics.setForeground(Colors.getColor(255, 0, 0)); |
|
92 graphics.setXORMode(true); |
|
93 graphics.drawRectangle(numberRect.x, numberRect.y, numberRect.width-1, numberRect.height-1 ); |
|
94 graphics.drawRectangle(titleRect.x, titleRect.y, titleRect.width-1, titleRect.height-1 ); |
|
95 graphics.setXORMode(false); |
|
96 } |
|
97 |
|
98 var oldX = graphics.getOffX(); |
|
99 var oldY = graphics.getOffY(); |
|
100 graphics.setOffX(contentRect.x); |
|
101 graphics.setOffY(contentRect.y); |
|
102 contentRect.x = 0; |
|
103 contentRect.y = 0; |
|
104 this.drawContent(instance, laf, graphics, contentRect); |
|
105 |
|
106 if (DRAW_BOUNDING_RECTS) { |
|
107 graphics.setForeground(Colors.getColor(128, 0, 0)); |
|
108 graphics.setXORMode(true); |
|
109 graphics.drawRectangle(contentRect.x, contentRect.y, contentRect.width-1, contentRect.height-1 ); |
|
110 graphics.setXORMode(false); |
|
111 } |
|
112 |
|
113 graphics.setOffX(oldX); |
|
114 graphics.setOffY(oldY); |
|
115 |
|
116 } else if (isDataQuery(instance.parent)) { |
|
117 // draw inner shadows |
|
118 var width = properties.size.width; |
|
119 var height = properties.size.height; |
|
120 graphics.setForeground(laf.getColor("control.shadow.inner")); |
|
121 graphics.drawRectangle(0, 0, width - 1, height - 1); |
|
122 |
|
123 |
|
124 graphics.setForeground(laf.getColor("control.shadow.outer")); |
|
125 graphics.drawLine(1, 1, width - 1, 1); |
|
126 graphics.drawLine(1, 1, 1, height - 1); |
|
127 |
|
128 // draw content |
|
129 var rect = new Rectangle(3, 3, |
|
130 properties.size.width - 6, properties.size.height - 6); |
|
131 this.drawContent(instance, laf, graphics, rect); |
|
132 } else { |
|
133 var rect = new Rectangle(0, 0, |
|
134 properties.size.width, properties.size.height); |
|
135 this.drawContent(instance, laf, graphics, rect); |
|
136 } |
|
137 } |
|
138 |
|
139 prototype.getPreferredSize = function(instance, laf, wHint, hHint) { |
|
140 var properties = instance.properties; |
|
141 |
|
142 // [[[ ordinary calculations |
|
143 |
|
144 // get current size |
|
145 width = properties.size.width; |
|
146 height = properties.size.height; |
|
147 |
|
148 // if either of these are empty, use the parent's bounds as starting point |
|
149 if ((width == 0) || (height == 0)) { |
|
150 width = instance.parent.properties.size.width; |
|
151 height = instance.parent.properties.size.height; |
|
152 } |
|
153 |
|
154 // use hints if provided |
|
155 if (wHint >= 0) |
|
156 width = wHint; |
|
157 if (hHint >= 0) |
|
158 height = hHint; |
|
159 |
|
160 // ]]] |
|
161 |
|
162 var rect = new Rectangle(0, 0, width, height); |
|
163 |
|
164 if (isForm(instance.parent)) { |
|
165 var rects = getFormItemRectanglesInRect(instance, laf, rect); |
|
166 var promptRect = rects[FORM_PROMPT_RECT_INDEX]; |
|
167 var contentRect = rects[FORM_CONTENT_RECT_INDEX]; |
|
168 |
|
169 // ensure size is big enough for content |
|
170 size = this.getContentSize(instance, laf, |
|
171 new Point(contentRect.width, contentRect.height)); |
|
172 |
|
173 // for double-space mode, add height for the prompt |
|
174 if (isDoubleSpaced(instance.parent)) { |
|
175 size.y += promptRect.height + getFormLineGap(laf); |
|
176 } else { |
|
177 size.y += getFormLineGap(laf); |
|
178 |
|
179 } |
|
180 } else if (isSettingItemList(instance.parent)) { |
|
181 var rects = getSettingItemRectanglesInRect(instance, laf, rect); |
|
182 var contentRect = rects[SIL_CONTENT_RECT_INDEX]; |
|
183 |
|
184 // ensure size is big enough for content |
|
185 size = this.getContentSize(instance, laf, |
|
186 new Point(contentRect.width, contentRect.height)); |
|
187 |
|
188 //size.y += getLineGap(laf); |
|
189 } else { |
|
190 size = this.getContentSize(instance, laf, new Point(width, height)); |
|
191 } |
|
192 |
|
193 return size; |
|
194 } |
|
195 |
|
196 // drawPrompt needs these routines |
|
197 setupEmbeddedImagePropertyInfo(prototype); |
|
198 } |
|
199 |
|
200 |
|
201 /** |
|
202 * Set up direct label editing implementation for a component with |
|
203 * one editable label |
|
204 * @param prototype the impl prototype to update |
|
205 * @param property the name of the edited property |
|
206 * @param areafunction a function, taking (instance, laf, rect), which returns the |
|
207 * editable area of the label (or null). If null, the default behavior is |
|
208 * to use the entire rendered area. Otherwise, the area should be a subset |
|
209 * of rect (which is adjusted to the content area in a form if necessary). |
|
210 * @param fontfunction a function, taking an instance and laf, which returns the |
|
211 * IFont to edit with (or null). If null, the default behavior is to return |
|
212 * null, indicating a default system font. |
|
213 */ |
|
214 function setupCommonEmbeddedDirectLabelEditing(prototype, property, |
|
215 areafunction, fontfunction) { |
|
216 |
|
217 prototype.getPropertyPaths = function(instance) { |
|
218 if (property) { |
|
219 if (isForm(instance.parent)) |
|
220 return [ "prompt", property ]; |
|
221 else if (isSettingItemList(instance.parent)) |
|
222 return [ "itemTitle", "compulsoryLabel", property ]; |
|
223 else |
|
224 return [ property ]; |
|
225 } else { |
|
226 if (isForm(instance.parent)) |
|
227 return [ "prompt" ]; |
|
228 else if (isSettingItemList(instance.parent)) |
|
229 return [ "itemTitle", "compulsoryLabel" ]; |
|
230 else |
|
231 return [ ]; |
|
232 } |
|
233 } |
|
234 |
|
235 prototype.getLabelBounds = function(instance, propertyPath, laf) { |
|
236 |
|
237 if (isForm(instance.parent)) { |
|
238 var rects = getFormItemRectangles(instance, laf); |
|
239 var promptLabelRect = rects[FORM_PROMPT_LABEL_RECT_INDEX]; |
|
240 var contentRect = rects[FORM_CONTENT_RECT_INDEX]; |
|
241 |
|
242 if (propertyPath == "prompt") { |
|
243 return promptLabelRect; |
|
244 } |
|
245 else if (property && propertyPath == property) { |
|
246 rect = contentRect; |
|
247 if (areafunction) |
|
248 rect = areafunction(instance, laf, rect); |
|
249 return rect; |
|
250 } |
|
251 else /* fall through */ ; |
|
252 } else if (isSettingItemList(instance.parent)) { |
|
253 var rects = getSettingItemRectangles(instance, laf); |
|
254 var titleLabelRect = rects[SIL_TITLE_RECT_INDEX]; |
|
255 var contentRect = rects[SIL_CONTENT_RECT_INDEX]; |
|
256 |
|
257 if (propertyPath == "itemTitle") { |
|
258 return titleLabelRect; |
|
259 } |
|
260 if (propertyPath == "compulsoryLabel") { |
|
261 return rects[SIL_INDICATOR_RECT_INDEX]; |
|
262 } |
|
263 if (property && propertyPath == property) { |
|
264 rect = contentRect; |
|
265 if (areafunction) |
|
266 rect = areafunction(instance, laf, rect); |
|
267 return rect; |
|
268 } |
|
269 /* fall through */ |
|
270 |
|
271 } |
|
272 |
|
273 var rect = new Rectangle(0, 0, |
|
274 instance.properties.size.width, instance.properties.size.height); |
|
275 |
|
276 if (property && propertyPath == property) { |
|
277 if (areafunction) |
|
278 rect = areafunction(instance, laf, rect); |
|
279 |
|
280 return rect; |
|
281 } |
|
282 |
|
283 return null; |
|
284 } |
|
285 |
|
286 prototype.getLabelFont = function(instance, propertyPath, laf) { |
|
287 if (propertyPath == "prompt") |
|
288 return getPromptFont(laf); |
|
289 if (propertyPath == "itemTitle") |
|
290 return getTitleFont(laf); |
|
291 |
|
292 if (property && propertyPath) { |
|
293 if (fontfunction) |
|
294 return fontfunction(instance, laf); |
|
295 } |
|
296 |
|
297 return null; |
|
298 } |
|
299 } |
|
300 |
|
301 /** |
|
302 * Support image validation for a form-provided promptImage property. |
|
303 */ |
|
304 function setupCommonEmbeddedDirectImageEditing(prototype) { |
|
305 setupCommonDirectImageEditing(prototype, "promptImage", |
|
306 |
|
307 /* areafunction */ |
|
308 function (instance, laf, propertyId) { |
|
309 if (isForm(instance.parent) && |
|
310 instance.parent.properties.EEikFormShowBitmaps) { |
|
311 var rects = getFormItemRectangles(instance, laf); |
|
312 return rects[FORM_PROMPT_IMAGE_RECT_INDEX]; |
|
313 } else { |
|
314 return null; |
|
315 } |
|
316 } |
|
317 ); |
|
318 } |
|
319 |
|
320 /** |
|
321 * Support image property info support for form |
|
322 */ |
|
323 function setupEmbeddedImagePropertyInfo(prototype) { |
|
324 // IImagePropertyRenderingInfo |
|
325 prototype.getViewableSize = function(instance, propertyId, laf) { |
|
326 if (propertyId == "promptImage") { |
|
327 if (isForm(instance.parent)) { |
|
328 // return rect even if prompt is invisible |
|
329 var rects = getFormItemRectangles(instance, laf); |
|
330 var rect = rects[FORM_PROMPT_IMAGE_RECT_INDEX]; |
|
331 if (rect != null) |
|
332 return new Point(rect.width, rect.height); |
|
333 } |
|
334 } |
|
335 return null; |
|
336 } |
|
337 |
|
338 prototype.isScaling = function(instance, propertyId, laf) { |
|
339 if (propertyId == "promptImage") { |
|
340 return isScalingIcons(); |
|
341 } |
|
342 return true; |
|
343 } |
|
344 |
|
345 prototype.getAlignmentWeights = function(instance, propertyId, laf) { |
|
346 if (propertyId == "promptImage") { |
|
347 return new Point(ImageUtils.ALIGN_CENTER_OR_LEFT, ImageUtils.ALIGN_CENTER_OR_TOP); |
|
348 } |
|
349 return null; |
|
350 } |
|
351 |
|
352 prototype.isPreservingAspectRatio = function(instance, propertyId, laf) { |
|
353 if (propertyId == "promptImage") { |
|
354 return true; |
|
355 } |
|
356 return true; |
|
357 } |
|
358 |
|
359 } |