uidesigner/com.nokia.sdt.series60.componentlibrary/components/navipane/NaviTabs_visual.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("../containers/containerLibrary.js")
       
    20 include("../renderLibrary.js")
       
    21 include("../srcgenLibrary.js")
       
    22 
       
    23 function NaviTabsVisual() {
       
    24 }
       
    25 
       
    26 function getNaviSize(instance, laf) {
       
    27 	var properties = instance.properties;
       
    28 	return new Point(properties.size.width, properties.size.height);
       
    29 }
       
    30 
       
    31 function isLongTabs(instance) {
       
    32 	var property = instance.properties.tabWidth;
       
    33 	return ((property == "EAknTabWidthWithTwoLongTabs") || 
       
    34 		(property == "EAknTabWidthWithThreeLongTabs"));
       
    35 }
       
    36 
       
    37 function isOneTab(property) {
       
    38 	return (property == "EAknTabWidthWithOneTab"); 
       
    39 }
       
    40 
       
    41 function getNumVisualTabs(property) {
       
    42 	if ((property == "EAknTabWidthWithTwoTabs") ||
       
    43 		(property == "EAknTabWidthWithTwoLongTabs"))
       
    44 		return 2;
       
    45 	else if ((property == "EAknTabWidthWithThreeTabs") ||
       
    46 		(property == "EAknTabWidthWithThreeLongTabs"))
       
    47 		return 3;
       
    48 	else if (isOneTab(property))
       
    49 		return 1;
       
    50 		
       
    51 	return 4;
       
    52 }
       
    53 
       
    54 function getHorizontalInset(laf) {
       
    55 	return laf.getDimension("navi.indicator.size").x;
       
    56 }
       
    57 
       
    58 function getTabOffset(totalWidth, longTabs, numVisualTabs, laf) {
       
    59 	if (longTabs)
       
    60 		return totalWidth / 18;
       
    61 	
       
    62 	var width = totalWidth - (2 * getHorizontalInset(laf));
       
    63 	return (width / numVisualTabs) - (2 * laf.getInteger("tab.corner", 3));
       
    64 }
       
    65 
       
    66 function getTabWidth(totalWidth, numVisualTabs, longTabs, laf) {
       
    67 	var sideInset = getHorizontalInset(laf);
       
    68 	return totalWidth - (2 * sideInset) - ((numVisualTabs - 1) * getTabOffset(totalWidth, longTabs, numVisualTabs, laf));
       
    69 }
       
    70 
       
    71 function getNumTabs(instance) {
       
    72 	var appUi = instance.parent.parent;
       
    73 	var numTabs = 0;
       
    74 	for (var i in appUi.children) {
       
    75 		if (appUi.children[i].isInstanceOf("com.nokia.sdt.series60.AvkonViewReference")) {
       
    76 			if (appUi.children[i].properties.inTabGroup)
       
    77 				numTabs++;
       
    78 		}
       
    79 	}
       
    80 	
       
    81 	return numTabs;
       
    82 }
       
    83 
       
    84 function drawTab(r, laf, graphics, isActive) {
       
    85 	var offset = laf.getInteger("tab.corner", 3);
       
    86 	
       
    87 	var intArray = [	
       
    88 					r.x,
       
    89 					r.y + r.height,
       
    90 					r.x + offset,
       
    91 					r.y + r.height - offset,
       
    92 					r.x + (4 * offset),
       
    93 					r.y + offset, 
       
    94 					r.x + (5 * offset),
       
    95 					r.y,
       
    96 					r.x + r.width - (5 * offset),
       
    97 					r.y,
       
    98 					r.x + r.width - (4 * offset),
       
    99 					r.y + offset,
       
   100 					r.x + r.width - offset,
       
   101 					r.y + r.height - offset,
       
   102 					r.x + r.width,
       
   103 					r.y + r.height,
       
   104 					];
       
   105 
       
   106 	if (laf.getBoolean("is.landscape", false)) {
       
   107 		for (var i = 0; i < intArray.length; i++) {
       
   108 			if ((i % 2) != 0) {
       
   109 				var yval = intArray[i];
       
   110 				intArray[i] = r.height - yval;
       
   111 			}
       
   112 		}
       
   113 	}
       
   114 
       
   115 	var faceColor = isActive ? laf.getColor("navi.tab.face") : laf.getColor("navi.tab.back");
       
   116 	graphics.setBackground(faceColor);
       
   117 	graphics.fillPolygon(intArray);
       
   118 	graphics.setForeground(laf.getColor("navi.tab.shade"));
       
   119 	graphics.drawPolyline(intArray);
       
   120 }
       
   121 
       
   122 function getViewRefFromIndex(instance, index) {
       
   123 	var appUiChildren = instance.parent.parent.children;
       
   124 	var tabIndex = -1;
       
   125 	for (var i in appUiChildren) {
       
   126 		var child = appUiChildren[i];
       
   127 		if ((child.componentId == "com.nokia.sdt.series60.AvkonViewReference") && child.properties.inTabGroup)
       
   128 			tabIndex++;
       
   129 		if (tabIndex == index)
       
   130 			return child;
       
   131 	}
       
   132 	
       
   133 	return null;
       
   134 }
       
   135 
       
   136 function getText(instance, index) {
       
   137 	var viewRef = getViewRefFromIndex(instance, index);
       
   138 	if (viewRef != null)
       
   139 		return viewRef.properties.tabText;
       
   140 	
       
   141 	return "";
       
   142 }
       
   143 
       
   144 function hasTabText(instance, index) {
       
   145 	return getText(instance, index).length > 0;
       
   146 }
       
   147 
       
   148 function drawText(instance, rect, font, graphics, index) {
       
   149 	var text = getText(instance, index);
       
   150 	text = chooseScalableText(text, font, rect.width);
       
   151 	var extent = font.stringExtent(text);
       
   152 	var newrect = new Rectangle(rect.x, (rect.height - extent.y) / 2, rect.width, rect.height)
       
   153 	graphics.drawFormattedString(text, newrect, Font.ALIGN_CENTER | Font.ANTIALIAS_OFF | Font.OVERFLOW_ELLIPSIS, 0);
       
   154 }
       
   155 
       
   156 function hasTabImage(instance, index) {
       
   157 	var viewRef = getViewRefFromIndex(instance, index);
       
   158 	if (viewRef != null) {
       
   159 		return isImagePropertySet(viewRef.properties.tabImage);
       
   160 	}
       
   161 		
       
   162 	return false;
       
   163 }
       
   164 
       
   165 function getUnmaskedFillColor(isOneTab, isActiveMulti, laf) {
       
   166 	if (isOneTab)
       
   167 		return laf.getColor("navi.pane.text");
       
   168 	else if (isActiveMulti)
       
   169 		return laf.getColor("navi.tab.face")
       
   170 	else
       
   171 		return laf.getColor("navi.tab.backText");
       
   172 }
       
   173 
       
   174 function renderTabImage(viewRef, isOneTab, isActiveMulti, laf, graphics, rect, color) {
       
   175 
       
   176 	var imagePropertyRendering = createImagePropertyRendering();
       
   177 	imagePropertyRendering.setImageProperty(viewRef, "tabImage", laf);
       
   178 
       
   179 	var imageProperty = viewRef.properties.tabImage.editableValue;
       
   180 	
       
   181 	// Different behavior for masked and unmasked images, in terms of the size
       
   182 	// of renderable area, the way the bitmap and mask are treated, etc.
       
   183 	 
       
   184 	if (imageProperty.isMasked()) {
       
   185 		// set the color used for monochrome rendering
       
   186 		graphics.setForeground(color);
       
   187 	} 
       
   188 	else {
       
   189 		graphics.setBackground(getUnmaskedFillColor(isOneTab, isActiveMulti, laf));
       
   190 		var fillRect = new Rectangle(rect.x, rect.y, rect.width, rect.height);
       
   191 		var hShrink = 0;
       
   192 		if (isOneTab)
       
   193 			hShrink = rect.width / 3;
       
   194 		else
       
   195 			hShrink = 4 * laf.getInteger("tab.corner", 3);
       
   196 		shrinkRect(fillRect, hShrink, 0);
       
   197 		graphics.fillRectangle(fillRect.x, fillRect.y, fillRect.width, fillRect.height);
       
   198 	}
       
   199 
       
   200 	imagePropertyRendering.setViewableSize(new Point(rect.width, rect.height));
       
   201 	imagePropertyRendering.setAlignmentWeights(new Point(ImageUtils.ALIGN_CENTER, ImageUtils.ALIGN_CENTER_OR_TOP));
       
   202 	imagePropertyRendering.setScaling(isScalingIcons());
       
   203 	imagePropertyRendering.setPreservingAspectRatio(true);
       
   204 	
       
   205 	imagePropertyRendering.setTransparencyHandling(imagePropertyRendering.TRANSPARENCY_FLATTEN);
       
   206 	
       
   207 	// use this model in S60ImagePropertyRendering to handle the weird (mis-)use of
       
   208 	// bitmap and mask in the navi pane
       
   209 	imagePropertyRendering.setRenderingModel(imagePropertyRendering.MODEL_NAVI_PANE_TABS);
       
   210 
       
   211 	imagePropertyRendering.render(graphics.getWrappedGC(), rect.x, rect.y);
       
   212 
       
   213 }
       
   214 
       
   215 function shrinkRect(rect, h, v) {
       
   216 	rect.x += h; 
       
   217 	rect.width -= (2 * h);
       
   218 	rect.y += v; 
       
   219 	rect.height -= (2 * v);
       
   220 }
       
   221 
       
   222 function drawTabImage(isOneTab, isActiveMulti, rect, instance, laf, graphics, index) {
       
   223 	var viewRef = getViewRefFromIndex(instance, index);
       
   224 	var color = getTextColor(isOneTab, isActiveMulti, laf);
       
   225 	var shrinkage = laf.getInteger("tab.corner", 3);
       
   226 	var drawRect = new Rectangle(rect.x, rect.y, rect.width, rect.height);
       
   227 	shrinkRect(drawRect, shrinkage, shrinkage);
       
   228 	renderTabImage(viewRef, isOneTab, isActiveMulti, laf, graphics, drawRect, color);
       
   229 }
       
   230 
       
   231 function drawOneTabContents(instance, rect, font, laf, graphics, index) {
       
   232 	var hasImage = hasTabImage(instance, index);
       
   233 	var hasText = hasTabText(instance, index);
       
   234 /*	
       
   235 NOT TRYING TO RENDER IMAGE AND TEXT, BECAUSE EXCEPT FOR VERY FEW CASES, IT LOOKS HOORIBLE ON THE EMULATOR!
       
   236 	if (hasImage && hasText) {
       
   237 		var imageRect = new Rectangle(rect.x, rect.y, rect.width / 2, rect.height);
       
   238 		drawTabImage(true, false, imageRect, instance, laf, graphics, index);
       
   239 		var text = getText(instance, index);
       
   240 		var textRect = new Rectangle(rect.x + (rect.width / 2), rect.y, rect.width / 2, rect.height);
       
   241 		drawText(instance, textRect, font, graphics, index);
       
   242 	}
       
   243 */	
       
   244 	if (hasText) {
       
   245 		var text = getText(instance, index);
       
   246 		drawText(instance, rect, font, graphics, index);
       
   247 	}
       
   248 	else if (hasImage) {
       
   249 		drawTabImage(true, false, rect, instance, laf, graphics, index);
       
   250 	}
       
   251 }
       
   252 
       
   253 function drawOneTab(instance, rect, laf, graphics, index) {
       
   254 	var color = getTextColor(true, false, laf);
       
   255 		
       
   256 	var font = laf.getFont("navi.text.font");
       
   257 	graphics.setFont(font);
       
   258 	graphics.setForeground(color);
       
   259 
       
   260 	drawOneTabContents(instance, rect, font, laf, graphics, index);
       
   261 }
       
   262 
       
   263 function getTextColor(isOneTab, isActiveMulti, laf) {
       
   264 	if (isOneTab)
       
   265 		return laf.getColor("navi.pane.text");
       
   266 	else if (isActiveMulti)
       
   267 		return laf.getColor("navi.tab.text")
       
   268 	else
       
   269 		return laf.getColor("navi.tab.backText");
       
   270 }
       
   271 
       
   272 function drawTabText(instance, rect, laf, graphics, isActive, index) {
       
   273 	var color = getTextColor(false, isActive, laf);
       
   274 	var font = laf.getFont("navi.tab.font");
       
   275 	graphics.setFont(font);
       
   276 	graphics.setForeground(color);
       
   277 	
       
   278 	drawText(instance, rect, font, graphics, index);
       
   279 }
       
   280 
       
   281 function drawTabContents(instance, rect, laf, graphics, isActive, index) {
       
   282 	var hasImage = hasTabImage(instance, index);
       
   283 	var hasText = hasTabText(instance, index);
       
   284 /*	
       
   285 NOT TRYING TO RENDER IMAGE AND TEXT, BECAUSE EXCEPT FOR VERY FEW CASES, IT LOOKS HOORIBLE ON THE EMULATOR!
       
   286 	if (hasImage && hasText) {
       
   287 		var text = getText(instance, index);
       
   288 		var textRect = new Rectangle(rect.x, rect.y, rect.width / 2, rect.height);new Rectangle(rect.x, rect.y, rect.width / 2, rect.height);
       
   289 		drawTabText(instance, textRect, laf, graphics, isActive, index);
       
   290 		var imageRect = new Rectangle(rect.x + (rect.width / 2), rect.y, rect.width / 2, rect.height);
       
   291 		drawTabImage(false, isActive, imageRect, instance, laf, graphics, index);
       
   292 	}
       
   293 */
       
   294 	if (hasText) {
       
   295 		var text = getText(instance, index);
       
   296 		drawTabText(instance, rect, laf, graphics, isActive, index);
       
   297 	}
       
   298 	else if (hasImage) {
       
   299 		drawTabImage(false, isActive, rect, instance, laf, graphics, index);
       
   300 	}
       
   301 }
       
   302 
       
   303 function drawMultipleTabs(instance, rect, laf, graphics, active) {
       
   304 	var numVisualTabs = getNumVisualTabs(instance.properties.tabWidth);
       
   305 	var longTabs = isLongTabs(instance);
       
   306 	var hInset = getHorizontalInset(laf);
       
   307 	var tabOffset = getTabOffset(rect.width, longTabs, numVisualTabs, laf);
       
   308 	var tabWidth = getTabWidth(rect.width, numVisualTabs, longTabs, laf);
       
   309 	
       
   310 	var firstTab = 0;
       
   311 	var numTabs = getNumTabs(instance);
       
   312 	if (active >= numVisualTabs)
       
   313 		firstTab = active;
       
   314 	if (firstTab + numVisualTabs >= numTabs)
       
   315 		firstTab = numTabs - numVisualTabs;
       
   316 	if (firstTab < 0)
       
   317 		firstTab = 0;
       
   318 	
       
   319 	// first draw the inactive tabs
       
   320 	for (var i = firstTab + numVisualTabs - 1; i > active; i--) {
       
   321 		var left = rect.x + hInset + ((i - firstTab) * tabOffset);
       
   322 		var drawRect = new Rectangle(left, rect.y, tabWidth, rect.height);
       
   323 		drawTab(drawRect, laf, graphics, false);
       
   324 		if (!longTabs) {
       
   325 			drawTabContents(instance, drawRect, laf, graphics, false, i);
       
   326 		}
       
   327 	}
       
   328 	for (var i = firstTab; i < active; i++) {
       
   329 		var left = rect.x + hInset + ((i - firstTab) * tabOffset);
       
   330 		var drawRect = new Rectangle(left, rect.y, tabWidth, rect.height);
       
   331 		drawTab(drawRect, laf, graphics, false);
       
   332 		if (!longTabs) {
       
   333 			drawTabContents(instance, drawRect, laf, graphics, false, i);
       
   334 		}
       
   335 	}
       
   336 	
       
   337 	// then draw the active tab
       
   338 	{
       
   339 		var left = rect.x + hInset + ((active - firstTab) * tabOffset);
       
   340 		var drawRect = new Rectangle(left, rect.y, tabWidth, rect.height);
       
   341 		drawTab(drawRect, laf, graphics, true);
       
   342 		drawTabContents(instance, drawRect, laf, graphics, true, active);
       
   343 	}
       
   344 }
       
   345 
       
   346 function drawArrow(onRight, rect, laf, graphics) {
       
   347 	var arrowHeight = rect.height / 3;
       
   348 	graphics.setForeground(laf.getColor("navi.tab.arrow"));
       
   349 	var arrowTop = (rect.height - arrowHeight) / 2;
       
   350 	var hInset = getHorizontalInset(laf);
       
   351 	var arrowWidth = ((arrowHeight % 2) == 0) ? arrowHeight / 2 + 1 : arrowHeight / 2;
       
   352 	
       
   353 	for (var i = 0; i < arrowWidth; i++) {
       
   354 		var x;
       
   355 		if (onRight)
       
   356 			x = rect.x + rect.width - hInset + i;
       
   357 		else
       
   358 			x = rect.x + hInset - i;
       
   359 		var y0 = arrowTop + i;
       
   360 		var y1 = arrowTop + arrowHeight - i;
       
   361 		graphics.drawLine(x, y0, x, y1);
       
   362 	}
       
   363 }
       
   364 
       
   365 NaviTabsVisual.prototype.draw = function(instance, laf, graphics) {
       
   366 	var properties = instance.properties;
       
   367 	var active = instance.properties.active;
       
   368 	var numTabs = getNumTabs(instance);
       
   369 	
       
   370 	if (active > (numTabs - 1))
       
   371 		active = numTabs - 1;
       
   372 
       
   373 	if (active < 0)
       
   374 		active = 0;
       
   375 		
       
   376 	var size = getNaviSize(instance, laf);
       
   377 	var rect = new Rectangle(0, 0, size.x, size.y);
       
   378 	if (!isOneTab(properties.tabWidth)) {
       
   379 		drawMultipleTabs(instance, rect, laf, graphics, active);
       
   380 	}
       
   381 	else {
       
   382 		drawOneTab(instance, rect, laf, graphics, active);
       
   383 	}
       
   384 
       
   385 	if (active > 0)
       
   386 		drawArrow(false, rect, laf, graphics);
       
   387 	
       
   388 	if (active < (numTabs - 1))
       
   389 		drawArrow(true, rect, laf, graphics);
       
   390 }
       
   391 
       
   392 NaviTabsVisual.prototype.getPreferredSize = function(instance, laf, wHint, hHint) {
       
   393 	return null; // needs implementation	
       
   394 }
       
   395