uidesigner/com.nokia.sdt.series60.componentlibrary/components/transient/popupDialogLibrary.js
changeset 2 d760517a8095
equal deleted inserted replaced
-1:000000000000 2:d760517a8095
       
     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 // Note that the rendering is not quite accurate with long text, since
       
    22 // text flows around the icon.
       
    23 
       
    24 /**
       
    25  *	Get the width of a standard popup dialog
       
    26  */
       
    27 function getStandardDialogWidth(laf) {
       
    28 	var padding = laf.getInteger("note.padding", 8);
       
    29 	var screenSize = laf.getDimension("screen.size");
       
    30 	return Math.min(screenSize.x, screenSize.y) - 4 * padding;
       
    31 }
       
    32 
       
    33 /**
       
    34  *	Get the left edge of a popup dialog relative to its instance bounds 
       
    35  *	when the instance also draws a CBA 
       
    36  */
       
    37 function getLeftOfDialogWithCBA(laf) {
       
    38 	var width = getStandardDialogWidth(laf);
       
    39 	if (laf.getBoolean("is.portrait", false)) {
       
    40 		var contentBounds = laf.getRectangle("content.pane.bounds");
       
    41 		return contentBounds.x + (contentBounds.width - width) / 2; 
       
    42 	}
       
    43 
       
    44 	return 0; // in landscape the dialog and instance are the same
       
    45 }
       
    46 
       
    47 /**
       
    48  *	Get the rectangle in which to draw the icon
       
    49  */
       
    50 function getIconRect(dialogLeft, laf) {
       
    51 	var iconSize = laf.getDimension("note.icon.size");
       
    52 	var padding = laf.getInteger("note.padding", 2);
       
    53 	var width = getStandardDialogWidth(laf);
       
    54 	var iconRect = new Rectangle(
       
    55 			width - iconSize.x - padding*2, 
       
    56 			0, iconSize.x, iconSize.y);
       
    57 	return iconRect;
       
    58 }
       
    59 
       
    60 /**
       
    61  *	Calculate the bounding rectangle,
       
    62  *	adjusting the height to contain all the text.
       
    63  *	@param flags the Font flags
       
    64  */
       
    65 function calculateBounds(properties, laf, flags, iconLeft, dialogLeft) {
       
    66 	var rect = new Rectangle(0, 0, 0, 0);
       
    67 	
       
    68 	var portrait = laf.getBoolean("is.portrait", true);
       
    69 	var d = laf.getDimension("screen.size");
       
    70 	var content = laf.getRectangle("content.pane.bounds");
       
    71 	
       
    72 	var padding = laf.getInteger("note.padding", 2);
       
    73 	rect.width = Math.min(d.x, d.y) - padding*2;
       
    74 	if (portrait) {
       
    75 		rect.x = content.x + (content.width - rect.width) / 2; 
       
    76 	}
       
    77 	else {
       
    78 		rect.x = d.x - rect.width;
       
    79 	}
       
    80 		
       
    81 	var font = laf.getFont("message.font");
       
    82 
       
    83 	var info = getTextInfo(properties, laf, font, flags, iconLeft, dialogLeft);
       
    84 	var extent = info[0];
       
    85 	var text = info[1];
       
    86 	var maxWidth = info[2];
       
    87 	var lineGap = info[3];
       
    88 	
       
    89 	var height = extent.y + 7*2 + lineGap
       
    90 	
       
    91 	if (portrait)
       
    92 		rect.y = content.y + content.height - height - padding;
       
    93 	else
       
    94 		rect.y = (d.y - height) / 2;
       
    95 
       
    96 	rect.height = height;
       
    97 	
       
    98 	// adjust for insets
       
    99 	var inset = laf.getDimension("note.inset");
       
   100 	rect.x += inset.x;
       
   101 	rect.width -= (2 * inset.x);
       
   102 	rect.height -= (2 * inset.y);
       
   103 	
       
   104 	// add pixels for shadow
       
   105 	rect.width += 3;
       
   106 	rect.height += 3;
       
   107 	
       
   108 	return rect;
       
   109 }
       
   110 
       
   111 function getTextInfo(properties, laf, font, flags, iconLeft, dialogLeft) {
       
   112 	var padding = laf.getInteger("note.padding", 8);
       
   113 
       
   114 	var maxWidth = iconLeft - padding*(3+2) - dialogLeft;
       
   115 	
       
   116 	var lineGap = laf.getInteger("note.text.lineGap", 0);
       
   117 	var minExtent = font.formattedStringExtent("Hello",
       
   118 		new Point(maxWidth, 0), flags, lineGap);
       
   119 	minExtent.y *= 3;
       
   120 	var text = chooseScalableText(properties.text, font, maxWidth);
       
   121 	var extent = calculateWrappedTextSize(text, maxWidth, font, flags, lineGap, 5);
       
   122 
       
   123 	if (extent.y < minExtent.y)
       
   124 		extent.y = minExtent.y;
       
   125 
       
   126 	return [extent, text, maxWidth, lineGap];
       
   127 }
       
   128 
       
   129 function isNote(instance) {
       
   130 	return (instance.isInstanceOf("com.nokia.sdt.series60.StandardNote") ||
       
   131 		    instance.isInstanceOf("com.nokia.sdt.series60.GlobalNote"));
       
   132 }
       
   133 
       
   134 function isConfirmationQuery(instance) {
       
   135 	return instance.isInstanceOf("com.nokia.sdt.series60.ConfirmationQuery");
       
   136 }
       
   137 
       
   138 function isProgress(instance) {
       
   139 	// add progress dialog here when we add that component
       
   140 	return instance.isInstanceOf("com.nokia.sdt.series60.WaitDialog");
       
   141 }
       
   142 
       
   143 function isDataQuery(instance) {
       
   144 	return instance.isInstanceOf("com.nokia.sdt.series60.SingleLineDataQuery") ||
       
   145 		instance.isInstanceOf("com.nokia.sdt.series60.MultiLineDataQuery");
       
   146 }
       
   147 
       
   148 function getIcon(instance, laf) {
       
   149 	var properties = instance.properties;
       
   150 	if (isNote(instance)) {
       
   151 		if (properties.type != null) {
       
   152 			var fileBase = "note." + properties.type.toString() + ".icon";
       
   153 			return laf.getImage(fileBase);
       
   154 		}
       
   155 	}
       
   156 	else if (isConfirmationQuery(instance)) {
       
   157 		return laf.getImage("note.query.icon");
       
   158 	} else if (isProgress(instance)) {
       
   159 		return laf.getImage("note.progress.icon");
       
   160 	}
       
   161 	
       
   162 	return null;
       
   163 }
       
   164 
       
   165 function drawPopupDialog(instance, laf, graphics, flags, bounds, iconRect, dialogLeft) {
       
   166 	var properties = instance.properties;
       
   167 	var font = laf.getFont("message.font");
       
   168 	graphics.setFont(font);
       
   169 	
       
   170 	var padding = laf.getInteger("note.padding", 8);
       
   171 	
       
   172 	// get bounding rects
       
   173 	var info = getTextInfo(properties, laf, font, flags, iconRect.x, dialogLeft);
       
   174 	var extent = info[0];
       
   175 	extent.x += dialogLeft;
       
   176 	var text = info[1];
       
   177 	var maxWidth = info[2];
       
   178 	var lineGap = info[3];
       
   179 
       
   180 	var x = bounds.x;
       
   181 	var y = bounds.y;
       
   182 	var width = bounds.width - 3;
       
   183 	var height = bounds.height - 3;
       
   184 
       
   185 	// fill 
       
   186 	graphics.setBackground(getBackgroundColor(instance, laf))
       
   187 	graphics.fillRectangle(new Rectangle(x, y, width, height))
       
   188 	
       
   189 	// edge
       
   190 	graphics.setForeground(Colors.getColor(0, 0, 0))
       
   191 	graphics.drawRectangle(new Rectangle(x, y, width, height))
       
   192 
       
   193 	// shadows
       
   194 	graphics.setForeground(laf.getColor("control.shadow.inner"))
       
   195 	graphics.drawLine(x + 1, y + height + 1, x + width + 1, y + height + 1)
       
   196 	graphics.drawLine(x + width + 1, y + 1, x + width + 1, y + height + 1)
       
   197 	
       
   198 	graphics.setForeground(laf.getColor("control.shadow.outer"))
       
   199 	graphics.drawLine(x + 2, y + height + 2, x + width + 2, y + height + 2)
       
   200 	graphics.drawLine(x + width + 2, y + 2, x + width + 2, y + height + 2)
       
   201 
       
   202 	graphics.setForeground(laf.getColor("listitem.text"));
       
   203 	
       
   204 	// draw text
       
   205 	var textRect = new Rectangle(padding*4 + bounds.x, padding*3 + bounds.y, 
       
   206 		iconRect.width + iconRect.x - padding*4, bounds.height - padding*3);
       
   207 
       
   208 	// get widths of each text line, where the first two are on
       
   209 	// the same line as the icon
       
   210 	var widths = [ 
       
   211 		extent.x, // first two lines ...
       
   212 		extent.x, // ... go to the edge of the icon
       
   213 		textRect.width ];	// and the remaining lines fill the dialog
       
   214 	
       
   215 	//println("textRect="+textRect);
       
   216 	graphics.drawFormattedString(text,
       
   217 			textRect,
       
   218 			flags | Font.OVERFLOW_ELLIPSIS,
       
   219 			lineGap,
       
   220 			widths);
       
   221 
       
   222 	// draw icon
       
   223 	var image = getIcon(instance, laf);
       
   224 	if (image != null) {
       
   225 		var imageData = image.getImageData();
       
   226 		graphics.drawImage(image, 0, 0, imageData.width, imageData.height,
       
   227 			dialogLeft + iconRect.x, bounds.y + iconRect.y, iconRect.width, iconRect.height);
       
   228 	}
       
   229 	
       
   230 	// progress bar
       
   231 	if (isProgress(instance)) {
       
   232 		drawProgressBar(instance, graphics, laf, bounds);
       
   233 	}
       
   234 }
       
   235 
       
   236 function drawProgressBar(instance, graphics, laf, bounds) {
       
   237 	var isPortrait = laf.getBoolean("is.portrait", true);
       
   238 	var padding = laf.getInteger("note.padding", 8);
       
   239 	var progressX = padding*4+bounds.x;
       
   240 	var progressHeight = laf.getInteger("progress.bar.height", 10);
       
   241 	var progressWidth = bounds.width - (padding*8);
       
   242 	var progressY = bounds.y + bounds.height - laf.getInteger("note.progress.offsetFromBottom", 0);
       
   243 	var image = laf.getImage("note.progress.bar");
       
   244 	var imageData = image.getImageData();
       
   245 	graphics.drawImage(image, 0, 0, imageData.width, imageData.height,
       
   246 			progressX, progressY, progressWidth, progressHeight);
       
   247 
       
   248 }
       
   249 
       
   250 function getChildAttribute(instance, childIndex, attributeName) {
       
   251 	var children = instance.children;
       
   252 	if (children.length > childIndex) {
       
   253 		var child = instance.children[childIndex];
       
   254 		return child.attributes[attributeName];
       
   255 	}
       
   256 	
       
   257 	return null;
       
   258 }
       
   259 
       
   260 /**
       
   261  *	Combine two bounds into one, vertically stacking them, getting
       
   262  *	the maximum combined horizontal extent, and adding vertical
       
   263  *	padding in between.
       
   264  *	@param rect1 one rectangle
       
   265  *	@param rect2 another rectangle
       
   266  *	@return a rectangle at y=0.
       
   267  */
       
   268 function getStackedBounds(rect1, rect2) {
       
   269 	var height = rect1.height + this.padding + rect2.height;
       
   270 	var maxX = Math.max(rect1.x + rect1.width, rect2.x + rect2.width);
       
   271 	var minX = Math.min(rect1.x, rect2.x);
       
   272 	return new Rectangle(minX, 0, maxX - minX, height);
       
   273 }
       
   274 
       
   275 //////////////////////////////////////////////////////////////
       
   276 // Popup Visual Helper
       
   277 //////////////////////////////////////////////////////////////
       
   278 
       
   279 include("../renderLibrary.js")
       
   280 
       
   281 /**
       
   282  *
       
   283  * Required prototype implementations
       
   284  * 	IVisualAppearance
       
   285  * 	ILayout
       
   286  * 	IDirectLabelEdit
       
   287  *
       
   288  * Required additional prototype functions:
       
   289  * getIconRect();
       
   290  *
       
   291  */
       
   292 function setupPopupVisualHelper(prototype) {
       
   293 
       
   294 /**
       
   295  *	Calculate the text bounds for a dialog, allowing for an icon,
       
   296  *	wrapping, and a range of allowed lines.  This assumes the
       
   297  *	width of the dialog to start with.
       
   298  *	@return bounds of text in dialog
       
   299  */
       
   300 prototype.calculateTextBounds = function(properties, laf, text, font, flags, minLines, maxLines) {
       
   301 	var rect = new Rectangle(0, 0, 0, 0);
       
   302 	
       
   303 	var portrait = laf.getBoolean("is.portrait", true);
       
   304 	var d = laf.getDimension("screen.size");
       
   305 	var content = laf.getRectangle("content.pane.bounds");
       
   306 	
       
   307 	var padding = laf.getInteger("note.padding", 2);
       
   308 	if (portrait) {
       
   309 		rect.x = padding;
       
   310 		rect.width = d.x - padding*2;
       
   311 	}
       
   312 	else {
       
   313 		rect.x = d.x / 5;
       
   314 		rect.width = d.x - rect.x;
       
   315 	}
       
   316 		
       
   317 	var iconRect = this.getIconRect();
       
   318 	var maxWidth = rect.width - iconRect.x - padding*(3+2);
       
   319 	
       
   320 	var lineGap = laf.getInteger("note.text.lineGap", 0);
       
   321 	
       
   322 	var minExtent = font.formattedStringExtent("Hello", new Point(maxWidth, 0), flags, lineGap);
       
   323 	minExtent.y *= minLines;
       
   324 	
       
   325 	var text = chooseScalableText(properties.text, font, maxWidth);
       
   326 	var extent;
       
   327 	
       
   328 	if ((flags & Font.WRAPPING_ENABLED) != 0)
       
   329 		extent = calculateWrappedTextSize(text, maxWidth, font, flags, lineGap, maxLines);
       
   330 	else
       
   331 		extent = font.formattedStringExtent(text, 
       
   332 			new Point(maxWidth, 0), flags, lineGap);
       
   333 	
       
   334 	//println("extent="+extent);
       
   335 	if (extent.y < minExtent.y)
       
   336 		extent.y = minExtent.y;
       
   337 
       
   338 	return new Rectangle(rect.x, rect.y, extent.x, extent.y);
       
   339 }
       
   340 
       
   341 /**
       
   342  *	Calculate the bounding rectangle for the dialog so it contains the
       
   343  *	text, icon, and editor.
       
   344  *	@param textExtent size of text
       
   345  *	@param editRect rect for editor content at bottom (only size used)
       
   346  *	@return Rectangle (0, 0, width, height)
       
   347  */
       
   348 prototype.calculateDialogBounds = function(properties, laf, textExtent, editRect) {
       
   349 	var rect = new Rectangle(0, 0, 0, 0);
       
   350 	
       
   351 	var portrait = laf.getBoolean("is.portrait", true);
       
   352 	var d = laf.getDimension("screen.size");
       
   353 	var content = laf.getRectangle("content.pane.bounds");
       
   354 	
       
   355 	var padding = laf.getInteger("note.padding", 2);
       
   356 	if (portrait) {
       
   357 		rect.x = padding;
       
   358 		rect.width = d.x - padding*2;
       
   359 	}
       
   360 	else {
       
   361 		rect.x = d.x / 5;
       
   362 		rect.width = d.x - rect.x;
       
   363 	}
       
   364 		
       
   365 	var lineGap = laf.getInteger("note.text.lineGap", 0);
       
   366 	var height = textExtent.y + 7*2 + lineGap
       
   367 	
       
   368 	if (editRect)
       
   369 		height += editRect.height + lineGap*2;
       
   370 	
       
   371 	rect.height = height;
       
   372 	
       
   373 	// adjust for insets
       
   374 	var inset = laf.getDimension("note.inset");
       
   375 	rect.x += inset.x;
       
   376 	rect.width -= (2 * inset.x);
       
   377 	rect.height -= (2 * inset.y);
       
   378 	
       
   379 	return rect;
       
   380 }
       
   381 
       
   382 
       
   383 //	Draw a simple dialog with using the 'text' property and the label font
       
   384 prototype.drawPopupDialog = function(instance, laf, graphics, font, flags, textRect, bounds) {
       
   385 	var properties = instance.properties;
       
   386 
       
   387 	this.drawPopupDialogBorder(instance, laf, graphics, bounds);
       
   388 
       
   389 	var text = chooseScalableText(properties.text, font, textRect.width);
       
   390 	
       
   391 	var offset = new Point(bounds.x, bounds.y);
       
   392 	this.drawPopupDialogPromptAndIcon(instance, laf, graphics, text, font, flags, offset, textRect);
       
   393 }
       
   394 
       
   395 /**
       
   396  *	Draw dialog prompt and icon.
       
   397  *	@param flags text flags
       
   398  *	@param offset Point offset at which to bias the iconRect and textRect
       
   399  */
       
   400 prototype.drawPopupDialogPromptAndIcon = function(instance, laf, graphics, text, font, flags, offset, textRect) {
       
   401 	var properties = instance.properties;
       
   402 	graphics.setFont(font);
       
   403 
       
   404 	var padding = laf.getInteger("note.padding", 8);
       
   405 	
       
   406 	graphics.setForeground(laf.getColor("listitem.text"));
       
   407 
       
   408 	// draw text
       
   409 	textRect.x = properties.location.x + offset.x;
       
   410 	textRect.y = properties.location.y + offset.y;
       
   411 	
       
   412 	//println("drawPopupDialogPromptAndIcon textRect = " + textRect);
       
   413 	graphics.drawFormattedString(text,
       
   414 			textRect,
       
   415 			flags | Font.OVERFLOW_ELLIPSIS,
       
   416 			laf.getInteger("note.text.lineGap", 0));
       
   417 
       
   418 	// draw icon
       
   419 	var iconRect = this.getIconRect();
       
   420 	var image = getIcon(instance, laf);
       
   421 	if (image != null) {
       
   422 		var imageData = image.getImageData();
       
   423 		graphics.drawImage(image, 0, 0, imageData.width, imageData.height,
       
   424 			iconRect.x, offset.y + iconRect.y, iconRect.width, iconRect.height);
       
   425 	}
       
   426 }
       
   427 
       
   428 /**
       
   429  *	Draw dialog border, with shadows.  The bounds should enclose only
       
   430  *	the contents of the dialog (shadows drawn outside).
       
   431  */
       
   432 prototype.drawPopupDialogBorder = function(instance, laf, graphics, bounds) {
       
   433 	var padding = laf.getInteger("note.padding", 8);
       
   434 	
       
   435 	// get bounding rects
       
   436 	
       
   437 	var x = bounds.x;
       
   438 	var y = bounds.y;
       
   439 	var width = bounds.width;
       
   440 	var height = bounds.height;
       
   441 
       
   442 	// fill 
       
   443 	graphics.setBackground(getBackgroundColor(instance, laf))
       
   444 	graphics.fillRectangle(new Rectangle(x, y, width, height))
       
   445 	
       
   446 	// edge
       
   447 	graphics.setForeground(Colors.getColor(0, 0, 0))
       
   448 	graphics.drawRectangle(new Rectangle(x, y, width, height))
       
   449 
       
   450 	// shadows
       
   451 	graphics.setForeground(laf.getColor("control.shadow.inner"))
       
   452 	graphics.drawLine(x + 1, y + height + 1, x + width + 1, y + height + 1)
       
   453 	graphics.drawLine(x + width + 1, y + 1, x + width + 1, y + height + 1)
       
   454 	
       
   455 	graphics.setForeground(laf.getColor("control.shadow.outer"))
       
   456 	graphics.drawLine(x + 2, y + height + 2, x + width + 2, y + height + 2)
       
   457 	graphics.drawLine(x + width + 2, y + 2, x + width + 2, y + height + 2)
       
   458 }
       
   459 
       
   460 } // setupPopupVisualHelper
       
   461 
       
   462 function getPreviewPopUpHeadingFont(laf) {
       
   463 	return laf.getFont("message.font");
       
   464 }
       
   465 
       
   466 function getPreviewPopUpHeadingHeight(instance, laf) {
       
   467 	if (instance.properties.headingText.length > 0) {
       
   468 		var font = getPreviewPopUpHeadingFont(laf);
       
   469 		var height = getFontHeight(font);
       
   470 		var padding = height / 4;
       
   471 		return height + 2 * padding;
       
   472 	}
       
   473 	
       
   474 	return 0;
       
   475 }
       
   476 
       
   477 function drawFrame(rect, colorArray, graphics) {
       
   478 	var saveColor = graphics.getForeground();
       
   479 	for(var i in colorArray) {
       
   480 		var color = colorArray[i];
       
   481 		if (color != null) {
       
   482 			graphics.setForeground(color);
       
   483 			var sizeOffset = 2 * i;
       
   484 			graphics.drawRectangle(rect.x + i, rect.y + i, rect.width - sizeOffset, rect.height - sizeOffset);
       
   485 		}
       
   486 	}
       
   487 	graphics.setForeground(saveColor);
       
   488 }
       
   489 
       
   490 function drawPreviewPopUpHeading(instance, graphics, laf) {
       
   491 	var properties = instance.properties;
       
   492 	var width = properties.size.width;
       
   493 	var height = properties.size.height
       
   494 	var drawButton = !properties.EPermanentMode;
       
   495 	var font = getPreviewPopUpHeadingFont(laf);
       
   496 	graphics.setFont(font);
       
   497 	var fontHeight = getFontHeight(font);
       
   498 	var padding = fontHeight / 8;
       
   499 	var textWidth = width - fontHeight - 2 * padding; // room for close button
       
   500 	var textRect = new Rectangle(6 + padding, 6 + padding, textWidth, fontHeight + padding);
       
   501 	graphics.setBackground(getBackgroundColor(instance, laf));
       
   502 	if (!properties.EFixedMode) {
       
   503 		var gradColor = Colors.getColor(214,223,222);
       
   504 		graphics.setForeground(gradColor);
       
   505 		var headingRect = new Rectangle(6, 6, width - 6, textRect.height + padding + 4);
       
   506 		graphics.fillGradientRectangle(headingRect.x, headingRect.y, headingRect.width, headingRect.height, true);
       
   507 		graphics.setLineWidth(1);
       
   508 		graphics.setForeground(Colors.getColor(239,239,239));
       
   509 		graphics.drawLine(headingRect.x, headingRect.y + headingRect.height, 
       
   510 							headingRect.x + headingRect.width, headingRect.y + headingRect.height);
       
   511 		graphics.setForeground(Colors.getColor(239,235,239));
       
   512 		graphics.drawLine(headingRect.x, headingRect.y + headingRect.height + 1, 
       
   513 							headingRect.x + headingRect.width, headingRect.y + headingRect.height + 1);
       
   514 		if (drawButton) {
       
   515 			var buttonSize = 22;
       
   516 			var buttonRect = new Rectangle(width - buttonSize - 8, padding + 8, buttonSize, buttonSize);
       
   517 			graphics.setForeground(getBackgroundColor(instance, laf));
       
   518 			graphics.setBackground(gradColor);
       
   519 			graphics.fillGradientRectangle(buttonRect.x, buttonRect.y, buttonRect.width, buttonRect.height, true);
       
   520 			var middleRect = new Rectangle(
       
   521 								buttonRect.x + buttonRect.width / 2 - 1, 
       
   522 								buttonRect.y + buttonRect.height / 2 - 1,
       
   523 								2, 2);
       
   524 			graphics.setForeground(Colors.getColor(84,96,127));
       
   525 			graphics.drawRectangle(middleRect);
       
   526 			graphics.drawRectangle(buttonRect);
       
   527 			textRect.width -= buttonRect.width;
       
   528 		}
       
   529 	}
       
   530 	else {
       
   531 		graphics.fillRectangle(0, 0, width, height);
       
   532 	}
       
   533 	graphics.setForeground(Colors.getColor(84,96,127));
       
   534 	var titleText = chooseScalableText(properties.headingText, font, textRect.width);
       
   535 	graphics.drawFormattedString(titleText, textRect, Font.ALIGN_LEFT | Font.OVERFLOW_ELLIPSIS, 0);	
       
   536 }
       
   537