2
|
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 |
include("renderLibrary.js")
|
|
20 |
|
|
21 |
/**
|
|
22 |
* Create a contribution that sets a property if its value
|
|
23 |
* is not equal to a given default.
|
|
24 |
* @param phase the phase to supply
|
|
25 |
* @param indent extra indentation to add (i.e. 1 if inside an "if")
|
|
26 |
* @param instanceMemberName the name of the member variable
|
|
27 |
* @param propertyValue the current value of the property
|
|
28 |
* @param defaultValue the value considered the default
|
|
29 |
* @param format a format string for setting the property, where
|
|
30 |
* {0} is substituted with instanceMemberName and
|
|
31 |
* {1} is substituted with the propertyValue
|
|
32 |
* @return a contribution, or null
|
|
33 |
*/
|
|
34 |
function createSetPropertyForPhase(contribs, phase, indent, instanceMemberName,
|
|
35 |
propertyValue, defaultValue, format) {
|
|
36 |
if (propertyValue != defaultValue) {
|
|
37 |
contrib = Engine.createContributionForPhase(phase);
|
|
38 |
contrib.indentAdjust(indent);
|
|
39 |
contrib.setFormattedText(format, new Array( instanceMemberName, propertyValue) );
|
|
40 |
return contrib;
|
|
41 |
}
|
|
42 |
return null;
|
|
43 |
}
|
|
44 |
|
|
45 |
/**
|
|
46 |
* Generate a contribution that sets a property if its value
|
|
47 |
* is not equal to a given default.
|
|
48 |
* @param contribs the contribution list
|
|
49 |
* @param phase the phase to supply
|
|
50 |
* @param indent extra indentation to add (i.e. 1 if inside an "if")
|
|
51 |
* @param instanceMemberName the name of the member variable
|
|
52 |
* @param propertyValue the current value of the property
|
|
53 |
* @param defaultValue the value considered the default
|
|
54 |
* @param format a format string for setting the property, where
|
|
55 |
* {0} is substituted with instanceMemberName and
|
|
56 |
* {1} is substituted with the propertyValue
|
|
57 |
* @param checkNull if true, insert check for null instance around sette
|
|
58 |
*/
|
|
59 |
function setPropertyForPhase(contribs, phase, indent, instanceMemberName,
|
|
60 |
propertyValue, defaultValue, format, checkNull) {
|
|
61 |
contrib = createSetPropertyForPhase(contribs, phase, indent,
|
|
62 |
instanceMemberName, propertyValue, defaultValue, format);
|
|
63 |
if (contrib == null)
|
|
64 |
return;
|
|
65 |
if (checkNull) {
|
|
66 |
acontrib = Engine.createContributionForPhase(phase);
|
|
67 |
acontrib.indentAdjust(indent);
|
|
68 |
acontrib.setFormattedText("if ( {0} )\n", [ instanceMemberName ]);
|
|
69 |
contribs.add(acontrib);
|
|
70 |
|
|
71 |
acontrib = Engine.createContributionForPhase(phase);
|
|
72 |
acontrib.indentAdjust(indent+1);
|
|
73 |
acontrib.setText("{\n");
|
|
74 |
contribs.add(acontrib);
|
|
75 |
|
|
76 |
contribs.add(contrib);
|
|
77 |
|
|
78 |
acontrib = Engine.createContributionForPhase(phase);
|
|
79 |
acontrib.indentAdjust(indent+1);
|
|
80 |
acontrib.setText("}\n");
|
|
81 |
contribs.add(acontrib);
|
|
82 |
} else {
|
|
83 |
contribs.add(contrib);
|
|
84 |
}
|
|
85 |
}
|
|
86 |
|
|
87 |
/**
|
|
88 |
* Generate a set of contributions to set multiple possible
|
|
89 |
* properties.
|
|
90 |
* Like #setPropertyForPhase(), where the 5th and later arguments
|
|
91 |
* are taken in groups of three as [propertyValue, defaultValue, format].
|
|
92 |
*/
|
|
93 |
function setPropertiesForPhase(contribs, phase, indent, instanceMemberName, checkNull) {
|
|
94 |
var any = false;
|
|
95 |
var innerIndent = indent + (checkNull ? 1 : 0);
|
|
96 |
for (var h = 5; h < arguments.length; h += 3) {
|
|
97 |
contrib = createSetPropertyForPhase(contribs, phase, innerIndent, instanceMemberName,
|
|
98 |
arguments[h], arguments[h+1], arguments[h+2]);
|
|
99 |
if (contrib == null)
|
|
100 |
continue;
|
|
101 |
if (!any && checkNull) {
|
|
102 |
acontrib = Engine.createContributionForPhase(phase);
|
|
103 |
acontrib.indentAdjust(indent);
|
|
104 |
acontrib.setFormattedText("if ( {0} )\n", [ instanceMemberName ]);
|
|
105 |
contribs.add(acontrib);
|
|
106 |
|
|
107 |
acontrib = Engine.createContributionForPhase(phase);
|
|
108 |
acontrib.indentAdjust(indent+1);
|
|
109 |
acontrib.setText("{\n");
|
|
110 |
contribs.add(acontrib);
|
|
111 |
|
|
112 |
any = true;
|
|
113 |
}
|
|
114 |
contribs.add(contrib);
|
|
115 |
}
|
|
116 |
|
|
117 |
if (any && checkNull) {
|
|
118 |
acontrib = Engine.createContributionForPhase(phase);
|
|
119 |
acontrib.indentAdjust(indent+1);
|
|
120 |
acontrib.setText("}\n");
|
|
121 |
contribs.add(acontrib);
|
|
122 |
}
|
|
123 |
}
|
|
124 |
|
|
125 |
/**
|
|
126 |
* Get the base filename
|
|
127 |
* @param path a path
|
|
128 |
*/
|
|
129 |
function getBaseFileName(path) {
|
|
130 |
var idx = path.lastIndexOf('/');
|
|
131 |
if (idx >= 0)
|
|
132 |
base = path.substring(idx+1);
|
|
133 |
else {
|
|
134 |
idx = path.lastIndexOf('\\');
|
|
135 |
if (idx >= 0)
|
|
136 |
base = path.substring(idx+1);
|
|
137 |
else
|
|
138 |
base = path;
|
|
139 |
}
|
|
140 |
idx = base.lastIndexOf('.');
|
|
141 |
if (idx >= 0)
|
|
142 |
base = base.substring(0, idx);
|
|
143 |
|
|
144 |
return base;
|
|
145 |
}
|
|
146 |
|
|
147 |
/**
|
|
148 |
* Get the bitmap header file
|
|
149 |
* @param path the system MBM/MIF name from the image.bmpfile property
|
|
150 |
*/
|
|
151 |
function getBitmapHeaderName(path) {
|
|
152 |
var base = getBaseFileName(path);
|
|
153 |
return base + ".mbg";
|
|
154 |
}
|
|
155 |
|
|
156 |
function addContrib(contribs, phase, loc, indent, text) {
|
|
157 |
var c;
|
|
158 |
if (phase != null)
|
|
159 |
c = Engine.createContributionForPhase(phase);
|
|
160 |
else
|
|
161 |
c = Engine.createContributionForLocation(loc);
|
|
162 |
c.setText(text);
|
|
163 |
c.indentAdjust(indent);
|
|
164 |
contribs.add(c);
|
|
165 |
}
|
|
166 |
|
|
167 |
function addFormattedContrib(contribs, phase, loc, indent, format, args) {
|
|
168 |
var c;
|
|
169 |
if (phase != null)
|
|
170 |
c = Engine.createContributionForPhase(phase);
|
|
171 |
else
|
|
172 |
c = Engine.createContributionForLocation(loc);
|
|
173 |
c.setFormattedText(format, args);
|
|
174 |
c.indentAdjust(indent);
|
|
175 |
contribs.add(c);
|
|
176 |
}
|
|
177 |
|
|
178 |
/**
|
|
179 |
* Get the nearest enclosing instance that defines a class.
|
|
180 |
*/
|
|
181 |
function getClassHolder(instance) {
|
|
182 |
while (instance != null && !instance.properties.className) {
|
|
183 |
instance = instance.parent;
|
|
184 |
}
|
|
185 |
return instance;
|
|
186 |
}
|
|
187 |
|
|
188 |
/**
|
|
189 |
* Get the table of multi-image filenames to literal names
|
|
190 |
*/
|
|
191 |
function getFilenameToLiteralTable(instance) {
|
|
192 |
var holder = getClassHolder(instance);
|
|
193 |
var key = "ImageSupport.filenameToLiteralTable:" + holder;
|
|
194 |
var table = Engine.getGlobalDictionary().get(key);
|
|
195 |
if (table == null) {
|
|
196 |
table = new java.util.HashMap();
|
|
197 |
Engine.getGlobalDictionary().put(key, table);
|
|
198 |
}
|
|
199 |
return table;
|
|
200 |
}
|
|
201 |
|
|
202 |
/**
|
|
203 |
* Get an identifier name from a MBM/MIF filepath
|
|
204 |
*/
|
|
205 |
function makeLiteralIdentifier(map, path) {
|
|
206 |
// no need to uniquify, as the base mbmdef/mifdef name must be unique as well
|
|
207 |
var base = getBaseFileName(path);
|
|
208 |
var litname = "K" + base + "File";
|
|
209 |
return litname;
|
|
210 |
}
|
|
211 |
|
|
212 |
/**
|
|
213 |
* Prepare a container for sourcegen that involves generating
|
|
214 |
* image properties. We need to ensure the MBM/MIF filename for
|
|
215 |
* an image is emitted as a constant only once.
|
|
216 |
*/
|
|
217 |
function resetImagePropertyState(instance) {
|
|
218 |
var classHolder = getClassHolder(instance);
|
|
219 |
classHolder.filenameToLiteralTable = new java.util.HashMap();
|
|
220 |
}
|
|
221 |
|
|
222 |
/**
|
|
223 |
* Tell if an image property is set. If not, it should be ignored.
|
|
224 |
*/
|
|
225 |
function isImagePropertySet(imageProperty) {
|
|
226 |
return imageProperty.bmpfile != ""
|
|
227 |
&& imageProperty.bmpid != "";
|
|
228 |
}
|
|
229 |
|
|
230 |
/**
|
|
231 |
* Tell if we support scaling at all
|
|
232 |
*/
|
|
233 |
function isScalingIcons() {
|
|
234 |
var version = getComponentVersions();
|
|
235 |
if (version.getMajor() >= 3)
|
|
236 |
return true;
|
|
237 |
if (version.getMajor() == 2 && version.getMinor() >= 8) {
|
|
238 |
appUi = getRootModelInstanceOfType("com.nokia.sdt.series60.CAknAppUi");
|
|
239 |
if (appUi != null)
|
|
240 |
return appUi.properties.layoutAware;
|
|
241 |
}
|
|
242 |
return false;
|
|
243 |
}
|
|
244 |
|
|
245 |
/**
|
|
246 |
* Set up contributions that set up an image property given
|
|
247 |
* its compound property. This uses CFbsBitmap* objects and
|
|
248 |
* thus allows for resizing behavior. Use a separate routine if
|
|
249 |
* setting up multiple images, since the repeated code for SVG setup
|
|
250 |
* can get quite long.
|
|
251 |
* @param contribs the contributions to append to
|
|
252 |
* @param instance instance the image is for (used to find the class)
|
|
253 |
* @param phase primary phase to write to (or null, loc must be set)
|
|
254 |
* @param loc primary location to write to (or null, phase must be set)
|
|
255 |
* @param indent indentation adjust
|
|
256 |
* @param imageProperty the property value
|
|
257 |
* @param aspectOption the appropriate enumeration for aspect ratio handling (or null)
|
|
258 |
* @param bitmapPattern when only a bitmap is set,
|
|
259 |
* a MessageFormat string to be substituted with arguments ([ CFbsBitmap* ])
|
|
260 |
* @param bitmapAndMaskPattern when a bitmap and mask is set,
|
|
261 |
* a MessageFormat string to be substituted with arguments (or null)
|
|
262 |
* ([ CFbsBitmap*, CFbsBitmap* ])
|
|
263 |
* @param theSize text representing the TSize argument (e.g. "control->Size()" or "TSize(45, 66)")
|
|
264 |
* or null to use the image's real size
|
|
265 |
*/
|
|
266 |
function setupImageFromPropertyViaCFbsBitmap(contribs, instance, phase, loc, indent,
|
|
267 |
imageProperty, aspectOption,
|
|
268 |
bitmapPattern, bitmapAndMaskPattern, theSize) {
|
|
269 |
|
|
270 |
var version = getComponentVersions();
|
|
271 |
var contrib;
|
|
272 |
|
|
273 |
// moved here to precede system includes of .mbg files
|
|
274 |
var isSVG = imageProperty.editableValue.isSVG();
|
|
275 |
|
|
276 |
if (isScalingIcons() || isSVG) {
|
|
277 |
// get icon utilities header
|
|
278 |
addContrib(contribs, "MainSystemIncludes", loc, 0,
|
|
279 |
"#include <akniconutils.h>\n");
|
|
280 |
}
|
|
281 |
|
|
282 |
if (imageProperty.bmpfile != "") {
|
|
283 |
// make the literal string for the filename
|
|
284 |
var litname = getImageRsrcLiteralName(contribs, instance, imageProperty);
|
|
285 |
}
|
|
286 |
|
|
287 |
if (!isScalingIcons() && !isSVG) {
|
|
288 |
// only unscalable bitmaps allowed, and initialized via CFbsBitmap
|
|
289 |
indent++;
|
|
290 |
addContrib(contribs, phase, loc, indent,
|
|
291 |
"{\n");
|
|
292 |
if (bitmapAndMaskPattern != null
|
|
293 |
&& imageProperty.bmpfile != ""
|
|
294 |
&& imageProperty.bmpmask != ""
|
|
295 |
&& imageProperty.bmpid != "") {
|
|
296 |
addContrib(contribs, phase, loc, indent,
|
|
297 |
"CFbsBitmap* bitmap = iEikonEnv->CreateBitmapL( " + litname + ", " + imageProperty.bmpid + " );\n"
|
|
298 |
);
|
|
299 |
addContrib(contribs, phase, loc, indent,
|
|
300 |
"CFbsBitmap* mask = iEikonEnv->CreateBitmapL( " + litname + ", " + imageProperty.bmpmask + " );\n"
|
|
301 |
);
|
|
302 |
|
|
303 |
addFormattedContrib(contribs, phase, loc, indent,
|
|
304 |
bitmapAndMaskPattern, [ "bitmap", "mask" ]);
|
|
305 |
}
|
|
306 |
else if (bitmapPattern != null) {
|
|
307 |
if (imageProperty.bmpfile != "" && imageProperty.bmpid != "") {
|
|
308 |
addContrib(contribs, phase, loc, indent,
|
|
309 |
"CFbsBitmap* bitmap = iEikonEnv->CreateBitmapL( " + litname + ", " + imageProperty.bmpid + " );\n"
|
|
310 |
);
|
|
311 |
} else {
|
|
312 |
// no image, but at least a bitmap is required
|
|
313 |
addContrib(contribs, phase, loc, indent,
|
|
314 |
"CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;\n"
|
|
315 |
);
|
|
316 |
}
|
|
317 |
addFormattedContrib(contribs, phase, loc, indent,
|
|
318 |
bitmapPattern, [ "bitmap" ]);
|
|
319 |
}
|
|
320 |
|
|
321 |
addContrib(contribs, phase, loc, indent,
|
|
322 |
"}\n");
|
|
323 |
indent--;
|
|
324 |
|
|
325 |
} else {
|
|
326 |
// S60 >= 3.0
|
|
327 |
|
|
328 |
indent++;
|
|
329 |
|
|
330 |
addContrib(contribs, phase, loc, indent,
|
|
331 |
"{\n");
|
|
332 |
|
|
333 |
var sizeArg = theSize;
|
|
334 |
if (sizeArg == null)
|
|
335 |
sizeArg = "size"; // for SVG
|
|
336 |
|
|
337 |
if (imageProperty.bmpfile != "") {
|
|
338 |
// load the bitmap and/or mask
|
|
339 |
addContrib(contribs, phase, loc, indent,
|
|
340 |
"CFbsBitmap *bitmap, *mask;\n");
|
|
341 |
|
|
342 |
addContrib(contribs, phase, loc, indent,
|
|
343 |
"AknIconUtils::CreateIconL( bitmap, mask,\n"+
|
|
344 |
"\t\t" + litname + ", " +
|
|
345 |
((bitmapPattern != null && imageProperty.bmpid != "") ?
|
|
346 |
imageProperty.bmpid : "-1") +
|
|
347 |
", " +
|
|
348 |
((bitmapAndMaskPattern != null && imageProperty.bmpmask != "") ?
|
|
349 |
imageProperty.bmpmask : "-1") +
|
|
350 |
" );\n");
|
|
351 |
|
|
352 |
// prepare to issue two calls needing SVG info
|
|
353 |
if (isSVG && theSize == null) {
|
|
354 |
addContrib(contribs, phase, loc, indent,
|
|
355 |
"TSize size;\n"+
|
|
356 |
"AknIconUtils::PreserveIconData( bitmap );\n"+
|
|
357 |
//"AknIconUtils::PreserveIconData( mask );\n"+
|
|
358 |
"");
|
|
359 |
}
|
|
360 |
|
|
361 |
} else {
|
|
362 |
// no image, but at least a bitmap WITH CONTENT is required
|
|
363 |
addContrib(contribs, phase, loc, indent,
|
|
364 |
"CFbsBitmap *bitmap = new (ELeave) CFbsBitmap;\n"+
|
|
365 |
"bitmap->Create( TSize( 1, 1), EGray2 );\n");
|
|
366 |
}
|
|
367 |
|
|
368 |
// set the size
|
|
369 |
var aspectText;
|
|
370 |
if (aspectOption != null && aspectOption != "")
|
|
371 |
aspectText = ", " + aspectOption;
|
|
372 |
else
|
|
373 |
aspectText = ", EAspectRatioNotPreserved";
|
|
374 |
|
|
375 |
if (imageProperty.bmpfile != "") {
|
|
376 |
if (isSVG && theSize == null) {
|
|
377 |
// get the size
|
|
378 |
addContrib(contribs, phase, loc, indent,
|
|
379 |
"AknIconUtils::GetContentDimensions( bitmap, size );\n");
|
|
380 |
}
|
|
381 |
}
|
|
382 |
|
|
383 |
if (bitmapAndMaskPattern != null
|
|
384 |
&& imageProperty.bmpfile != ""
|
|
385 |
&& imageProperty.bmpmask != ""
|
|
386 |
&& imageProperty.bmpid != "") {
|
|
387 |
|
|
388 |
addContrib(contribs, phase, loc, indent,
|
|
389 |
"AknIconUtils::SetSize( bitmap, " + sizeArg + aspectText + " );\n");
|
|
390 |
addContrib(contribs, phase, loc, indent,
|
|
391 |
"AknIconUtils::SetSize( mask, " + sizeArg + aspectText + " );\n");
|
|
392 |
|
|
393 |
addFormattedContrib(contribs, phase, loc, indent,
|
|
394 |
bitmapAndMaskPattern, [ "bitmap", "mask" ]);
|
|
395 |
|
|
396 |
} else if (bitmapPattern != null) {
|
|
397 |
addContrib(contribs, phase, loc, indent,
|
|
398 |
"AknIconUtils::SetSize( bitmap, " + theSize + aspectText + " );\n");
|
|
399 |
|
|
400 |
addFormattedContrib(contribs, phase, loc, indent,
|
|
401 |
bitmapPattern, [ "bitmap" ]);
|
|
402 |
}
|
|
403 |
|
|
404 |
if (isSVG && theSize == null) {
|
|
405 |
addContrib(contribs, phase, loc, indent,
|
|
406 |
"AknIconUtils::DestroyIconData( bitmap );\n");
|
|
407 |
}
|
|
408 |
|
|
409 |
addContrib(contribs, phase, loc, indent,
|
|
410 |
"}\n");
|
|
411 |
|
|
412 |
indent--;
|
|
413 |
}
|
|
414 |
}
|
|
415 |
|
|
416 |
/**
|
|
417 |
* Set up contributions that set up an image property given
|
|
418 |
* its compound property. This passes arguments to a function
|
|
419 |
* which takes the (TDesc aFileName, TInt bmpid, TInt maskid)
|
|
420 |
* arguments. Image resizing is not allowed.
|
|
421 |
* @param contribs the contributions to append to
|
|
422 |
* @param instance instance the image is for (used to find the class)
|
|
423 |
* @param phase primary phase to write to (or null, loc must be set)
|
|
424 |
* @param loc primary location to write to (or null, phase must be set)
|
|
425 |
* @param indent indentation adjust
|
|
426 |
* @param imageProperty the compound property providing bmpfile, bmpid, bmpmask
|
|
427 |
* @param bitmapPattern when only a bitmap is set,
|
|
428 |
* a MessageFormat string to be substituted with arguments
|
|
429 |
* ([ filename, id ])
|
|
430 |
* @param bitmapAndMaskPattern when a bitmap and mask is set,
|
|
431 |
* a MessageFormat string to be substituted with arguments (or null)
|
|
432 |
* ([ filename, id, maskid ])
|
|
433 |
*/
|
|
434 |
function setupImageFromPropertyViaTuple(contribs, instance, phase, loc, indent,
|
|
435 |
imageProperty,
|
|
436 |
bitmapPattern, bitmapAndMaskPattern) {
|
|
437 |
|
|
438 |
if (!isImagePropertySet(imageProperty))
|
|
439 |
return;
|
|
440 |
|
|
441 |
var version = getComponentVersions();
|
|
442 |
var contrib;
|
|
443 |
|
|
444 |
// make the literal string for the filename
|
|
445 |
var litname = getImageRsrcLiteralName(contribs, instance, imageProperty);
|
|
446 |
|
|
447 |
if (bitmapAndMaskPattern != null
|
|
448 |
&& imageProperty.bmpmask != "") {
|
|
449 |
|
|
450 |
addFormattedContrib(contribs, phase, loc, indent,
|
|
451 |
bitmapAndMaskPattern, [ litname, imageProperty.bmpid, imageProperty.bmpmask ]);
|
|
452 |
}
|
|
453 |
else if (bitmapPattern != null) {
|
|
454 |
addFormattedContrib(contribs, phase, loc, indent,
|
|
455 |
bitmapPattern, [ litname, imageProperty.bmpid ]);
|
|
456 |
}
|
|
457 |
|
|
458 |
}
|
|
459 |
|
|
460 |
/**
|
|
461 |
* Gets the literal (_LIT) name from an image resource bitmap name.
|
|
462 |
* If the literal name has not been created, it will create it for you.
|
|
463 |
* @param contribs the contributions to append to
|
|
464 |
* @param instance the instance the image it for
|
|
465 |
* @param imageProperty the compound property providing bmpfile, bmpid, bmpmask
|
|
466 |
*/
|
|
467 |
function getImageRsrcLiteralName(contribs, instance, imageProperty){
|
|
468 |
var table = getFilenameToLiteralTable(instance);
|
|
469 |
var litname = table.get(imageProperty.bmpfile);
|
|
470 |
if (!litname) {
|
|
471 |
litname = makeLiteralIdentifier(table, imageProperty.bmpfile);
|
|
472 |
addContrib(contribs, "MainConstants", null, 0,
|
|
473 |
"_LIT( " + litname +", \"" +
|
|
474 |
TextUtils.escape(imageProperty.bmpfile, '"') + "\" );\n");
|
|
475 |
// get the mbg header
|
|
476 |
addContrib(contribs, "MainSystemIncludes", null, 0,
|
|
477 |
"#include <" + getBitmapHeaderName(imageProperty.bmpfile) + ">\n");
|
|
478 |
table.put(imageProperty.bmpfile, litname);
|
|
479 |
}
|
|
480 |
return litname;
|
|
481 |
}
|
|
482 |
|
|
483 |
/**
|
|
484 |
* Create a method that loads and scales SVG or BMP icons, for use when
|
|
485 |
* multiple icons are loaded at once. This assumes the function defined in
|
|
486 |
* LoadAndScaleIconL.inc. For S60 2.8 or newer.
|
|
487 |
*/
|
|
488 |
function defineIconLoadingRoutines(contribs, location, className) {
|
|
489 |
// get icon utilities headers.
|
|
490 |
addContrib(contribs, "HeaderIncludes", null, 0,
|
|
491 |
"#include <akniconutils.h>\n");
|
|
492 |
addContrib(contribs, "HeaderIncludes", null, 0,
|
|
493 |
"#include <gulicon.h>\n");
|
|
494 |
|
|
495 |
//// needs to be permanent or else it's duplicated
|
|
496 |
//addContrib(contribs, "UserHandlers", null, 0,
|
|
497 |
addContrib(contribs, "ClassMethods", null, 0,
|
|
498 |
"static CGulIcon* LoadAndScaleIconL(\n"+
|
|
499 |
"\t\tconst TDesC& aFileName,\n"+
|
|
500 |
"\t\tTInt aBitmapId,\n"+
|
|
501 |
"\t\tTInt aMaskId,\n"+
|
|
502 |
"\t\tTSize* aSize,\n"+
|
|
503 |
"\t\tTScaleMode aScaleMode );\n"
|
|
504 |
);
|
|
505 |
|
|
506 |
// force the location to be instantiated
|
|
507 |
addContrib(contribs, null, location, 0, "");
|
|
508 |
return;
|
|
509 |
}
|
|
510 |
|
|
511 |
var alignmentMap = {
|
|
512 |
"EHLeft+EVTop" : "EHLeftVTop",
|
|
513 |
"EHLeft+EVCenter" : "EHLeftVCenter",
|
|
514 |
"EHLeft+EVBottom" : "EHLeftVBottom",
|
|
515 |
"EHCenter+EVTop" : "EHCenterVTop",
|
|
516 |
"EHCenter+EVCenter" : "EHCenterVCenter",
|
|
517 |
"EHCenter+EVBottom" : "EHCenterVBottom",
|
|
518 |
"EHRight+EVTop" : "EHRightVTop",
|
|
519 |
"EHRight+EVCenter" : "EHRightVCenter",
|
|
520 |
"EHRight+EVBottom" : "EHRightVBottom"
|
|
521 |
};
|
|
522 |
|
|
523 |
function getTGulAlignmentValue(horiz, vert) {
|
|
524 |
return alignmentMap[horiz+"+"+vert];
|
|
525 |
}
|
|
526 |
|
|
527 |
//////////////////////////
|
|
528 |
|
|
529 |
/**
|
|
530 |
* Get the table of unique images in an icon array
|
|
531 |
* @return an ImageList
|
|
532 |
*/
|
|
533 |
function getImageList(instance) {
|
|
534 |
var key = "srcgenLibrary.ImageList:" + instance.name;
|
|
535 |
var table = Engine.getGlobalDictionary().get(key);
|
|
536 |
if (table == null) {
|
|
537 |
table = new ImageList(instance);
|
|
538 |
Engine.getGlobalDictionary().put(key, table);
|
|
539 |
}
|
|
540 |
return table;
|
|
541 |
}
|
|
542 |
|
|
543 |
|
|
544 |
/**
|
|
545 |
* This is a prototype used to track arrays of icons.
|
|
546 |
* Create an instance of the class and populate it with image
|
|
547 |
* properties, then generate contributions that create a
|
|
548 |
* CArrayPtr<CGulIcon> array, then look up indices of image
|
|
549 |
* properties either by index or generated enum.
|
|
550 |
*
|
|
551 |
* @param ownerInstance the instance that owns all the images
|
|
552 |
*/
|
|
553 |
function ImageList(ownerInstance) {
|
|
554 |
this.ownerInstance = ownerInstance;
|
|
555 |
this.imageMap = new java.util.LinkedHashMap();
|
|
556 |
this.enumSet = new java.util.LinkedHashSet();
|
|
557 |
this.imageIdx = 0;
|
|
558 |
this.lastEnum = "0";
|
|
559 |
}
|
|
560 |
|
|
561 |
ImageList.prototype.getImagePropertyKey = function(imageProperty) {
|
|
562 |
if (isImagePropertySet(imageProperty)) {
|
|
563 |
return imageProperty.bmpfile + "|" + imageProperty.bmpid + "|" + imageProperty.bmpmask;
|
|
564 |
} else {
|
|
565 |
return null;
|
|
566 |
}
|
|
567 |
}
|
|
568 |
|
|
569 |
ImageList.prototype.uniquifyEnum = function(enm) {
|
|
570 |
var idx = 1;
|
|
571 |
var base = enm;
|
|
572 |
while (this.enumSet.contains(enm)) {
|
|
573 |
enm = base + (++idx);
|
|
574 |
}
|
|
575 |
return enm;
|
|
576 |
}
|
|
577 |
|
|
578 |
IL_PROPERTY_INDEX = 0;
|
|
579 |
IL_INDEX_INDEX = 1;
|
|
580 |
IL_ENUM_INDEX = 2;
|
|
581 |
|
|
582 |
/**
|
|
583 |
* Register an image property. Only adds if unique.
|
|
584 |
* @param instance the instance containing the property
|
|
585 |
* @param property the property ID
|
|
586 |
*/
|
|
587 |
ImageList.prototype.registerImageProperty = function(imageProperty) {
|
|
588 |
var key = this.getImagePropertyKey(imageProperty);
|
|
589 |
if (key != null && !this.imageMap.containsKey(key)) {
|
|
590 |
var base = imageProperty.bmpid;
|
|
591 |
if (base == "")
|
|
592 |
base = imageProperty.bmpmask;
|
|
593 |
if (base.substring(0, 4) == "EMbm")
|
|
594 |
base = base.substring(4);
|
|
595 |
|
|
596 |
var enm = "E" + titleCase(this.ownerInstance.name) + base + "Index";
|
|
597 |
enm = this.uniquifyEnum(enm);
|
|
598 |
this.enumSet.add(enm);
|
|
599 |
this.lastEnum = enm;
|
|
600 |
|
|
601 |
this.imageMap.put(key, [imageProperty, this.imageIdx++, enm]);
|
|
602 |
}
|
|
603 |
}
|
|
604 |
|
|
605 |
ImageList.prototype.getSystemImageKey = function(bitmap, mask) {
|
|
606 |
if (bitmap == null || bitmap.length == 0)
|
|
607 |
return null;
|
|
608 |
|
|
609 |
var file = "KAvkonBitmapFile"; // constant in aknconsts.h
|
|
610 |
var prefix = "EMbmAvkon";
|
|
611 |
var key = file
|
|
612 |
+ "|"
|
|
613 |
+ (bitmap.length > 0 ? prefix + titleCase(bitmap) : "")
|
|
614 |
+ "|"
|
|
615 |
+ (mask.length > 0 ? prefix + titleCase(mask) : "");
|
|
616 |
return key;
|
|
617 |
}
|
|
618 |
|
|
619 |
/**
|
|
620 |
* Register an Avkon system image (only added if unique).
|
|
621 |
*/
|
|
622 |
ImageList.prototype.registerAvkonSystemImage = function(bitmap, mask) {
|
|
623 |
var key = this.getSystemImageKey(bitmap, mask);
|
|
624 |
if (key != null && !this.imageMap.containsKey(key)) {
|
|
625 |
var enm = "E" + titleCase(this.ownerInstance.name)
|
|
626 |
+ "Avkon" + titleCase(bitmap != null ? bitmap : mask)
|
|
627 |
+ "Index";
|
|
628 |
enm = this.uniquifyEnum(enm);
|
|
629 |
this.lastEnum = enm;
|
|
630 |
|
|
631 |
this.imageMap.put(key, [null, this.imageIdx++, enm]);
|
|
632 |
}
|
|
633 |
}
|
|
634 |
|
|
635 |
/**
|
|
636 |
* Get the icon index for the given image.
|
|
637 |
*/
|
|
638 |
ImageList.prototype.getListIconIndexForProperty = function(imageProperty) {
|
|
639 |
var key = this.getImagePropertyKey(imageProperty);
|
|
640 |
var value = this.imageMap.get(key);
|
|
641 |
if (value != null)
|
|
642 |
return value[IL_INDEX_INDEX];
|
|
643 |
else
|
|
644 |
return -1;
|
|
645 |
}
|
|
646 |
|
|
647 |
/**
|
|
648 |
* Get the enumerator for the given image.
|
|
649 |
*/
|
|
650 |
ImageList.prototype.getListIconEnumForProperty = function(imageProperty, getEnum) {
|
|
651 |
var key = this.getImagePropertyKey(imageProperty);
|
|
652 |
var value = this.imageMap.get(key);
|
|
653 |
if (value != null)
|
|
654 |
return value[IL_ENUM_INDEX];
|
|
655 |
else
|
|
656 |
return null;
|
|
657 |
}
|
|
658 |
|
|
659 |
/**
|
|
660 |
* Get the number of images, also the upper bound of the indices
|
|
661 |
*/
|
|
662 |
ImageList.prototype.getImageCount = function() {
|
|
663 |
return this.imageIdx;
|
|
664 |
}
|
|
665 |
|
|
666 |
ImageList.prototype.getLastEnumerator = function() {
|
|
667 |
return this.lastEnum;
|
|
668 |
}
|
|
669 |
|
|
670 |
/**
|
|
671 |
* Generate code to set up a CGulIcon icon array. Since S60 doesn't
|
|
672 |
* tolerate empty arrays, the generated code allocates the array only if needed,
|
|
673 |
* leaving it on the cleanup stack. The caller of this code/routine
|
|
674 |
* needs to examine the return value and handle cleaning up appropriately.
|
|
675 |
* @param contribs
|
|
676 |
* @param iconsVar name of array variable to create (must be declared)
|
|
677 |
* @param location the function to add code to
|
|
678 |
* @param mainLocation preferably owned section in main file to add function to if needed
|
|
679 |
* @param instance instance to search upwards for owning class
|
|
680 |
* @param isScaling true if scaling bitmaps and icons, false otherwise
|
|
681 |
* @return true if icon array allocated
|
|
682 |
*/
|
|
683 |
ImageList.prototype.generateSetupIconArrayL = function(contribs, iconsVar, location, mainLocation, instance, isScaling) {
|
|
684 |
// must not generate a zero-size array or set an empty icon array
|
|
685 |
var anyIcons = false;
|
|
686 |
|
|
687 |
var iconVar = (iconsVar.match(".*s") ? iconsVar.substring(0, iconsVar.length - 1) : iconsVar + "_instance");
|
|
688 |
|
|
689 |
for (var iter = this.imageMap.entrySet().iterator(); iter.hasNext(); ) {
|
|
690 |
var entry = iter.next();
|
|
691 |
var key = entry.getKey();
|
|
692 |
var value = entry.getValue();
|
|
693 |
var property = value[IL_PROPERTY_INDEX];
|
|
694 |
var index = value[IL_INDEX_INDEX];
|
|
695 |
var enm = value[IL_ENUM_INDEX];
|
|
696 |
var granularity = this.enumSet.size() > 0? this.enumSet.size() : 1;
|
|
697 |
|
|
698 |
if (!anyIcons) {
|
|
699 |
addFormattedContrib(contribs, null, location, 0,
|
|
700 |
"{0} = new (ELeave) CAknIconArray( {1} );\n",
|
|
701 |
[ iconsVar,
|
|
702 |
granularity
|
|
703 |
] );
|
|
704 |
|
|
705 |
addFormattedContrib(contribs, null, location, 0,
|
|
706 |
"CleanupStack::PushL( {0} );\n",
|
|
707 |
[ iconsVar ]);
|
|
708 |
|
|
709 |
if (isScaling) {
|
|
710 |
defineIconLoadingRoutines(contribs, mainLocation, getClassHolder(instance).properties["className"]);
|
|
711 |
}
|
|
712 |
|
|
713 |
addFormattedContrib(contribs, null, location, 0,
|
|
714 |
"CGulIcon* {0};\n",
|
|
715 |
[ iconVar ]);
|
|
716 |
|
|
717 |
anyIcons = true;
|
|
718 |
}
|
|
719 |
|
|
720 |
//println("querying " + instance + ", property="+property);
|
|
721 |
|
|
722 |
// This assumes the user doesn't modify the ordering and
|
|
723 |
// all enums map evenly to 0...N.
|
|
724 |
// We can't use ->InsertL or ->ExtendL since they're stupid.
|
|
725 |
var adder = "->AppendL";
|
|
726 |
|
|
727 |
// Bug 7621: please ensure that a leave in the AppendL doesn't
|
|
728 |
// leak the allocated image.
|
|
729 |
var saveIcon = "CleanupStack::PushL( " + iconVar + " );\n";
|
|
730 |
var restoreIcon = "CleanupStack::Pop( " + iconVar + " );\n";
|
|
731 |
var addIcon = iconsVar + adder + "( " + iconVar + " );\n";
|
|
732 |
var saveAddAndRestore = saveIcon + addIcon + restoreIcon;
|
|
733 |
|
|
734 |
contrib = Engine.createContributionForLocation(location);
|
|
735 |
contrib.setText("// for " + enm + "\n");
|
|
736 |
contribs.add(contrib);
|
|
737 |
|
|
738 |
if (property == null) {
|
|
739 |
// system image
|
|
740 |
var parts = key.split("\\|");
|
|
741 |
|
|
742 |
var contrib = Engine.createContributionForPhase("MainSystemIncludes");
|
|
743 |
contrib.setText("#include <aknconsts.h>\n");
|
|
744 |
contribs.add(contrib);
|
|
745 |
|
|
746 |
contrib = Engine.createContributionForPhase("MainSystemIncludes");
|
|
747 |
contrib.setText("#include <avkon.mbg>\n");
|
|
748 |
contribs.add(contrib);
|
|
749 |
|
|
750 |
var format;
|
|
751 |
|
|
752 |
if (isScaling) {
|
|
753 |
if (parts[2] != "") {
|
|
754 |
format = iconVar + " = LoadAndScaleIconL(\n\t\t{0}, {1}, {2},\n\t\tNULL, EAspectRatioPreserved );\n"
|
|
755 |
+ saveAddAndRestore;
|
|
756 |
} else {
|
|
757 |
format = iconVar + " = LoadAndScaleIconL(\n\t\t{0}, {1}, -1,\n\t\tNULL, EAspectRatioPreserved );\n"
|
|
758 |
+ saveAddAndRestore;
|
|
759 |
}
|
|
760 |
} else {
|
|
761 |
if (parts[2] != "") {
|
|
762 |
format = iconVar + " = CEikonEnv::Static()->CreateIconL(\n\t\t{0}, {1}, {2} );\n"
|
|
763 |
+ saveAddAndRestore;
|
|
764 |
} else {
|
|
765 |
format = iconVar + " = CEikonEnv::Static()->CreateIconL(\n\t\t{0}, {1} );\n"
|
|
766 |
+ saveAddAndRestore;
|
|
767 |
}
|
|
768 |
}
|
|
769 |
contrib = Engine.createContributionForLocation(location);
|
|
770 |
contrib.setFormattedText(format, parts);
|
|
771 |
contribs.add(contrib);
|
|
772 |
|
|
773 |
} else {
|
|
774 |
if (isScaling) {
|
|
775 |
setupImageFromPropertyViaTuple(contribs, instance, null, location, 0,
|
|
776 |
property,
|
|
777 |
iconVar + " = LoadAndScaleIconL(\n\t\t{0}, {1}, -1,\n\t\tNULL, EAspectRatioPreserved );\n"
|
|
778 |
+ saveAddAndRestore,
|
|
779 |
iconVar + " = LoadAndScaleIconL(\n\t\t{0}, {1}, {2},\n\t\tNULL, EAspectRatioPreserved );\n"
|
|
780 |
+ saveAddAndRestore
|
|
781 |
);
|
|
782 |
} else {
|
|
783 |
setupImageFromPropertyViaTuple(contribs, instance, null, location, 0,
|
|
784 |
property,
|
|
785 |
iconVar + " = CEikonEnv::Static()->CreateIconL(\n\t\t{0}, {1} );\n"
|
|
786 |
+ saveAddAndRestore,
|
|
787 |
iconVar + " = CEikonEnv::Static()->CreateIconL(\n\t\t{0}, {1}, {2} );\n"
|
|
788 |
+ saveAddAndRestore);
|
|
789 |
}
|
|
790 |
}
|
|
791 |
}
|
|
792 |
|
|
793 |
if (anyIcons) {
|
|
794 |
return true;
|
|
795 |
}
|
|
796 |
else
|
|
797 |
return false;
|
|
798 |
}
|
|
799 |
|
|
800 |
/**
|
|
801 |
* Generate text to be substituted into an enum{} declaration.
|
|
802 |
*/
|
|
803 |
ImageList.prototype.generateImageListEnums = function() {
|
|
804 |
var text = "";
|
|
805 |
for (var iter = this.imageMap.entrySet().iterator(); iter.hasNext(); ) {
|
|
806 |
var entry = iter.next();
|
|
807 |
var index = entry.getValue()[IL_INDEX_INDEX];
|
|
808 |
var enm = entry.getValue()[IL_ENUM_INDEX];
|
|
809 |
text += enm + " = " + index + ",\n";
|
|
810 |
}
|
|
811 |
text += "E" + titleCase(this.ownerInstance.name) + "FirstUserImageIndex\n";
|
|
812 |
return text;
|
|
813 |
}
|
|
814 |
|
|
815 |
ImageList.prototype.dump = function() {
|
|
816 |
println("dump of image list: ");
|
|
817 |
for (var iter = this.imageMap.entrySet().iterator(); iter.hasNext(); ) {
|
|
818 |
var entry = iter.next();
|
|
819 |
var key = entry.getKey();
|
|
820 |
var value = entry.getValue();
|
|
821 |
var property = value[IL_PROPERTY_INDEX];
|
|
822 |
var index = value[IL_INDEX_INDEX];
|
|
823 |
|
|
824 |
println("key="+key+", property="+property+", index="+index);
|
|
825 |
}
|
|
826 |
}
|