001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package javax.microedition.lcdui;
028:
029: import com.sun.midp.i3test.*;
030:
031: public class TestStringItemSizing extends TestCase {
032:
033: /**
034: * Maximum width available for items.
035: */
036: private final int MAX_WIDTH = 220;
037:
038: // Parameter order for PLAIN_PRMS, HYPERLINK_PRMS, BUTTON_PRMS arrays
039: private final int ITEM_LEFT_PAD = 0;
040: private final int ITEM_RIGHT_PAD = 1;
041: private final int ITEM_TOP_PAD = 2;
042: private final int ITEM_BOTTOM_PAD = 3;
043:
044: private final int CONTENT_LEFT_PAD = 4;
045: private final int CONTENT_RIGHT_PAD = 5;
046: private final int CONTENT_TOP_PAD = 6;
047: private final int CONTENT_BOTTOM_PAD = 7;
048:
049: private final int LABEL_BODY_HORIZ_PAD = 8;
050: private final int LABEL_BODY_VERTICAL_PAD = 9;
051:
052: private final int LABEL_I_WIDTH = 10;
053: private final int LABEL_FONT_HEIGHT = 11;
054: private final int TEXT_I_WIDTH = 12;
055: private final int TEXT_FONT_HEIGHT = 13;
056:
057: // Padding, 'i' width and height values for
058: // different appearances of StringItem
059: private final int PLAIN_PRMS[] = new int[] { 4, 4, 4, 4, 0, 0, 0,
060: 0, 4, 0, 3, 13, 3, 15 };
061: private final int HYPERLINK_PRMS[] = new int[] { 4, 4, 4, 4, 0, 0,
062: 0, 0, 4, 0, 3, 13, 3, 15 };
063: private final int BUTTON_PRMS[] = new int[] { 4, 4, 4, 4, 5, 5, 5,
064: 5, 4, 0, 3, 13, 3, 15 };
065:
066: // StringItem types (in terms of internal layout)
067: private final int EMPTY = 0;
068: private final int EMPTY_LABEL = 1; // text can be multiline
069: private final int EMPTY_TEXT = 2; // label can be multiline
070: private final int SAME_LINE = 3; // both text and label present (no \n)
071: private final int MULT_LINE = 4; // both text and label present
072:
073: private final String[] appearanceModeNames = new String[] {
074: new String("Item.PLAIN"), new String("Item.HYPERLINK"),
075: new String("Item.BUTTON") };
076:
077: // The following StringItems are empty or are so narrow that we
078: // assume that they can be displayed with word wrapping
079: StringItemInfo itemInfos[] = {
080: //-------------Empty stringItems ----------------------------------
081: new StringItemInfo(new StringItem(null, null), EMPTY,
082: "StringItem(null, null"),
083: new StringItemInfo(new StringItem("", ""), EMPTY,
084: "StringItem(\"\", \"\""),
085: new StringItemInfo(new StringItem(null, ""), EMPTY,
086: "StringItem(null, \"\""),
087: new StringItemInfo(new StringItem("", null), EMPTY,
088: "StringItem(\"\", null"),
089: //--------------End of line --------------------------------------
090: new StringItemInfo(new StringItem("", "\n"), EMPTY_LABEL,
091: "StringItem(\"\", \"\\n\""),
092: new StringItemInfo(new StringItem("\n", ""), EMPTY_TEXT,
093: "StringItem(\"\\n\", \"\""),
094: //--------------Empty label - Single line text----------------------
095: new StringItemInfo(new StringItem(null, "i"), EMPTY_LABEL,
096: "StringItem(null, \"i\""),
097: //--------------Empty text - Single line label----------------------
098: new StringItemInfo(new StringItem("i", null), EMPTY_TEXT,
099: "StringItem(\"i\", null"),
100: //--------------Narrow label and text on the same line
101: new StringItemInfo(new StringItem("i", "i"), SAME_LINE,
102: "StringItem(\"i\", \"i\""),
103: //-------------Label or text is multiline---------
104: new StringItemInfo(new StringItem("i\ni", ""), EMPTY_TEXT,
105: "StringItem(\"i\\ni\", \"\""),
106: new StringItemInfo(new StringItem("", "i\ni"), EMPTY_LABEL,
107: "StringItem(\"\", \"i\\ni\""),
108: //-------------Narrow label and text are multiline
109: new StringItemInfo(new StringItem("ii\ni", "i\nii"),
110: MULT_LINE, "StringItem(\"ii\\ni\", \"i\\nii\"") };
111:
112: // the following 2 arrays represent different appearances that
113: // a StringItem could be created with (appearance is modified by
114: // add/remove commands)
115: // each strItem in the itemInfos[].strItem should be tested with
116: // all appearances modes from modes[] with a command added or note
117: // based on corresponding addCommands[] value
118: int modes[] = new int[] { Item.PLAIN, Item.HYPERLINK, Item.BUTTON,
119: Item.PLAIN, Item.HYPERLINK, Item.BUTTON };
120:
121: boolean addCommands[] = new boolean[] { false, true, true, true,
122: false, false };
123:
124: // The sizing of the following StringItems is available width dependent
125: StringItemInfo itemInfosWidthDependent[] = new StringItemInfo[] {
126: // ------------- Label and text on the same line
127: new StringItemInfo(new StringItem(
128: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
129: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", Item.PLAIN),
130: SAME_LINE, "StringItem(34is, 35is, Item.PLAIN)"),
131: new StringItemInfo(new StringItem(
132: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
133: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
134: Item.HYPERLINK), SAME_LINE,
135: "StringItem(34is, 35is, Item.HYPERLINK)"),
136: new StringItemInfo(
137: new StringItem(
138: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
139: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
140: Item.BUTTON), SAME_LINE,
141: "StringItem(33is, 33is, Item.BUTTON)"),
142: new StringItemInfo(new StringItem(
143: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
144: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
145: Item.HYPERLINK), SAME_LINE,
146: "StringItem(34is, 35is, Item.HYPERLINK) command added"),
147: new StringItemInfo(new StringItem(
148: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
149: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", Item.BUTTON),
150: SAME_LINE,
151: "StringItem(33is, 33is, Item.BUTTON) command added"),
152: new StringItemInfo(new StringItem(
153: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
154: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", Item.PLAIN),
155: SAME_LINE,
156: "StringItem(34is, 35is, Item.PLAIN) command added"),
157:
158: //--------------Label and text on multiple lines
159: new StringItemInfo(new StringItem(
160: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
161: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", Item.PLAIN),
162: MULT_LINE, "StringItem(35is, 35is, Item.PLAIN)"),
163: new StringItemInfo(new StringItem(
164: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
165: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
166: Item.HYPERLINK), MULT_LINE,
167: "StringItem(35is, 35is, Item.HYPERLINK)"),
168: new StringItemInfo(
169: new StringItem(
170: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
171: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
172: Item.BUTTON), MULT_LINE,
173: "StringItem(35is, 35is, Item.BUTTON)"),
174: new StringItemInfo(new StringItem(
175: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
176: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
177: Item.HYPERLINK), MULT_LINE,
178: "StringItem(35is, 35is, Item.HYPERLINK) command added"),
179: new StringItemInfo(
180: new StringItem(
181: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
182: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
183: Item.BUTTON), MULT_LINE,
184: "StringItem(35is, 35is, Item.BUTTON) command added"),
185: new StringItemInfo(new StringItem(
186: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii",
187: "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", Item.PLAIN),
188: MULT_LINE,
189: "StringItem(35is, 35is, Item.PLAIN) command added") };
190:
191: boolean addCommandsToWidthDepInfos[] = new boolean[] { false,
192: false, false, true, true, true, false, false, false, true,
193: true, true };
194:
195: // -----------------------------------------------------------------------
196: // utilities
197:
198: StringItemInfo[] createTestArray() {
199:
200: StringItemInfo newItemInfos[] = new StringItemInfo[itemInfos.length
201: * modes.length + itemInfosWidthDependent.length];
202:
203: Command c = new Command("", Command.ITEM, 1);
204:
205: for (int j, mode = 0; mode < modes.length; mode++) {
206:
207: j = itemInfos.length * mode;
208:
209: for (int i = 0; i < itemInfos.length; i++, j++) {
210: newItemInfos[j] = new StringItemInfo(new StringItem(
211: itemInfos[i].strItem.label,
212: itemInfos[i].strItem.str, modes[mode]),
213: itemInfos[i].type, itemInfos[i].description
214: + ", "
215: + appearanceModeNames[modes[mode]]
216: + ")"
217: + (addCommands[mode] ? " command added"
218: : ""));
219:
220: if (addCommands[mode]) {
221: newItemInfos[j].strItem.addCommand(c);
222: }
223: }
224: }
225:
226: // Copy elements from itemInfosWidthDependent and add commands
227: // if needed
228: System.arraycopy(itemInfosWidthDependent, 0, newItemInfos,
229: itemInfos.length * modes.length,
230: itemInfosWidthDependent.length);
231:
232: for (int i = itemInfos.length * modes.length, j = 0; i < newItemInfos.length; i++, j++) {
233: if (addCommandsToWidthDepInfos[j]) {
234: newItemInfos[i].strItem.addCommand(c);
235: }
236: }
237:
238: return newItemInfos;
239: }
240:
241: int calculateWidthEmptyLabel(int params[], int numOfIperLine[]) {
242: int maxIs = 0;
243: for (int i = 0; i < numOfIperLine.length; i++) {
244: if (numOfIperLine[i] > maxIs) {
245: maxIs = numOfIperLine[i];
246: }
247: }
248: return params[ITEM_LEFT_PAD] + params[CONTENT_LEFT_PAD] + maxIs
249: * params[TEXT_I_WIDTH] + params[CONTENT_RIGHT_PAD]
250: + params[ITEM_RIGHT_PAD];
251: }
252:
253: int calculateHeightEmptyLabel(int params[], int numOfLines) {
254: return params[ITEM_TOP_PAD] + params[CONTENT_LEFT_PAD]
255: + params[TEXT_FONT_HEIGHT] * numOfLines
256: + params[CONTENT_RIGHT_PAD] + params[ITEM_BOTTOM_PAD];
257: }
258:
259: int calculateWidthEmptyText(int params[], int numOfIperLine[]) {
260: int maxIs = 0;
261: for (int i = 0; i < numOfIperLine.length; i++) {
262: if (numOfIperLine[i] > maxIs) {
263: maxIs = numOfIperLine[i];
264: }
265: }
266: return params[ITEM_LEFT_PAD] + maxIs * params[LABEL_I_WIDTH]
267: + params[ITEM_RIGHT_PAD];
268: }
269:
270: int calculateHeightEmptyText(int params[], int numOfLines) {
271: return params[ITEM_TOP_PAD] + params[LABEL_FONT_HEIGHT]
272: * numOfLines + params[ITEM_BOTTOM_PAD];
273: }
274:
275: int calculateWidthSameLine(int params[], int labelNumOfI,
276: int textNumOfI) {
277: return params[ITEM_LEFT_PAD] + labelNumOfI
278: * params[LABEL_I_WIDTH] + params[LABEL_BODY_HORIZ_PAD]
279: + params[CONTENT_LEFT_PAD] + textNumOfI
280: * params[TEXT_I_WIDTH] + params[CONTENT_RIGHT_PAD]
281: + params[ITEM_RIGHT_PAD];
282: }
283:
284: int calculateHeightSameLine(int params[]) {
285: int contentHeight = params[CONTENT_LEFT_PAD]
286: + params[TEXT_FONT_HEIGHT] + params[CONTENT_RIGHT_PAD];
287: return params[ITEM_TOP_PAD]
288: + params[ITEM_BOTTOM_PAD]
289: + (params[LABEL_FONT_HEIGHT] > contentHeight ? params[LABEL_FONT_HEIGHT]
290: : contentHeight);
291: }
292:
293: int calculateWidthMultLines(int params[], int labelNumOfIperLine[],
294: int textNumOfIperLine[]) {
295: int labelMaxI = 0;
296: for (int i = 0; i < labelNumOfIperLine.length; i++) {
297: if (labelNumOfIperLine[i] > labelMaxI) {
298: labelMaxI = labelNumOfIperLine[i];
299: }
300: }
301: labelMaxI *= params[LABEL_I_WIDTH];
302:
303: int textMaxI = 0;
304: for (int i = 0; i < textNumOfIperLine.length; i++) {
305: if (textNumOfIperLine[i] > textMaxI) {
306: textMaxI = textNumOfIperLine[i];
307: }
308: }
309: textMaxI *= params[TEXT_I_WIDTH];
310: textMaxI += params[CONTENT_LEFT_PAD]
311: + params[CONTENT_RIGHT_PAD];
312:
313: return params[ITEM_LEFT_PAD] + params[ITEM_RIGHT_PAD]
314: + (labelMaxI > textMaxI ? labelMaxI : textMaxI);
315: }
316:
317: int calculateHeightMultLines(int params[], int labelNumLines,
318: int textNumLines) {
319: return params[ITEM_TOP_PAD] + labelNumLines
320: * params[LABEL_FONT_HEIGHT]
321: + params[LABEL_BODY_VERTICAL_PAD]
322: + params[CONTENT_TOP_PAD] + labelNumLines
323: * params[TEXT_FONT_HEIGHT] + params[CONTENT_BOTTOM_PAD]
324: + params[ITEM_BOTTOM_PAD];
325: }
326:
327: // it is assumed in the following function that all 'i's following each
328: // other can fit on one line. '\n' is the only line break
329: // All characters other than '\n' should be 'i'
330: int[] getNumOfIsPerLine(String str) {
331: if (str == null || str.length() == 0) {
332: return new int[] { 0 };
333: }
334:
335: int lines = 1;
336: for (int i = 0; i < str.length(); i++) {
337: if (str.charAt(i) == '\n') {
338: lines++;
339: }
340: }
341:
342: int return_array[] = new int[lines];
343: int j = 0, numOfIs = 0;
344: for (int i = 0; i < str.length(); i++) {
345: if (str.charAt(i) == '\n') {
346: return_array[j] = numOfIs;
347: numOfIs = 0;
348: j++;
349: } else {
350: numOfIs++;
351: }
352: }
353:
354: return_array[j] = numOfIs;
355:
356: return return_array;
357: }
358:
359: int[] getParameters(StringItem strItem) {
360: // Hyperlink and Button appearance settings are ignored
361: // if there are no commands added
362:
363: // If a command is added to a StringItem with PLAIN appearance mode
364: // it is changed to be HYPERLINK
365:
366: switch (strItem.getAppearanceMode()) {
367: case Item.PLAIN:
368: return (strItem.numCommands == 0 ? PLAIN_PRMS
369: : HYPERLINK_PRMS);
370:
371: case Item.HYPERLINK:
372: return (strItem.numCommands == 0 ? PLAIN_PRMS
373: : HYPERLINK_PRMS);
374:
375: case Item.BUTTON:
376: return (strItem.numCommands == 0 ? PLAIN_PRMS : BUTTON_PRMS);
377: }
378: return null;
379: }
380:
381: int calculateWidth(StringItem strItem, int type) {
382:
383: int params[] = getParameters(strItem);
384:
385: switch (type) {
386: case EMPTY:
387: return 0;
388:
389: case EMPTY_LABEL:
390: return calculateWidthEmptyLabel(params,
391: getNumOfIsPerLine(strItem.str));
392:
393: case EMPTY_TEXT:
394: return calculateWidthEmptyText(params,
395: getNumOfIsPerLine(strItem.label));
396:
397: case SAME_LINE:
398: // we rely on the fact that both label and text are present
399: // and not empty
400: return calculateWidthSameLine(params,
401: getNumOfIsPerLine(strItem.label)[0],
402: getNumOfIsPerLine(strItem.str)[0]);
403:
404: case MULT_LINE:
405: return calculateWidthMultLines(params,
406: getNumOfIsPerLine(strItem.label),
407: getNumOfIsPerLine(strItem.str));
408:
409: default:
410: System.err.println("Incorrect type passing");
411: return 0;
412: }
413: }
414:
415: int calculateHeight(StringItem strItem, int type) {
416:
417: int params[] = getParameters(strItem);
418:
419: switch (type) {
420: case EMPTY:
421: return 0;
422:
423: case EMPTY_LABEL:
424: return calculateHeightEmptyLabel(params,
425: getNumOfIsPerLine(strItem.str).length);
426:
427: case EMPTY_TEXT:
428: return calculateHeightEmptyText(params,
429: getNumOfIsPerLine(strItem.label).length);
430:
431: case SAME_LINE:
432: return calculateHeightSameLine(params);
433:
434: case MULT_LINE:
435: return calculateHeightMultLines(params,
436: getNumOfIsPerLine(strItem.label).length,
437: getNumOfIsPerLine(strItem.str).length);
438:
439: default:
440: System.err.println("Incorrect type passing");
441: return 0;
442: }
443: }
444:
445: // the tests
446:
447: public void testDefaultPreferredWidth(StringItemInfo strItemInfo) {
448: assertEquals(calculateWidth(strItemInfo.strItem,
449: strItemInfo.type), strItemInfo.strItem.stringItemLF
450: .lGetPreferredWidth(-1));
451: }
452:
453: public void testDefaultPreferredHeight(StringItemInfo strItemInfo) {
454: assertEquals(calculateHeight(strItemInfo.strItem,
455: strItemInfo.type), strItemInfo.strItem.stringItemLF
456: .lGetPreferredHeight(-1));
457: }
458:
459: public void runTests() {
460:
461: StringItemInfo newItemInfos[] = createTestArray();
462:
463: for (int i = 0; i < newItemInfos.length; i++) {
464: declare("testPreferredWidth StringItem("
465: + newItemInfos[i].description);
466: testDefaultPreferredWidth(newItemInfos[i]);
467:
468: declare("testPreferredHeight StringItem("
469: + newItemInfos[i].description);
470: testDefaultPreferredHeight(newItemInfos[i]);
471: }
472: }
473:
474: class StringItemInfo {
475: StringItemInfo(StringItem strItem, int type, String description) {
476: this .strItem = strItem;
477: this .type = type;
478: this .description = description;
479: }
480:
481: StringItem strItem;
482: int type;
483: String description;
484: };
485: }
|