1/**
2 * $Id: mxMockupContainers.js,v 1.10 2013/07/09 11:19:51 mate Exp $
3 * Copyright (c) 2006-2010, JGraph Ltd
4 */
5
6//**********************************************************************************************************************************************************
7//Video Player
8//**********************************************************************************************************************************************************
9/**
10 * Extends mxShape.
11 */
12function mxShapeMockupVideoPlayer(bounds, fill, stroke, strokewidth)
13{
14	mxShape.call(this);
15	this.bounds = bounds;
16	this.fill = fill;
17	this.stroke = stroke;
18	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
19	this.barPos = 20;
20	this.barHeight = 30;
21};
22
23/**
24 * Extends mxShape.
25 */
26mxUtils.extend(mxShapeMockupVideoPlayer, mxShape);
27
28mxShapeMockupVideoPlayer.prototype.cst = {
29		FILL_COLOR2 : 'fillColor2',
30		TEXT_COLOR : 'textColor',
31		STROKE_COLOR2 : 'strokeColor2',
32		STROKE_COLOR3 : 'strokeColor3',
33		SHAPE_VIDEO_PLAYER : 'mxgraph.mockup.containers.videoPlayer',
34		BAR_POS : 'barPos',
35		BAR_HEIGHT : 'barHeight'
36};
37
38mxShapeMockupVideoPlayer.prototype.customProperties = [
39	{name: 'fillColor2', dispName: 'Fill2 Color', type: 'color'},
40	{name: 'textColor', dispName: 'Text Color', type: 'color'},
41	{name: 'strokeColor2', dispName: 'Stroke2 Color', type: 'color'},
42	{name: 'strokeColor3', dispName: 'Stroke3 Color', type: 'color'},
43	{name: 'barPos', dispName: 'Handle Position', type: 'float', min:0, max:100, defVal:20},
44	{name: 'barHeight', dispName: 'Video Bar Height', type: 'float', min:0, defVal:30}
45];
46
47/**
48 * Function: paintVertexShape
49 *
50 * Paints the vertex shape.
51 */
52mxShapeMockupVideoPlayer.prototype.paintVertexShape = function(c, x, y, w, h)
53{
54	var bgColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
55	var buttonColor = mxUtils.getValue(this.style, mxShapeMockupVideoPlayer.prototype.cst.FILL_COLOR2, '#c4c4c4');
56	var frameColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#666666');
57	var filledColor = mxUtils.getValue(this.style, mxShapeMockupVideoPlayer.prototype.cst.STROKE_COLOR2, '#008cff');
58	var emptyColor = mxUtils.getValue(this.style, mxShapeMockupVideoPlayer.prototype.cst.STROKE_COLOR3, '#c4c4c4');
59	var barHeight = mxUtils.getValue(this.style, mxShapeMockupVideoPlayer.prototype.cst.BAR_HEIGHT, '30');
60
61	w = Math.max(w, 5 * barHeight);
62	h = Math.max(h, barHeight + 10);
63
64	c.translate(x, y);
65	this.background(c, x, y, w, h, bgColor, frameColor);
66	c.setShadow(false);
67	this.otherShapes(c, x, y, w, h, buttonColor, frameColor, filledColor, emptyColor, barHeight);
68};
69
70mxShapeMockupVideoPlayer.prototype.background = function(c, x, y, w, h, bgColor, frameColor)
71{
72	c.setFillColor(bgColor);
73	c.setStrokeColor(frameColor);
74	c.begin();
75	c.moveTo(0, 0);
76	c.lineTo(w, 0);
77	c.lineTo(w, h);
78	c.lineTo(0, h);
79	c.close();
80	c.fillAndStroke();
81};
82
83mxShapeMockupVideoPlayer.prototype.otherShapes = function(c, x, y, w, h, buttonColor, frameColor, filledColor, emptyColor, barHeight)
84{
85	var barPos = mxUtils.getValue(this.style, mxShapeMockupVideoPlayer.prototype.cst.BAR_POS, '20');
86	barPos = Math.max(0, barPos);
87	barPos = Math.min(100, barPos);
88
89	var strokeWidth = mxUtils.getValue(this.style, mxConstants.STYLE_STROKEWIDTH, '1');
90	var buttonR = 8;
91	var barY = h - barHeight;
92
93	var barMin = buttonR;
94	var barMax = w - buttonR;
95	var barRange = barMax - barMin;
96	var realBarPos = barRange * barPos / 100;
97	var barEnd = barMin + realBarPos;
98
99	//progress bar
100	c.setStrokeColor(filledColor);
101	c.begin();
102	c.moveTo(0, barY);
103	c.lineTo(barEnd, barY);
104	c.stroke();
105	c.setStrokeColor(emptyColor);
106	c.begin();
107	c.moveTo(barEnd, barY);
108	c.lineTo(w, barY);
109	c.stroke();
110
111	//progress bar button
112	c.setStrokeColor(frameColor);
113	c.begin();
114	c.ellipse(barEnd - buttonR, barY - buttonR, 2 * buttonR, 2 * buttonR);
115	c.fillAndStroke();
116
117	c.begin();
118	c.setStrokeWidth(strokeWidth / 2);
119	c.ellipse(barEnd - buttonR * 0.5, barY - buttonR * 0.5, buttonR, buttonR);
120	c.fillAndStroke();
121	c.setStrokeWidth(strokeWidth);
122
123	var iconSize = barHeight * 0.3;
124	var iconY = h - (barHeight + iconSize) * 0.5;
125	var iconX = barHeight * 0.3;
126	c.setFillColor(buttonColor);
127	c.setStrokeColor(buttonColor);
128
129	//play icon
130	c.begin();
131	c.moveTo(iconX, iconY);
132	c.lineTo(iconX + iconSize, iconY + iconSize * 0.5);
133	c.lineTo(iconX, iconY + iconSize);
134	c.close();
135	c.fillAndStroke();
136
137	//volume icon
138	var speakerX = barHeight;
139	var speakerY = h - barHeight;
140	c.moveTo(speakerX + barHeight * 0.05, speakerY + barHeight * 0.4);
141	c.lineTo(speakerX + barHeight * 0.15, speakerY + barHeight * 0.4);
142	c.lineTo(speakerX + barHeight * 0.3, speakerY + barHeight * 0.25);
143	c.lineTo(speakerX + barHeight * 0.3, speakerY + barHeight * 0.75);
144	c.lineTo(speakerX + barHeight * 0.15, speakerY + barHeight * 0.6);
145	c.lineTo(speakerX + barHeight * 0.05, speakerY + barHeight * 0.6);
146	c.close();
147	c.fillAndStroke();
148
149	c.begin();
150	c.moveTo(speakerX + barHeight * 0.4, speakerY + barHeight * 0.35);
151	c.arcTo(barHeight * 0.2, barHeight * 0.3, 0, 0, 1, speakerX + barHeight * 0.4, speakerY + barHeight * 0.65);
152	c.moveTo(speakerX + barHeight * 0.425, speakerY + barHeight * 0.25);
153	c.arcTo(barHeight * 0.225, barHeight * 0.35, 0, 0, 1, speakerX + barHeight * 0.425, speakerY + barHeight * 0.75);
154	c.stroke();
155
156	//fullscreen button
157	var screenX = w - barHeight * 1.3;
158	c.begin();
159	c.moveTo(screenX + barHeight * 0.1, speakerY + barHeight * 0.4);
160	c.lineTo(screenX + barHeight * 0.1, speakerY + barHeight * 0.3);
161	c.lineTo(screenX + barHeight * 0.25, speakerY + barHeight * 0.3);
162
163	c.moveTo(screenX + barHeight * 0.1, speakerY + barHeight * 0.6);
164	c.lineTo(screenX + barHeight * 0.1, speakerY + barHeight * 0.7);
165	c.lineTo(screenX + barHeight * 0.25, speakerY + barHeight * 0.7);
166
167	c.moveTo(screenX + barHeight * 0.9, speakerY + barHeight * 0.4);
168	c.lineTo(screenX + barHeight * 0.9, speakerY + barHeight * 0.3);
169	c.lineTo(screenX + barHeight * 0.75, speakerY + barHeight * 0.3);
170
171	c.moveTo(screenX + barHeight * 0.9, speakerY + barHeight * 0.6);
172	c.lineTo(screenX + barHeight * 0.9, speakerY + barHeight * 0.7);
173	c.lineTo(screenX + barHeight * 0.75, speakerY + barHeight * 0.7);
174	c.stroke();
175
176	var textColor = mxUtils.getValue(this.style, mxShapeMockupVideoPlayer.prototype.cst.TEXT_COLOR, '#666666');
177	c.begin();
178	c.setFontSize(barHeight * 0.5);
179	c.setFontColor(textColor);
180	c.text(barHeight * 1.9, h - barHeight * 0.45, 0, 0, '0:00/3:53', mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
181};
182
183mxCellRenderer.registerShape(mxShapeMockupVideoPlayer.prototype.cst.SHAPE_VIDEO_PLAYER, mxShapeMockupVideoPlayer);
184
185Graph.handleFactory[mxShapeMockupVideoPlayer.prototype.cst.SHAPE_VIDEO_PLAYER] = function(state)
186{
187	var handles = [Graph.createHandle(state, ['barPos'], function(bounds)
188			{
189				var barPos = Math.max(0, Math.min(100, parseFloat(mxUtils.getValue(this.state.style, 'barPos', this.barPos))));
190
191				var barH = parseFloat(mxUtils.getValue(this.state.style, 'barHeight', this.barHeight));
192
193				return new mxPoint(bounds.x + ((bounds.width - 16) * barPos / bounds.width) / 100 * bounds.width + 8, bounds.y + bounds.height - barH - 20);
194			}, function(bounds, pt)
195			{
196				this.state.style['barPos'] = Math.round(1000 * Math.max(0, Math.min(100, (pt.x - bounds.x) * 100 / bounds.width))) / 1000;
197			})];
198
199	var handle2 = Graph.createHandle(state, ['barHeight'], function(bounds)
200			{
201				var barHeight = Math.max(0, Math.min(bounds.height, parseFloat(mxUtils.getValue(this.state.style, 'barHeight', this.barHeight))));
202
203				return new mxPoint(bounds.x + bounds.width - 20, bounds.y + bounds.height - barHeight);
204			}, function(bounds, pt)
205			{
206				this.state.style['barHeight'] = Math.round(1000 * Math.max(0, Math.min(bounds.height, bounds.y + bounds.height - pt.y))) / 1000;
207			});
208
209	handles.push(handle2);
210
211	return handles;
212}
213
214//**********************************************************************************************************************************************************
215//Accordion (LEGACY)
216//**********************************************************************************************************************************************************
217/**
218 * Extends mxShape.
219 */
220function mxShapeMockupAccordion(bounds, fill, stroke, strokewidth)
221{
222	mxShape.call(this);
223	this.bounds = bounds;
224	this.fill = fill;
225	this.stroke = stroke;
226	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
227};
228
229/**
230 * Extends mxShape.
231 */
232mxUtils.extend(mxShapeMockupAccordion, mxShape);
233
234mxShapeMockupAccordion.prototype.cst = {
235		TEXT_COLOR : 'textColor',
236		TEXT_COLOR2 : 'textColor2',
237		TEXT_SIZE : 'textSize',
238		SHAPE_ACCORDION : 'mxgraph.mockup.containers.accordion',
239		STROKE_COLOR2 : 'strokeColor2',
240		FILL_COLOR2 : 'fillColor2',
241		SELECTED : '+',			// must be 1 char
242		MAIN_TEXT : 'mainText'
243};
244
245/**
246 * Function: paintVertexShape
247 *
248 * Paints the vertex shape.
249 */
250mxShapeMockupAccordion.prototype.paintVertexShape = function(c, x, y, w, h)
251{
252	var textStrings = mxUtils.getValue(this.style, mxShapeMockupAccordion.prototype.cst.MAIN_TEXT, '+Group 1, Group 2, Group 3').toString().split(',');
253	var fontColor = mxUtils.getValue(this.style, mxShapeMockupAccordion.prototype.cst.TEXT_COLOR, '#666666');
254	var selectedFontColor = mxUtils.getValue(this.style, mxShapeMockupAccordion.prototype.cst.TEXT_COLOR2, '#ffffff');
255	var fontSize = mxUtils.getValue(this.style, mxShapeMockupAccordion.prototype.cst.TEXT_SIZE, '17').toString();
256	var frameColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#666666');
257	var separatorColor = mxUtils.getValue(this.style, mxShapeMockupAccordion.prototype.cst.STROKE_COLOR2, '#c4c4c4');
258	var bgColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
259	var selectedFillColor = mxUtils.getValue(this.style, mxShapeMockupAccordion.prototype.cst.FILL_COLOR2, '#008cff');
260	var buttonNum = textStrings.length;
261	var maxButtonWidth = 0;
262	var selectedButton = -1;
263	var rSize = 10; //rounding size
264	var labelOffset = 5;
265
266	for (var i = 0; i < buttonNum; i++)
267	{
268		var buttonText = textStrings[i];
269
270		if(buttonText.charAt(0) === mxShapeMockupAccordion.prototype.cst.SELECTED)
271		{
272			buttonText = textStrings[i].substring(1);
273			selectedButton = i;
274		}
275
276		var currWidth = mxUtils.getSizeForString(buttonText, fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
277
278		if (currWidth > maxButtonWidth)
279		{
280			maxButtonWidth = currWidth;
281		}
282	}
283
284	var minButtonHeight =  fontSize * 1.5;
285	var minH = buttonNum * minButtonHeight;
286	var trueH = Math.max(h, minH);
287	var minW = 2 * labelOffset + maxButtonWidth;
288	var trueW = Math.max(w, minW);
289
290	c.translate(x, y);
291
292	this.background(c, trueW, trueH, rSize, buttonNum, labelOffset, buttonNum * minButtonHeight, frameColor, separatorColor, bgColor, selectedFillColor, selectedButton, minButtonHeight);
293	c.setShadow(false);
294
295	var currWidth = 0;
296
297	for (var i = 0; i < buttonNum; i++)
298	{
299		if (i === selectedButton)
300		{
301			c.setFontColor(selectedFontColor);
302		}
303		else
304		{
305			c.setFontColor(fontColor);
306		}
307
308		currWidth = currWidth + labelOffset;
309		var currHeight = 0;
310
311		if (selectedButton === -1 || i <= selectedButton)
312		{
313			currHeight = (i * minButtonHeight + minButtonHeight * 0.5);
314		}
315		else
316		{
317			currHeight = trueH - (buttonNum - i - 0.5) * minButtonHeight;
318		}
319
320		this.buttonText(c, trueW, currHeight, textStrings[i], fontSize);
321	}
322};
323
324mxShapeMockupAccordion.prototype.background = function(c, w, h, rSize, buttonNum, labelOffset, minH, frameColor, separatorColor, bgColor, selectedFillColor, selectedButton, minButtonHeight)
325{
326	c.begin();
327
328	//draw the frame
329	c.setStrokeColor(frameColor);
330	c.setFillColor(bgColor);
331	c.moveTo(0, 0);
332	c.lineTo(w, 0);
333	c.lineTo(w, h);
334	c.lineTo(0, h);
335	c.close();
336	c.fillAndStroke();
337
338	//draw the button separators
339	c.setStrokeColor(separatorColor);
340	c.begin();
341
342	for (var i = 1; i < buttonNum; i++)
343	{
344		if (i !== selectedButton)
345		{
346			if (selectedButton === -1 || i < selectedButton)
347			{
348				var currHeight = i * minButtonHeight;
349				c.moveTo(0, currHeight);
350				c.lineTo(w, currHeight);
351			}
352			else
353			{
354				var currHeight = h - (buttonNum - i) * minButtonHeight;
355				c.moveTo(0, currHeight);
356				c.lineTo(w, currHeight);
357			}
358		}
359	}
360
361	c.stroke();
362
363	//draw the selected button
364	c.setStrokeColor(mxConstants.NONE);
365	c.setFillColor(selectedFillColor);
366
367	if (selectedButton !== -1)
368	{
369		c.begin();
370		var buttonTop = minButtonHeight * selectedButton;
371		var buttonBottom = minButtonHeight * (selectedButton + 1);
372		c.moveTo(0, buttonTop);
373		c.lineTo(w, buttonTop);
374		c.lineTo(w, buttonBottom);
375		c.lineTo(0, buttonBottom);
376		c.close();
377		c.fill();
378	}
379
380//	//draw the frame again, to achieve a nicer effect
381	c.begin();
382	c.setStrokeColor(frameColor);
383	c.setFillColor(bgColor);
384	c.moveTo(0, 0);
385	c.lineTo(w, 0);
386	c.lineTo(w, h);
387	c.lineTo(0, h);
388	c.close();
389	c.stroke();
390};
391
392mxShapeMockupAccordion.prototype.buttonText = function(c, w, h, textString, fontSize)
393{
394	if(textString.charAt(0) === mxShapeMockupAccordion.prototype.cst.SELECTED)
395	{
396		textString = textString.substring(1);
397	}
398
399	c.begin();
400	c.setFontSize(fontSize);
401	c.text((w * 0.5), h, 0, 0, textString, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
402};
403
404mxCellRenderer.registerShape(mxShapeMockupAccordion.prototype.cst.SHAPE_ACCORDION, mxShapeMockupAccordion);
405
406//**********************************************************************************************************************************************************
407//Browser Window
408//**********************************************************************************************************************************************************
409/**
410 * Extends mxShape.
411 */
412function mxShapeMockupBrowserWindow(bounds, fill, stroke, strokewidth)
413{
414	mxShape.call(this);
415	this.bounds = bounds;
416	this.fill = fill;
417	this.stroke = stroke;
418	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
419};
420
421/**
422 * Extends mxShape.
423 */
424mxUtils.extend(mxShapeMockupBrowserWindow, mxShape);
425
426mxShapeMockupBrowserWindow.prototype.cst = {
427		STROKE_COLOR2 : 'strokeColor2',
428		STROKE_COLOR3 : 'strokeColor3',
429		MAIN_TEXT : 'mainText',
430		SHAPE_BROWSER_WINDOW : 'mxgraph.mockup.containers.browserWindow'
431
432};
433
434mxShapeMockupBrowserWindow.prototype.customProperties = [
435	{name: 'strokeColor2', dispName: 'Stroke2 Color', type: 'color'},
436	{name: 'strokeColor3', dispName: 'Stroke3 Color', type: 'color'}
437];
438
439/**
440 * Function: paintVertexShape
441 *
442 * Paints the vertex shape.
443 */
444mxShapeMockupBrowserWindow.prototype.paintVertexShape = function(c, x, y, w, h)
445{
446	var bgColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
447	var frameColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#666666');
448	var closeColor = mxUtils.getValue(this.style, mxShapeMockupBrowserWindow.prototype.cst.STROKE_COLOR2, '#008cff');
449	var insideColor = mxUtils.getValue(this.style, mxShapeMockupBrowserWindow.prototype.cst.STROKE_COLOR3, '#c4c4c4');
450	w = Math.max(w, 260);
451	h = Math.max(h, 110);
452	c.translate(x, y);
453	this.background(c, x, y, w, h, bgColor, frameColor);
454	c.setShadow(false);
455	this.otherShapes(c, x, y, w, h, frameColor, insideColor, closeColor);
456};
457
458mxShapeMockupBrowserWindow.prototype.background = function(c, x, y, w, h, bgColor, frameColor)
459{
460	c.setFillColor(bgColor);
461	c.setStrokeColor(frameColor);
462	c.begin();
463	c.moveTo(0, 0);
464	c.lineTo(w, 0);
465	c.lineTo(w, h);
466	c.lineTo(0, h);
467	c.close();
468	c.fillAndStroke();
469};
470
471mxShapeMockupBrowserWindow.prototype.otherShapes = function(c, x, y, w, h, frameColor, insideColor, closeColor)
472{
473	var strokeWidth = mxUtils.getValue(this.style, mxConstants.STYLE_STROKEWIDTH, '1');
474	var mainText = mxUtils.getValue(this.style, mxShapeMockupBrowserWindow.prototype.cst.MAIN_TEXT, 'http://www.draw.io,Page 1').toString().split(',');
475
476	//window buttons
477	c.setStrokeColor(frameColor);
478	c.ellipse(w - 75, 5, 20, 20);
479	c.stroke();
480
481	c.ellipse(w - 50, 5, 20, 20);
482	c.stroke();
483
484	c.setStrokeColor(closeColor);
485	c.ellipse(w - 25, 5, 20, 20);
486	c.stroke();
487
488	c.setStrokeColor(insideColor);
489	//lines
490	c.begin();
491	c.moveTo(0, 40);
492	c.lineTo(30, 40);
493	c.lineTo(30, 15);
494	c.arcTo(5, 5, 0, 0, 1, 35, 10);
495	c.lineTo(170, 10);
496	c.arcTo(5, 5, 0, 0, 1, 175, 15);
497	c.lineTo(175, 40);
498	c.lineTo(w, 40);
499	c.stroke();
500
501	c.begin();
502	c.moveTo(0, 110);
503	c.lineTo(w, 110);
504	c.stroke();
505
506	//address field
507	c.begin();
508	c.moveTo(100, 60);
509	c.arcTo(5, 5, 0, 0, 1, 105, 55);
510	c.lineTo(w - 15, 55);
511	c.arcTo(5, 5, 0, 0, 1, w - 10, 60);
512	c.lineTo(w - 10, 85);
513	c.arcTo(5, 5, 0, 0, 1, w - 15, 90);
514	c.lineTo(105, 90);
515	c.arcTo(5, 5, 0, 0, 1, 100, 85);
516	c.close();
517	c.stroke();
518
519	//text
520	var textColor = mxUtils.getValue(this.style, mxShapeMockupBrowserWindow.prototype.cst.TEXT_COLOR, '#666666');
521	c.setFontColor(textColor);
522	c.setFontSize(17);
523	c.text(65, 25, 0, 0, mainText[1], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
524	c.text(130, 73, 0, 0, mainText[0], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
525	c.stroke();
526
527	//icon on tab
528	c.translate(37, 17);
529	c.begin();
530	c.moveTo(0, 0);
531	c.lineTo(11, 0);
532	c.lineTo(15, 4);
533	c.lineTo(15, 18);
534	c.lineTo(0, 18);
535	c.close();
536	c.stroke();
537
538	c.setStrokeWidth(strokeWidth * 0.5); //maybe because of this (read later)
539	c.begin();
540	c.moveTo(11, 0);
541	c.lineTo(11, 4);
542	c.lineTo(15, 5);
543	c.stroke();
544
545	//icon in address bar
546	c.setStrokeWidth(strokeWidth * 2); // i'm not sure why i have to multiply here
547	c.translate(70, 47);
548	c.begin();
549	c.moveTo(0, 0);
550	c.lineTo(11, 0);
551	c.lineTo(15, 4);
552	c.lineTo(15, 18);
553	c.lineTo(0, 18);
554	c.close();
555	c.stroke();
556
557	c.setStrokeWidth(strokeWidth * 0.5);
558	c.begin();
559	c.moveTo(11, 0);
560	c.lineTo(11, 4);
561	c.lineTo(15, 5);
562	c.stroke();
563
564	//back
565	var iSi = 20; //icon size
566	c.setFillColor(insideColor);
567	c.begin();
568	c.setStrokeWidth(strokeWidth * 2); // i'm not sure why i have to multiply here
569	c.translate(-95, 0);
570	c.moveTo(0, iSi * 0.5);
571	c.lineTo(iSi * 0.5, 0);
572	c.lineTo(iSi * 0.5, iSi * 0.3);
573	c.lineTo(iSi, iSi * 0.3);
574	c.lineTo(iSi, iSi * 0.7);
575	c.lineTo(iSi * 0.5, iSi * 0.7);
576	c.lineTo(iSi * 0.5, iSi);
577	c.close();
578	c.fillAndStroke();
579
580	//forward
581	c.begin();
582	c.translate(30, 0);
583	c.moveTo(iSi, iSi * 0.5);
584	c.lineTo(iSi * 0.5, 0);
585	c.lineTo(iSi * 0.5, iSi * 0.3);
586	c.lineTo(0, iSi * 0.3);
587	c.lineTo(0, iSi * 0.7);
588	c.lineTo(iSi * 0.5, iSi * 0.7);
589	c.lineTo(iSi * 0.5, iSi);
590	c.close();
591	c.fillAndStroke();
592
593	//refresh
594	c.begin();
595	c.translate(30, 0);
596	c.moveTo(iSi * 0.78, iSi * 0.665);
597	c.arcTo(iSi * 0.3, iSi * 0.3, 0, 1, 1, iSi * 0.675, iSi * 0.252);
598	c.lineTo(iSi * 0.595, iSi * 0.325);
599	c.lineTo(iSi * 0.99, iSi * 0.415);
600	c.lineTo(iSi * 0.9, iSi * 0.04);
601	c.lineTo(iSi * 0.815, iSi * 0.12);
602	c.arcTo(iSi * 0.49, iSi * 0.49, 0, 1, 0, iSi * 0.92, iSi * 0.8);
603	c.close();
604	c.fillAndStroke();
605};
606
607mxCellRenderer.registerShape(mxShapeMockupBrowserWindow.prototype.cst.SHAPE_BROWSER_WINDOW, mxShapeMockupBrowserWindow);
608
609//**********************************************************************************************************************************************************
610//User, Male
611//**********************************************************************************************************************************************************
612/**
613 * Extends mxShape.
614 */
615function mxShapeMockupUserMale(bounds, fill, stroke, strokewidth)
616{
617	mxShape.call(this);
618	this.bounds = bounds;
619	this.fill = fill;
620	this.stroke = stroke;
621	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
622};
623
624/**
625 * Extends mxShape.
626 */
627mxUtils.extend(mxShapeMockupUserMale, mxShape);
628
629mxShapeMockupUserMale.prototype.cst = {
630		STROKE_COLOR2 : 'strokeColor2',
631		SHAPE_MALE_USER : 'mxgraph.mockup.containers.userMale'
632};
633
634mxShapeMockupUserMale.prototype.customProperties = [
635	{name: 'strokeColor2', dispName: 'Stroke2 Color', type: 'color'}
636];
637
638/**
639 * Function: paintVertexShape
640 *
641 * Paints the vertex shape.
642 */
643mxShapeMockupUserMale.prototype.paintVertexShape = function(c, x, y, w, h)
644{
645	var bgColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
646	var frameColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#666666');
647	var insideColor = mxUtils.getValue(this.style, mxShapeMockupUserMale.prototype.cst.STROKE_COLOR2, '#008cff');
648	c.translate(x, y);
649	this.background(c, x, y, w, h, bgColor, frameColor);
650	c.setShadow(false);
651	this.otherShapes(c, x, y, w, h, insideColor, frameColor);
652};
653
654mxShapeMockupUserMale.prototype.background = function(c, x, y, w, h, bgColor, frameColor)
655{
656	c.setFillColor(bgColor);
657	c.setStrokeColor(frameColor);
658	c.begin();
659	c.moveTo(0, 0);
660	c.lineTo(w, 0);
661	c.lineTo(w, h);
662	c.lineTo(0, h);
663	c.close();
664	c.fillAndStroke();
665};
666
667mxShapeMockupUserMale.prototype.otherShapes = function(c, x, y, w, h, insideColor, frameColor)
668{
669	//head left
670	c.setStrokeColor(insideColor);
671	c.setLineCap('round');
672	c.setLineJoin('round');
673	c.begin();
674	c.moveTo(w * 0.5, h * 0.6721);
675	c.curveTo(w * 0.3891, h * 0.6721, w * 0.31, h * 0.5648, w * 0.31, h * 0.3962);
676	c.curveTo(w * 0.31, h * 0.3656, w * 0.3012, h * 0.3473, w * 0.3051, h * 0.3227);
677	c.curveTo(w * 0.3126, h * 0.2762, w * 0.3124, h * 0.2212, w * 0.332, h * 0.1939);
678	c.curveTo(w * 0.354, h * 0.1633, w * 0.4382, h * 0.12, w * 0.5, h * 0.12);
679	c.stroke();
680
681	//left ear
682	c.begin();
683	c.moveTo(w * 0.3046, h * 0.3716);
684	c.curveTo(w * 0.3046, h * 0.3716, w * 0.3046, h * 0.341, w * 0.2826, h * 0.3594);
685	c.curveTo(w * 0.2606, h * 0.3778, w * 0.2661, h * 0.4452, w * 0.266, h * 0.4452);
686	c.quadTo(w * 0.2715, h * 0.4942, w * 0.277, h * 0.5065);
687	c.curveTo(w * 0.2825, h * 0.5187, w * 0.277, h * 0.5187, w * 0.2935, h * 0.5371);
688	c.curveTo(w * 0.31, h * 0.5554, w * 0.3375, h * 0.5615, w * 0.3375, h * 0.5616);
689	c.stroke();
690
691	// left shoulder
692	c.begin();
693	c.moveTo(w * 0.3829, h * 0.6213);
694	c.curveTo(w * 0.3829, h * 0.6213, w * 0.405, h * 0.7704, w * 0.2921, h * 0.7888);
695	c.curveTo(w * 0.2536, h * 0.795, w * 0.1328, h * 0.85, w * 0.1052, h * 0.8745);
696	c.curveTo(w * 0.0776, h * 0.899, w * 0.0641, h * 0.9316, w * 0.0571, h * 0.9622);
697	c.quadTo(w * 0.05, h, w * 0.05, h);
698	c.stroke();
699
700	// left hairline
701	c.begin();
702	c.moveTo(w * 0.3427, h * 0.4185);
703	c.curveTo(w * 0.3427, h * 0.4185, w * 0.3427, h * 0.3839, w * 0.3427, h * 0.3593);
704	c.curveTo(w * 0.3427, h * 0.3348, w * 0.3663, h * 0.3103, w * 0.3718, h * 0.3041);
705	c.curveTo(w * 0.3773, h * 0.298, w * 0.3822, h * 0.2673, w * 0.3877, h * 0.2551);
706	c.curveTo(w * 0.3932, h * 0.2429, w * 0.4095, h * 0.2429, w * 0.4259, h * 0.2367);
707	c.curveTo(w * 0.4424, h * 0.2306, w * 0.4984, h * 0.2357, w * 0.4984, h * 0.2357);
708	c.stroke();
709
710	//shirt
711	c.begin();
712	c.moveTo(w * 0.365, h * 0.7427);
713	c.curveTo(w * 0.365, h * 0.7427, w * 0.3772, h * 0.8076, w * 0.4286, h * 0.8224);
714	c.curveTo(w * 0.4816, h * 0.8377, w * 0.5028, h * 0.8347, w * 0.5028, h * 0.8347);
715	c.stroke();
716
717	c.begin();
718	c.moveTo(w * 0.3322, h * 0.7764);
719	c.curveTo(w * 0.3322, h * 0.7764, w * 0.3556, h * 0.8386, w * 0.4038, h * 0.8684);
720	c.curveTo(w * 0.4533, h * 0.8991, w * 0.5029, h * 0.8929, w * 0.5029, h * 0.8929);
721	c.stroke();
722
723	c.begin();
724	c.moveTo(w * 0.2717, h * 0.9);
725	c.lineTo(w * 0.2717, h);
726	c.stroke();
727
728	c.begin();
729	c.moveTo(w * 0.1671, h * 0.8991);
730	c.curveTo(w * 0.1671, h * 0.8991, w * 0.1726, h * 0.9114, w * 0.1836, h * 0.9481);
731	c.curveTo(w * 0.1946, h * 0.9849, w * 0.2, h, w * 0.2, h);
732	c.stroke();
733
734	//head right
735	c.begin();
736	c.moveTo(w * 0.5, h * 0.6721);
737	c.curveTo(w * 0.6109, h * 0.6721, w * 0.69, h * 0.5648, w * 0.69, h * 0.3962);
738	c.curveTo(w * 0.69, h * 0.3656, w * 0.6988, h * 0.3473, w * 0.6949, h * 0.3227);
739	c.curveTo(w * 0.6847, h * 0.2762, w * 0.6876, h * 0.2212, w * 0.668, h * 0.1939);
740	c.curveTo(w * 0.646, h * 0.1633, w * 0.5618, h * 0.12, w * 0.5, h * 0.12);
741	c.stroke();
742
743	//right ear
744	c.begin();
745	c.moveTo(w * 0.6954, h * 0.3716);
746	c.curveTo(w * 0.6954, h * 0.3716, w * 0.6954, h * 0.341, w * 0.7174, h * 0.3594);
747	c.curveTo(w * 0.7394, h * 0.3778, w * 0.7339, h * 0.4452, w * 0.734, h * 0.4452);
748	c.quadTo(w * 0.7285, h * 0.4942, w * 0.723, h * 0.5065);
749	c.curveTo(w * 0.7175, h * 0.5187, w * 0.723, h * 0.5187, w * 0.7065, h * 0.5371);
750	c.curveTo(w * 0.69, h * 0.5554, w * 0.6625, h * 0.5615, w * 0.6625, h * 0.5616);
751	c.stroke();
752
753	// right shoulder
754	c.begin();
755	c.moveTo(w * 0.6171, h * 0.6213);
756	c.curveTo(w * 0.6171, h * 0.6213, w * 0.595, h * 0.7704, w * 0.7079, h * 0.7888);
757	c.curveTo(w * 0.7464, h * 0.795, w * 0.8672, h * 0.85, w * 0.8948, h * 0.8745);
758	c.curveTo(w * 0.9224, h * 0.899, w * 0.9359, h * 0.9316, w * 0.9429, h * 0.9622);
759	c.quadTo(w * 0.95, h, w * 0.95, h);
760	c.stroke();
761
762	// right hairline
763	c.begin();
764	c.moveTo(w * 0.6573, h * 0.4185);
765	c.curveTo(w * 0.6573, h * 0.4185, w * 0.6573, h * 0.3839, w * 0.6573, h * 0.3593);
766	c.curveTo(w * 0.6573, h * 0.3348, w * 0.6337, h * 0.3103, w * 0.6282, h * 0.3041);
767	c.curveTo(w * 0.6227, h * 0.298, w * 0.6178, h * 0.2673, w * 0.6123, h * 0.2551);
768	c.curveTo(w * 0.6068, h * 0.2429, w * 0.5905, h * 0.2429, w * 0.5741, h * 0.2367);
769	c.curveTo(w * 0.5576, h * 0.2306, w * 0.5016, h * 0.2357, w * 0.5016, h * 0.2357);
770	c.stroke();
771
772	//shirt, right
773	c.begin();
774	c.moveTo(w * 0.635, h * 0.7427);
775	c.curveTo(w * 0.635, h * 0.7427, w * 0.6228, h * 0.8076, w * 0.5714, h * 0.8224);
776	c.curveTo(w * 0.5184, h * 0.8377, w * 0.4972, h * 0.8347, w * 0.4972, h * 0.8347);
777	c.stroke();
778
779	c.begin();
780	c.moveTo(w * 0.6678, h * 0.7764);
781	c.curveTo(w * 0.6678, h * 0.7764, w * 0.6444, h * 0.8386, w * 0.5962, h * 0.8684);
782	c.curveTo(w * 0.5467, h * 0.8991, w * 0.4971, h * 0.8929, w * 0.4971, h * 0.8929);
783	c.stroke();
784
785	c.begin();
786	c.moveTo(w * 0.7283, h * 0.9);
787	c.lineTo(w * 0.7283, h);
788	c.stroke();
789
790	c.begin();
791	c.moveTo(w * 0.8329, h * 0.8991);
792	c.curveTo(w * 0.8329, h * 0.8991, w * 0.8274, h * 0.9114, w * 0.8164, h * 0.9481);
793	c.curveTo(w * 0.8054, h * 0.9849, w * 0.8, h, w * 0.8, h);
794	c.stroke();
795
796	c.setStrokeColor(frameColor);
797	c.begin();
798	c.moveTo(0, 0);
799	c.lineTo(w, 0);
800	c.lineTo(w, h);
801	c.lineTo(0, h);
802	c.close();
803	c.stroke();
804};
805
806mxCellRenderer.registerShape(mxShapeMockupUserMale.prototype.cst.SHAPE_MALE_USER, mxShapeMockupUserMale);
807
808//**********************************************************************************************************************************************************
809//User, Female
810//**********************************************************************************************************************************************************
811/**
812 * Extends mxShape.
813 */
814function mxShapeMockupUserFemale(bounds, fill, stroke, strokewidth)
815{
816	mxShape.call(this);
817	this.bounds = bounds;
818	this.fill = fill;
819	this.stroke = stroke;
820	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
821};
822
823/**
824 * Extends mxShape.
825 */
826mxUtils.extend(mxShapeMockupUserFemale, mxShape);
827
828mxShapeMockupUserFemale.prototype.cst = {
829		STROKE_COLOR2 : 'strokeColor2',
830		SHAPE_FEMALE_USER : 'mxgraph.mockup.containers.userFemale'
831};
832
833mxShapeMockupUserFemale.prototype.customProperties = [
834	{name: 'strokeColor2', dispName: 'Stroke2 Color', type: 'color'}
835];
836
837/**
838 * Function: paintVertexShape
839 *
840 * Paints the vertex shape.
841 */
842mxShapeMockupUserFemale.prototype.paintVertexShape = function(c, x, y, w, h)
843{
844	var bgColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
845	var frameColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#666666');
846	var insideColor = mxUtils.getValue(this.style, mxShapeMockupUserFemale.prototype.cst.STROKE_COLOR2, '#008cff');
847	c.translate(x, y);
848	this.background(c, x, y, w, h, bgColor, frameColor);
849	c.setShadow(false);
850	this.otherShapes(c, x, y, w, h, insideColor, frameColor);
851};
852
853mxShapeMockupUserFemale.prototype.background = function(c, x, y, w, h, bgColor, frameColor)
854{
855	c.setFillColor(bgColor);
856	c.setStrokeColor(frameColor);
857	c.begin();
858	c.moveTo(0, 0);
859	c.lineTo(w, 0);
860	c.lineTo(w, h);
861	c.lineTo(0, h);
862	c.close();
863	c.fillAndStroke();
864};
865
866mxShapeMockupUserFemale.prototype.otherShapes = function(c, x, y, w, h, insideColor, frameColor)
867{
868	//head left
869	c.setStrokeColor(insideColor);
870	c.setLineCap('round');
871	c.setLineJoin('round');
872	c.begin();
873	c.moveTo(w * 0.3148, h * 0.468);
874	c.curveTo(w * 0.3045, h * 0.3195, w * 0.3176, h * 0.2383, w * 0.3302, h * 0.2069);
875	c.curveTo(w * 0.3508, h * 0.1557, w * 0.44, h * 0.1156, w * 0.5026, h * 0.1156);
876	c.stroke();
877
878	c.begin();
879	c.moveTo(w * 0.5029, h * 0.6728);
880	c.curveTo(w * 0.4616, h * 0.6728, w * 0.4018, h * 0.6177, w * 0.3663, h * 0.5653);
881	c.stroke();
882
883	c.begin();
884	c.moveTo(w * 0.3108, h * 0.4021);
885	c.curveTo(w * 0.3108, h * 0.4021, w * 0.3091, h * 0.3765, w * 0.2891, h * 0.3933);
886	c.curveTo(w * 0.2691, h * 0.4101, w * 0.2782, h * 0.4661, w * 0.2782, h * 0.4661);
887	c.quadTo(w * 0.2862, h * 0.5067, w * 0.2922, h * 0.5166);
888	c.curveTo(w * 0.2982, h * 0.5265, w * 0.2929, h * 0.5268, w * 0.3097, h * 0.5412);
889	c.stroke();
890
891	c.begin();
892	c.moveTo(w * 0.4038, h * 0.6176);
893	c.curveTo(w * 0.4038, h * 0.6176, w * 0.4324, h * 0.7778, w * 0.3375, h * 0.7963);
894	c.curveTo(w * 0.3054, h * 0.8026, w * 0.1753, h * 0.8578, w * 0.15, h * 0.8826);
895	c.curveTo(w * 0.1247, h * 0.9074, w * 0.1126, h * 0.9412, w * 0.1063, h * 0.9722);
896	c.curveTo(w * 0.10, h * 1.0032, w * 0.1, h, w * 0.1, h);
897	c.stroke();
898
899	c.begin();
900	c.moveTo(w * 0.6377, h * 0.3365);
901	c.curveTo(w * 0.5927, h * 0.2634, w * 0.5206, h * 0.2634, w * 0.5206, h * 0.2634);
902	c.quadTo(w * 0.3769, h * 0.2591, w * 0.3713, h * 0.2659);
903	c.curveTo(w * 0.3657, h * 0.2727, w * 0.3405, h * 0.3674, w * 0.3405, h * 0.3946);
904	c.curveTo(w * 0.3405, h * 0.4218, w * 0.3405, h * 0.4602, w * 0.3405, h * 0.4602);
905	c.quadTo(w * 0.3546, h * 0.6401, w * 0.3546, h * 0.6626);
906	c.stroke();
907
908	c.begin();
909	c.moveTo(w * 0.2931, h * 0.818);
910	c.curveTo(w * 0.2931, h * 0.818, w * 0.3224, h * 0.9159, w * 0.3826, h * 0.9677);
911	c.curveTo(w * 0.4446, h * 1.01, w * 0.5065, h, w * 0.5065, h);
912	c.stroke();
913
914	c.begin();
915	c.moveTo(w * 0.2995, h * 0.9106);
916	c.lineTo(w * 0.2995, h);
917	c.stroke();
918
919	c.begin();
920	c.moveTo(w * 0.2081, h * 0.907);
921	c.curveTo(w * 0.2081, h * 0.907, w * 0.2131, h * 0.9194, w * 0.2232, h * 0.9565);
922	c.curveTo(w * 0.2333, h * 0.9936, w * 0.24, h, w * 0.24, h);
923	c.stroke();
924
925	c.begin();
926	c.moveTo(w * 0.6951, h * 0.4988);
927	c.curveTo(w * 0.6951, h * 0.4662, w * 0.7042, h * 0.3453, w * 0.7, h * 0.32);
928	c.curveTo(w * 0.6923, h * 0.273, w * 0.6926, h * 0.2175, w * 0.6727, h * 0.19);
929	c.curveTo(w * 0.6504, h * 0.159, w * 0.5651, h * 0.1157, w * 0.5025, h * 0.1157);
930	c.stroke();
931
932	c.begin();
933	c.moveTo(w * 0.5029, h * 0.6728);
934	c.curveTo(w * 0.5546, h * 0.6728, w * 0.6107, h * 0.6316, w * 0.6461, h * 0.5602);
935	c.stroke();
936
937	c.begin();
938	c.moveTo(w * 0.696, h * 0.4022);
939	c.curveTo(w * 0.696, h * 0.4022, w * 0.6983, h * 0.3766, w * 0.7179, h * 0.4106);
940	c.curveTo(w * 0.7375, h * 0.4278, w * 0.7273, h * 0.4836, w * 0.7273, h * 0.4836);
941	c.quadTo(w * 0.7184, h * 0.5241, w * 0.7123, h * 0.5338);
942	c.curveTo(w * 0.7062, h * 0.5436, w * 0.7114, h * 0.544, w * 0.6943, h * 0.558);
943	c.stroke();
944
945	c.begin();
946	c.moveTo(w * 0.5995, h * 0.6278);
947	c.curveTo(w * 0.5995, h * 0.6278, w * 0.5724, h * 0.7777, w * 0.6663, h * 0.7963);
948	c.curveTo(w * 0.6984, h * 0.8026, w * 0.8386, h * 0.8578, w * 0.8638, h * 0.8826);
949	c.curveTo(w * 0.8891, h * 0.9074, w * 0.9016, h * 0.9412, w * 0.9079, h * 0.9722);
950	c.curveTo(w * 0.9142, h * 1.0032, w * 0.91, h, w * 0.91, h);
951	c.stroke();
952
953	c.begin();
954	c.moveTo(w * 0.6545, h * 0.6802);
955	c.lineTo(w * 0.6545, h * 0.3986);
956	c.stroke();
957
958	c.begin();
959	c.moveTo(w * 0.7132, h * 0.8078);
960	c.curveTo(w * 0.7132, h * 0.8078, w * 0.6839, h * 0.916, w * 0.6237, h * 0.9678);
961	c.curveTo(w * 0.5617, h * 1.01, w * 0.4998, h, w * 0.4998, h);
962	c.stroke();
963
964	c.begin();
965	c.moveTo(w * 0.7111, h * 0.9106);
966	c.lineTo(w * 0.7111, h);
967	c.stroke();
968
969	c.begin();
970	c.moveTo(w * 0.8075, h * 0.907);
971	c.curveTo(w * 0.8075, h * 0.907, w * 0.8025, h * 0.9194, w * 0.7924, h * 0.9565);
972	c.curveTo(w * 0.7823, h * 0.9936, w * 0.775, h, w * 0.775, h);
973	c.stroke();
974
975	c.begin();
976	c.moveTo(w * 0.3148, h * 0.5448);
977	c.curveTo(w * 0.3148, h * 0.5448, w * 0.32, h * 0.6216, w * 0.3148, h * 0.6677);
978	c.quadTo(w * 0.2891, h * 0.7343, w * 0.2891, h * 0.7343);
979	c.lineTo(w * 0.3303, h * 0.7625);
980	c.lineTo(w * 0.39, h * 0.7625);
981	c.stroke();
982
983	c.begin();
984	c.moveTo(w * 0.6852, h * 0.5448);
985	c.curveTo(w * 0.6852, h * 0.5448, w * 0.68, h * 0.6216, w * 0.6852, h * 0.6677);
986	c.quadTo(w * 0.7109, h * 0.7343, w * 0.7109, h * 0.7343);
987	c.lineTo(w * 0.6697, h * 0.7625);
988	c.lineTo(w * 0.62, h * 0.7625);
989	c.stroke();
990
991	c.setStrokeColor(frameColor);
992	c.begin();
993	c.moveTo(0, 0);
994	c.lineTo(w, 0);
995	c.lineTo(w, h);
996	c.lineTo(0, h);
997	c.close();
998	c.stroke();
999};
1000
1001mxCellRenderer.registerShape(mxShapeMockupUserFemale.prototype.cst.SHAPE_FEMALE_USER, mxShapeMockupUserFemale);
1002
1003//**********************************************************************************************************************************************************
1004//Group
1005//**********************************************************************************************************************************************************
1006/**
1007 * Extends mxShape.
1008 */
1009function mxShapeMockupGroup(bounds, fill, stroke, strokewidth)
1010{
1011	mxShape.call(this);
1012	this.bounds = bounds;
1013	this.fill = fill;
1014	this.stroke = stroke;
1015	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1016};
1017
1018/**
1019 * Extends mxShape.
1020 */
1021mxUtils.extend(mxShapeMockupGroup, mxShape);
1022
1023mxShapeMockupGroup.prototype.cst = {
1024		MAIN_TEXT : 'mainText',
1025		TEXT_SIZE : 'textSize',
1026		TEXT_COLOR : 'textColor',
1027		FILL_COLOR2 : 'fillColor2',
1028		SHAPE_GROUP : 'mxgraph.mockup.containers.group'
1029};
1030
1031/**
1032 * Function: paintVertexShape
1033 *
1034 * Paints the vertex shape.
1035 */
1036mxShapeMockupGroup.prototype.paintVertexShape = function(c, x, y, w, h)
1037{
1038	var groupString = mxUtils.getValue(this.style, mxShapeMockupGroup.prototype.cst.MAIN_TEXT, 'Group').toString();
1039	var fontSize = mxUtils.getValue(this.style, mxShapeMockupGroup.prototype.cst.TEXT_SIZE, '17');
1040
1041	var textWidth = mxUtils.getSizeForString(groupString, fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
1042
1043	if (textWidth === 0)
1044	{
1045		textWidth = Math.max(80, textWidth);
1046	}
1047
1048	c.translate(x, y);
1049
1050	w = Math.max(w, textWidth + 15);
1051	h = Math.max(h, fontSize + 10);
1052
1053	this.background(c, w, h, textWidth, fontSize);
1054	c.setShadow(false);
1055	this.foreground(c, w, h, textWidth, fontSize);
1056	this.buttonText(c, w, h, groupString, fontSize);
1057};
1058
1059mxShapeMockupGroup.prototype.background = function(c, w, h, textWidth, fontSize)
1060{
1061	c.roundrect(0, fontSize * 0.5, w, h - fontSize * 0.5, 5, 5);
1062	c.fillAndStroke();
1063};
1064
1065mxShapeMockupGroup.prototype.foreground = function(c, w, h, textWidth, fontSize)
1066{
1067	var fillColor = mxUtils.getValue(this.style, mxShapeMockupGroup.prototype.cst.FILL_COLOR2, '#000000');
1068	c.setFillColor(fillColor);
1069	c.roundrect(3, 0, textWidth + 6, fontSize * 1.5, fontSize * 0.25, fontSize * 0.25);
1070	c.fill();
1071};
1072
1073mxShapeMockupGroup.prototype.buttonText = function(c, w, h, textString, fontSize)
1074{
1075	var fontColor = mxUtils.getValue(this.style, mxShapeMockupGroup.prototype.cst.TEXT_COLOR, '#ffffff');
1076
1077	c.setFontColor(fontColor);
1078	c.setFontSize(fontSize);
1079	c.text(6, 0, 0, 0, textString, mxConstants.ALIGN_LEFT, mxConstants.ALIGN_TOP, 0, null, 0, 0, 0);
1080};
1081
1082mxCellRenderer.registerShape(mxShapeMockupGroup.prototype.cst.SHAPE_GROUP, mxShapeMockupGroup);
1083
1084//**********************************************************************************************************************************************************
1085//Window
1086//**********************************************************************************************************************************************************
1087/**
1088 * Extends mxShape.
1089 */
1090function mxShapeMockupWindow(bounds, fill, stroke, strokewidth)
1091{
1092	mxShape.call(this);
1093	this.bounds = bounds;
1094	this.fill = fill;
1095	this.stroke = stroke;
1096	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1097};
1098
1099/**
1100 * Extends mxShape.
1101 */
1102mxUtils.extend(mxShapeMockupWindow, mxShape);
1103
1104mxShapeMockupWindow.prototype.cst = {
1105		MAIN_TEXT : 'mainText',
1106		TEXT_SIZE : 'textSize',
1107		TEXT_COLOR : 'textColor',
1108		STROKE_COLOR2 : 'strokeColor2',
1109		STROKE_COLOR3 : 'strokeColor3',
1110		SHAPE_WINDOW : 'mxgraph.mockup.containers.window'
1111};
1112
1113mxShapeMockupWindow.prototype.customProperties = [
1114	{name: 'strokeColor2', dispName: 'Stroke2 Color', type: 'color'},
1115	{name: 'strokeColor3', dispName: 'Stroke3 Color', type: 'color'}
1116];
1117
1118/**
1119 * Function: paintVertexShape
1120 *
1121 * Paints the vertex shape.
1122 */
1123mxShapeMockupWindow.prototype.paintVertexShape = function(c, x, y, w, h)
1124{
1125	var bgColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
1126	var frameColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#666666');
1127	var closeColor = mxUtils.getValue(this.style, mxShapeMockupWindow.prototype.cst.STROKE_COLOR2, '#008cff');
1128	var insideColor = mxUtils.getValue(this.style, mxShapeMockupWindow.prototype.cst.STROKE_COLOR3, '#c4c4c4');
1129	c.translate(x, y);
1130
1131	h = Math.max(h, 30);
1132	w = Math.max(w, 90);
1133
1134	this.background(c, x, y, w, h, bgColor, frameColor);
1135	c.setShadow(false);
1136	this.otherShapes(c, x, y, w, h, frameColor, insideColor, closeColor);
1137};
1138
1139mxShapeMockupWindow.prototype.background = function(c, x, y, w, h, bgColor, frameColor)
1140{
1141	c.setFillColor(bgColor);
1142	c.setStrokeColor(frameColor);
1143	c.rect(0, 0, w, h);
1144	c.fillAndStroke();
1145};
1146
1147mxShapeMockupWindow.prototype.otherShapes = function(c, x, y, w, h, frameColor, insideColor, closeColor)
1148{
1149	var strokeWidth = mxUtils.getValue(this.style, mxConstants.STYLE_STROKEWIDTH, '1');
1150
1151	//window buttons
1152	c.setStrokeColor(frameColor);
1153	c.ellipse(w - 75, 5, 20, 20);
1154	c.stroke();
1155
1156	c.ellipse(w - 50, 5, 20, 20);
1157	c.stroke();
1158
1159	c.setStrokeColor(closeColor);
1160	c.ellipse(w - 25, 5, 20, 20);
1161	c.stroke();
1162
1163	c.setStrokeColor(insideColor);
1164	//lines
1165	c.begin();
1166	c.moveTo(0, 30);
1167	c.lineTo(w, 30);
1168	c.stroke();
1169
1170	//text
1171	var windowTitle = mxUtils.getValue(this.style, mxShapeMockupWindow.prototype.cst.MAIN_TEXT, 'Window Title');
1172	var fontColor = mxUtils.getValue(this.style, mxShapeMockupWindow.prototype.cst.TEXT_COLOR, '#666666');
1173	var fontSize = mxUtils.getValue(this.style, mxShapeMockupWindow.prototype.cst.TEXT_SIZE, '17').toString();
1174
1175	c.setFontColor(fontColor);
1176	c.setFontSize(fontSize);
1177	c.text(10, 15, 0, 0, windowTitle, mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1178	c.stroke();
1179};
1180
1181mxCellRenderer.registerShape(mxShapeMockupWindow.prototype.cst.SHAPE_WINDOW, mxShapeMockupWindow);
1182
1183//**********************************************************************************************************************************************************
1184//Horizontal Tab Bar (LEGACY)
1185//**********************************************************************************************************************************************************
1186/**
1187 * Extends mxShape.
1188 */
1189function mxShapeMockupHorTabBar(bounds, fill, stroke, strokewidth)
1190{
1191	mxShape.call(this);
1192	this.bounds = bounds;
1193	this.fill = fill;
1194	this.stroke = stroke;
1195	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1196};
1197
1198/**
1199 * Extends mxShape.
1200 */
1201mxUtils.extend(mxShapeMockupHorTabBar, mxShape);
1202
1203mxShapeMockupHorTabBar.prototype.cst = {
1204		BLOCK : 'block',
1205		CONE : 'cone',
1206		HALF_CONE : 'halfCone',
1207		ROUND : 'round',
1208		TEXT_SIZE : 'textSize',
1209		TAB_NAMES : 'tabs',
1210		TAB_STYLE : 'tabStyle',
1211		STYLE_FILLCOLOR2 : 'fillColor2',
1212		TEXT_COLOR : 'textColor',
1213		SEL_TEXT_COLOR : 'textColor2',
1214		SHAPE_HOR_TAB_BAR : 'mxgraph.mockup.containers.horTabBar'
1215};
1216
1217/**
1218 * Function: paintVertexShape
1219 *
1220 * Paints the vertex shape.
1221 */
1222//TODO tab widths are fixed, so tab text length is a bit of an issue. Cannot be fixed while we use labels for tab names
1223mxShapeMockupHorTabBar.prototype.paintVertexShape = function(c, x, y, w, h)
1224{
1225	var fontSize = mxUtils.getValue(this.style, mxShapeMockupHorTabBar.prototype.cst.TEXT_SIZE, '17').toString();
1226	var tabNames = mxUtils.getValue(this.style, mxShapeMockupHorTabBar.prototype.cst.TAB_NAMES, 'Tab 1,+Tab 2,Tab 3').toString().split(',');
1227
1228	var tabH = fontSize * 1.5;
1229	var startOffset = 10;
1230	var tabOffset = 5;
1231	var labelOffset = 10;
1232	var tabCount = tabNames.length;
1233	var minW = 2 * startOffset + (tabCount - 1) * tabOffset + tabCount * 2 * labelOffset;
1234	var rSize = 5;
1235	var labelWidths = new Array();
1236	var selectedTab = -1;
1237
1238	for (var i = 0; i < tabCount; i++)
1239	{
1240		var currLabel = tabNames[i];
1241
1242		if(currLabel.charAt(0) === '+')
1243		{
1244			currLabel = currLabel.substring(1);
1245			selectedTab = i;
1246		}
1247
1248		currW = mxUtils.getSizeForString(currLabel, fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
1249
1250		if (currW === 0)
1251		{
1252			labelWidths[i] = 40;
1253		}
1254		else
1255		{
1256			labelWidths[i] = currW;
1257		};
1258
1259		minW = minW + labelWidths[i];
1260	}
1261
1262	w = Math.max(w, minW);
1263	h = Math.max(h, tabH + rSize);
1264
1265	c.translate(x, y);
1266
1267	this.background(c, w, h, rSize, tabH);
1268	c.setShadow(false);
1269	this.backTabs(c, w, h, rSize, tabH, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab);
1270	this.focusTab(c, w, h, rSize, tabH, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab);
1271	this.tabText(c, w, h, rSize, tabH, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab, tabNames);
1272};
1273
1274mxShapeMockupHorTabBar.prototype.background = function(c, w, h, rSize, tabH)
1275{
1276	c.begin();
1277	c.moveTo(0, tabH + rSize);
1278	c.arcTo(rSize, rSize, 0, 0, 1, rSize, tabH);
1279	c.lineTo(w - rSize, tabH);
1280	c.arcTo(rSize, rSize, 0, 0, 1, w, tabH + rSize);
1281	c.lineTo(w, h);
1282	c.lineTo(0, h);
1283	c.close();
1284	c.fillAndStroke();
1285};
1286
1287mxShapeMockupHorTabBar.prototype.backTabs = function(c, w, h, rSize, tabH, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab)
1288{
1289	var tabStyle = mxUtils.getValue(this.style, mxShapeMockupHorTabBar.prototype.cst.TAB_STYLE, mxShapeMockupHorTabBar.prototype.cst.BLOCK);
1290
1291	var currW = startOffset;
1292	for (var i=0; i < tabCount; i++)
1293	{
1294		var tabW = labelWidths[i] + 2 * labelOffset;
1295
1296		if (selectedTab !== i)
1297		{
1298			if (tabStyle === mxShapeMockupHorTabBar.prototype.cst.BLOCK)
1299			{
1300				c.rect(currW, 0, tabW, tabH);
1301			}
1302			else if (tabStyle === mxShapeMockupHorTabBar.prototype.cst.CONE)
1303			{
1304				c.begin();
1305				c.moveTo(currW, tabH);
1306				c.lineTo(currW + labelOffset * 0.5, 0);
1307				c.lineTo(currW + tabW - labelOffset * 0.5, 0);
1308				c.lineTo(currW + tabW, tabH);
1309			}
1310			else if (tabStyle === mxShapeMockupHorTabBar.prototype.cst.HALF_CONE)
1311			{
1312				c.begin();
1313				c.moveTo(currW, tabH);
1314				c.lineTo(currW + labelOffset * 0.5, 0);
1315				c.lineTo(currW + tabW, 0);
1316				c.lineTo(currW + tabW, tabH);
1317			}
1318			else if (tabStyle === mxShapeMockupHorTabBar.prototype.cst.ROUND)
1319			{
1320				c.begin();
1321				c.moveTo(currW - rSize, tabH);
1322				c.arcTo(rSize, rSize, 0, 0, 0, currW, tabH - rSize);
1323				c.lineTo(currW, rSize);
1324				c.arcTo(rSize, rSize, 0, 0, 1, currW + rSize, 0);
1325				c.lineTo(currW + tabW - rSize, 0);
1326				c.arcTo(rSize, rSize, 0, 0, 1, currW + tabW, rSize);
1327				c.lineTo(currW + tabW, tabH - rSize);
1328				c.arcTo(rSize, rSize, 0, 0, 0, currW + tabW + rSize, tabH);
1329			}
1330
1331			c.fillAndStroke();
1332		}
1333
1334		currW = currW + tabW + tabOffset;
1335	}
1336};
1337
1338mxShapeMockupHorTabBar.prototype.focusTab = function(c, w, h, rSize, tabH, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab)
1339{
1340	var tabStyle = mxUtils.getValue(this.style, mxShapeMockupHorTabBar.prototype.cst.TAB_STYLE, mxShapeMockupHorTabBar.prototype.cst.BLOCK);
1341	var selectedFill = mxUtils.getValue(this.style, mxShapeMockupHorTabBar.prototype.cst.STYLE_FILLCOLOR2, '#008cff');
1342
1343	var currW = startOffset;
1344	c.setStrokeColor(selectedFill);
1345	c.setFillColor(selectedFill);
1346
1347	for (var i=0; i <= selectedTab; i++)
1348	{
1349		var tabW = labelWidths[i] + 2 * labelOffset;
1350
1351		if (selectedTab === i)
1352		{
1353			if (tabStyle === mxShapeMockupHorTabBar.prototype.cst.BLOCK)
1354			{
1355				c.begin();
1356				c.moveTo(0, tabH + rSize);
1357				c.arcTo(rSize, rSize, 0, 0, 1, rSize, tabH);
1358				c.lineTo(currW, tabH);
1359				c.lineTo(currW, 0);
1360				c.lineTo(currW + tabW, 0);
1361				c.lineTo(currW + tabW, tabH);
1362				c.lineTo(w - rSize, tabH);
1363				c.arcTo(rSize, rSize, 0, 0, 1, w, tabH + rSize);
1364				c.close();
1365			}
1366			else if (tabStyle === mxShapeMockupHorTabBar.prototype.cst.CONE)
1367			{
1368				c.begin();
1369				c.moveTo(0, tabH + rSize);
1370				c.arcTo(rSize, rSize, 0, 0, 1, rSize, tabH);
1371				c.lineTo(currW, tabH);
1372				c.lineTo(currW + labelOffset * 0.5, 0);
1373				c.lineTo(currW + tabW - labelOffset * 0.5, 0);
1374				c.lineTo(currW + tabW, tabH);
1375				c.lineTo(w - rSize, tabH);
1376				c.arcTo(rSize, rSize, 0, 0, 1, w, tabH + rSize);
1377				c.close();
1378			}
1379			else if (tabStyle === mxShapeMockupHorTabBar.prototype.cst.HALF_CONE)
1380			{
1381				c.begin();
1382				c.moveTo(0, tabH + rSize);
1383				c.arcTo(rSize, rSize, 0, 0, 1, rSize, tabH);
1384				c.lineTo(currW, tabH);
1385				c.lineTo(currW + labelOffset * 0.5, 0);
1386				c.lineTo(currW + tabW, 0);
1387				c.lineTo(currW + tabW, tabH);
1388				c.lineTo(w - rSize, tabH);
1389				c.arcTo(rSize, rSize, 0, 0, 1, w, tabH + rSize);
1390				c.close();
1391			}
1392			else if (tabStyle === mxShapeMockupHorTabBar.prototype.cst.ROUND)
1393			{
1394				c.begin();
1395				c.moveTo(0, tabH + rSize);
1396				c.arcTo(rSize, rSize, 0, 0, 1, rSize, tabH);
1397				c.lineTo(currW - rSize, tabH);
1398				c.arcTo(rSize, rSize, 0, 0, 0, currW, tabH - rSize);
1399				c.lineTo(currW, rSize);
1400				c.arcTo(rSize, rSize, 0, 0, 1, currW + rSize, 0);
1401				c.lineTo(currW + tabW - rSize, 0);
1402				c.arcTo(rSize, rSize, 0, 0, 1, currW + tabW, rSize);
1403				c.lineTo(currW + tabW, tabH - rSize);
1404				c.arcTo(rSize, rSize, 0, 0, 0, currW + tabW + rSize, tabH);
1405				c.lineTo(w - rSize, tabH);
1406				c.arcTo(rSize, rSize, 0, 0, 1, w, tabH + rSize);
1407				c.close();
1408			}
1409
1410			c.fillAndStroke();
1411		}
1412
1413		currW = currW + tabW + tabOffset;
1414	}
1415};
1416
1417mxShapeMockupHorTabBar.prototype.tabText = function(c, w, h, rSize, tabH, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab, tabNames)
1418{
1419	var fontColor = mxUtils.getValue(this.style, mxShapeMockupHorTabBar.prototype.cst.TEXT_COLOR, '#666666');
1420	var selFontColor = mxUtils.getValue(this.style, mxShapeMockupHorTabBar.prototype.cst.SEL_TEXT_COLOR, '#ffffff');
1421	var fontSize = mxUtils.getValue(this.style, mxShapeMockupHorTabBar.prototype.cst.TEXT_SIZE, '17').toString();
1422
1423	c.setFontColor(fontColor);
1424	c.setFontSize(fontSize);
1425
1426	var currW = startOffset;
1427
1428	for (var i=0; i < tabCount; i++)
1429	{
1430		var currLabel = tabNames[i];
1431
1432		if (i === selectedTab)
1433		{
1434			c.setFontColor(selFontColor);
1435		}
1436
1437		if (currLabel.charAt(0) === '+')
1438		{
1439			currLabel = currLabel.substring(1);
1440		}
1441
1442		var tabW = labelWidths[i] + 2 * labelOffset;
1443
1444		c.text(currW + labelOffset, tabH * 0.5, 0, 0, currLabel, mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1445
1446		currW = currW + tabW + tabOffset;
1447
1448		if (i === selectedTab)
1449		{
1450			c.setFontColor(fontColor);
1451		}
1452	}
1453
1454};
1455
1456mxCellRenderer.registerShape(mxShapeMockupHorTabBar.prototype.cst.SHAPE_HOR_TAB_BAR, mxShapeMockupHorTabBar);
1457
1458//**********************************************************************************************************************************************************
1459//Vertical Tab Bar (LEGACY)
1460//**********************************************************************************************************************************************************
1461/**
1462 * Extends mxShape.
1463 */
1464//TODO tab widths are fixed, so tab text length is a bit of an issue. Cannot be fixed while we use labels for tab names
1465function mxShapeMockupVerTabBar(bounds, fill, stroke, strokewidth)
1466{
1467	mxShape.call(this);
1468	this.bounds = bounds;
1469	this.fill = fill;
1470	this.stroke = stroke;
1471	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1472};
1473
1474/**
1475 * Extends mxShape.
1476 */
1477mxUtils.extend(mxShapeMockupVerTabBar, mxShape);
1478
1479mxShapeMockupVerTabBar.prototype.cst = {
1480		BLOCK : 'block',
1481		ROUND : 'round',
1482		TEXT_SIZE : 'textSize',
1483		TAB_NAMES : 'tabs',
1484		TAB_STYLE : 'tabStyle',
1485		STYLE_FILLCOLOR2 : 'fillColor2',
1486		TEXT_COLOR : 'textColor',
1487		SEL_TEXT_COLOR : 'textColor2',
1488		SHAPE_VER_TAB_BAR : 'mxgraph.mockup.containers.verTabBar'
1489};
1490
1491/**
1492 * Function: paintVertexShape
1493 *
1494 * Paints the vertex shape.
1495 */
1496mxShapeMockupVerTabBar.prototype.paintVertexShape = function(c, x, y, w, h)
1497{
1498	var fontSize = mxUtils.getValue(this.style, mxShapeMockupVerTabBar.prototype.cst.TEXT_SIZE, '17').toString();
1499	var tabNames = mxUtils.getValue(this.style, mxShapeMockupVerTabBar.prototype.cst.TAB_NAMES, 'Tab 1,+Tab 2,Tab 3').toString().split(',');
1500
1501	var tabH = fontSize * 1.5;
1502	var startOffset = 10;
1503	var tabOffset = 5;
1504	var labelOffset = 10;
1505	var tabCount = tabNames.length;
1506	var rSize = 5;
1507	var labelWidths = new Array();
1508	var selectedTab = -1;
1509	for (var i = 0; i < tabCount; i++)
1510	{
1511		var currLabel = tabNames[i];
1512
1513		if(currLabel.charAt(0) === '+')
1514		{
1515			currLabel = currLabel.substring(1);
1516			selectedTab = i;
1517		}
1518
1519		var currW = mxUtils.getSizeForString(currLabel, fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
1520
1521		if (currW === 0)
1522		{
1523			labelWidths[i] = 42;
1524		}
1525		else
1526		{
1527			labelWidths[i] = currW;
1528		}
1529	}
1530
1531	var tabW = 2 * labelOffset + Math.max.apply(Math, labelWidths);
1532	var minW = tabW + rSize;
1533	w = Math.max(w, minW);
1534	h = Math.max(h, 2 * startOffset + tabCount * tabH + (tabCount - 1) * tabOffset);
1535
1536	c.translate(x, y);
1537
1538	this.background(c, w, h, rSize, tabW);
1539	c.setShadow(false);
1540	this.backTabs(c, w, h, rSize, tabH, tabW, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab);
1541	this.focusTab(c, w, h, rSize, tabH, tabW, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab);
1542	this.tabText(c, w, h, rSize, tabH, tabW, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab, tabNames);
1543};
1544
1545mxShapeMockupVerTabBar.prototype.background = function(c, w, h, rSize, tabW)
1546{
1547	c.begin();
1548	c.moveTo(tabW + rSize, h);
1549	c.arcTo(rSize, rSize, 0, 0, 1, tabW, h - rSize);
1550	c.lineTo(tabW, rSize);
1551	c.arcTo(rSize, rSize, 0, 0, 1, tabW + rSize, 0);
1552	c.lineTo(w, 0);
1553	c.lineTo(w, h);
1554	c.close();
1555	c.fillAndStroke();
1556};
1557
1558mxShapeMockupVerTabBar.prototype.backTabs = function(c, w, h, rSize, tabH, tabW, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab)
1559{
1560	var tabStyle = mxUtils.getValue(this.style, mxShapeMockupVerTabBar.prototype.cst.TAB_STYLE, mxShapeMockupVerTabBar.prototype.cst.BLOCK);
1561
1562	var currH = startOffset;
1563
1564	for (var i=0; i < tabCount; i++)
1565	{
1566		if (selectedTab !== i)
1567		{
1568			if (tabStyle === mxShapeMockupVerTabBar.prototype.cst.BLOCK)
1569			{
1570				c.rect(0, currH, tabW, tabH);
1571			}
1572			else if (tabStyle === mxShapeMockupVerTabBar.prototype.cst.ROUND)
1573			{
1574				c.begin();
1575				c.moveTo(tabW, currH + tabH + rSize);
1576				c.arcTo(rSize, rSize, 0, 0, 0, tabW - rSize, currH + tabH);
1577				c.lineTo(rSize, currH + tabH);
1578				c.arcTo(rSize, rSize, 0, 0, 1, 0, currH + tabH - rSize);
1579				c.lineTo(0, currH + rSize);
1580				c.arcTo(rSize, rSize, 0, 0, 1, rSize, currH);
1581				c.lineTo(tabW - rSize, currH);
1582				c.arcTo(rSize, rSize, 0, 0, 0, tabW, currH - rSize);
1583			}
1584
1585			c.fillAndStroke();
1586		}
1587
1588		currH = currH + tabH + tabOffset;
1589	}
1590};
1591
1592mxShapeMockupVerTabBar.prototype.focusTab = function(c, w, h, rSize, tabH, tabW, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab)
1593{
1594	var tabStyle = mxUtils.getValue(this.style, mxShapeMockupVerTabBar.prototype.cst.TAB_STYLE, mxShapeMockupVerTabBar.prototype.cst.BLOCK);
1595	var selectedFill = mxUtils.getValue(this.style, mxShapeMockupVerTabBar.prototype.cst.STYLE_FILLCOLOR2, '#008cff');
1596
1597	if (selectedTab !== -1)
1598	{
1599
1600		var currH = startOffset + (tabH  + tabOffset) * selectedTab;
1601		c.setStrokeColor(selectedFill);
1602		c.setFillColor(selectedFill);
1603
1604		if (tabStyle === mxShapeMockupVerTabBar.prototype.cst.BLOCK)
1605		{
1606			c.begin();
1607			c.moveTo(tabW + rSize, h);
1608			c.arcTo(rSize, rSize, 0, 0, 1, tabW, h - rSize);
1609			c.lineTo(tabW, currH + tabH);
1610			c.lineTo(0, currH + tabH);
1611			c.lineTo(0, currH);
1612			c.lineTo(tabW, currH);
1613			c.lineTo(tabW, rSize);
1614			c.arcTo(rSize, rSize, 0, 0, 1, tabW + rSize, 0);
1615			c.close();
1616		}
1617		else if (tabStyle === mxShapeMockupVerTabBar.prototype.cst.ROUND)
1618		{
1619			c.begin();
1620			c.moveTo(tabW + rSize, h);
1621			c.arcTo(rSize, rSize, 0, 0, 1, tabW, h - rSize);
1622			c.lineTo(tabW, currH + tabH + rSize);
1623			c.arcTo(rSize, rSize, 0, 0, 0, tabW - rSize, currH + tabH);
1624			c.lineTo(rSize, currH + tabH);
1625			c.arcTo(rSize, rSize, 0, 0, 1, 0, currH + tabH - rSize);
1626			c.lineTo(0, currH + rSize);
1627			c.arcTo(rSize, rSize, 0, 0, 1, rSize, currH);
1628			c.lineTo(tabW - rSize, currH);
1629			c.arcTo(rSize, rSize, 0, 0, 0, tabW, currH - rSize);
1630			c.lineTo(tabW, rSize);
1631			c.arcTo(rSize, rSize, 0, 0, 1, tabW + rSize, 0);
1632			c.close();
1633		}
1634
1635		c.fillAndStroke();
1636	}
1637
1638};
1639
1640mxShapeMockupVerTabBar.prototype.tabText = function(c, w, h, rSize, tabH, tabW, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab, tabNames)
1641{
1642	var fontColor = mxUtils.getValue(this.style, mxShapeMockupVerTabBar.prototype.cst.TEXT_COLOR, '#666666');
1643	var selFontColor = mxUtils.getValue(this.style, mxShapeMockupVerTabBar.prototype.cst.SEL_TEXT_COLOR, '#ffffff');
1644	var fontSize = mxUtils.getValue(this.style, mxShapeMockupVerTabBar.prototype.cst.TEXT_SIZE, '17').toString();
1645
1646	c.setFontColor(fontColor);
1647	c.setFontSize(fontSize);
1648
1649	var currH = startOffset;
1650
1651	for (var i=0; i < tabCount; i++)
1652	{
1653		var currLabel = tabNames[i];
1654
1655		if (i === selectedTab)
1656		{
1657			c.setFontColor(selFontColor);
1658		}
1659
1660		if (currLabel.charAt(0) === '+')
1661		{
1662			currLabel = currLabel.substring(1);
1663		}
1664
1665		c.text(tabW * 0.5, currH + tabH * 0.5, 0, 0, currLabel, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1666
1667		currH = currH + tabH + tabOffset;
1668
1669		if (i === selectedTab)
1670		{
1671			c.setFontColor(fontColor);
1672		}
1673	}
1674
1675};
1676
1677mxCellRenderer.registerShape(mxShapeMockupVerTabBar.prototype.cst.SHAPE_VER_TAB_BAR, mxShapeMockupVerTabBar);
1678
1679//**********************************************************************************************************************************************************
1680//Alert Box (LEGACY)
1681//**********************************************************************************************************************************************************
1682/**
1683 * Extends mxShape.
1684 */
1685function mxShapeMockupAlertBox(bounds, fill, stroke, strokewidth)
1686{
1687	mxShape.call(this);
1688	this.bounds = bounds;
1689	this.fill = fill;
1690	this.stroke = stroke;
1691	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1692};
1693
1694/**
1695 * Extends mxShape.
1696 */
1697mxUtils.extend(mxShapeMockupAlertBox, mxShape);
1698
1699mxShapeMockupAlertBox.prototype.cst = {
1700		MAIN_TEXT : 'mainText',
1701		SUB_TEXT : 'subText',
1702		BUTTON_TEXT : 'buttonText',
1703		TEXT_SIZE : 'textSize',
1704		TEXT_COLOR : 'textColor',
1705		STROKE_COLOR2 : 'strokeColor2',
1706		STROKE_COLOR3 : 'strokeColor3',
1707		SHAPE_ALERT_BOX : 'mxgraph.mockup.containers.alertBox'
1708};
1709
1710/**
1711 * Function: paintVertexShape
1712 *
1713 * Paints the vertex shape.
1714 */
1715mxShapeMockupAlertBox.prototype.paintVertexShape = function(c, x, y, w, h)
1716{
1717	var bgColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
1718	var frameColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#666666');
1719	var closeColor = mxUtils.getValue(this.style, mxShapeMockupAlertBox.prototype.cst.STROKE_COLOR2, '#008cff');
1720	var insideColor = mxUtils.getValue(this.style, mxShapeMockupAlertBox.prototype.cst.STROKE_COLOR3, '#c4c4c4');
1721	c.translate(x, y);
1722
1723	h = Math.max(h, 75);
1724	w = Math.max(w, 90);
1725
1726	this.background(c, x, y, w, h, bgColor, frameColor);
1727	c.setShadow(false);
1728	this.foreground(c, x, y, w, h, frameColor, insideColor, closeColor);
1729};
1730
1731mxShapeMockupAlertBox.prototype.background = function(c, x, y, w, h, bgColor, frameColor)
1732{
1733	c.setFillColor(bgColor);
1734	c.setStrokeColor(frameColor);
1735	c.rect(0, 0, w, h);
1736	c.fillAndStroke();
1737};
1738
1739mxShapeMockupAlertBox.prototype.foreground = function(c, x, y, w, h, frameColor, insideColor, closeColor)
1740{
1741	var strokeWidth = mxUtils.getValue(this.style, mxConstants.STYLE_STROKEWIDTH, '1');
1742
1743	c.setStrokeColor(closeColor);
1744	c.ellipse(w - 25, 5, 20, 20);
1745	c.stroke();
1746
1747	c.setStrokeColor(insideColor);
1748	c.begin();
1749	c.moveTo(0, 30);
1750	c.lineTo(w, 30);
1751	c.stroke();
1752
1753	//buttons
1754	var windowTitle = mxUtils.getValue(this.style, mxShapeMockupAlertBox.prototype.cst.MAIN_TEXT, 'Window Title').toString();
1755	var subText = mxUtils.getValue(this.style, mxShapeMockupAlertBox.prototype.cst.SUB_TEXT, 'Sub Text').toString().split(',');
1756	var buttonText = mxUtils.getValue(this.style, mxShapeMockupAlertBox.prototype.cst.BUTTON_TEXT, 'OK,Cancel').toString().split(',');
1757	var fontColor = mxUtils.getValue(this.style, mxShapeMockupAlertBox.prototype.cst.TEXT_COLOR, '#666666');
1758	var fontSize = mxUtils.getValue(this.style, mxShapeMockupAlertBox.prototype.cst.TEXT_SIZE, '17').toString();
1759
1760	var buttonCount = buttonText.length;
1761	var buttonOffset = 10;
1762	var buttonW = (w - buttonOffset * (buttonCount + 1)) / buttonCount;
1763
1764	c.setFontColor(fontColor);
1765	c.setFontSize(fontSize);
1766	c.text(10, 15, 0, 0, windowTitle, mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1767
1768	var currW = buttonOffset;
1769
1770	for (var i = 0; i < buttonText.length; i++)
1771	{
1772		if (buttonText[i] !== '')
1773		{
1774			c.rect(currW, h - 10 - fontSize * 1.5, buttonW, fontSize * 1.5);
1775			c.stroke();
1776			c.text(currW + buttonW * 0.5, h - 10 - fontSize * 0.75, 0, 0, buttonText[i], mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1777		}
1778
1779		currW = currW + buttonW + buttonOffset;
1780	}
1781
1782
1783	for (var i = 0; i < subText.length; i++)
1784	{
1785		c.text(w * 0.5, 30 + fontSize * (i * 1.5 + 0.75), 0, 0, subText[i], mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1786	}
1787
1788	c.stroke();
1789};
1790
1791mxCellRenderer.registerShape(mxShapeMockupAlertBox.prototype.cst.SHAPE_ALERT_BOX, mxShapeMockupAlertBox);
1792
1793//**********************************************************************************************************************************************************
1794//Rounded rectangle (adjustable rounding)
1795//**********************************************************************************************************************************************************
1796/**
1797* Extends mxShape.
1798*/
1799function mxShapeMockupContainersRRect(bounds, fill, stroke, strokewidth)
1800{
1801	mxShape.call(this);
1802	this.bounds = bounds;
1803	this.fill = fill;
1804	this.stroke = stroke;
1805	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1806};
1807
1808/**
1809* Extends mxShape.
1810*/
1811mxUtils.extend(mxShapeMockupContainersRRect, mxShape);
1812
1813mxShapeMockupContainersRRect.prototype.cst = {
1814		RRECT : 'mxgraph.mockup.containers.rrect',
1815		R_SIZE : 'rSize'
1816};
1817
1818mxShapeMockupContainersRRect.prototype.customProperties = [
1819	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10},
1820];
1821
1822/**
1823* Function: paintVertexShape
1824*
1825* Paints the vertex shape.
1826*/
1827mxShapeMockupContainersRRect.prototype.paintVertexShape = function(c, x, y, w, h)
1828{
1829	c.translate(x, y);
1830
1831	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeMockupContainersRRect.prototype.cst.R_SIZE, '10'));
1832	c.roundrect(0, 0, w, h, rSize);
1833	c.fillAndStroke();
1834};
1835
1836mxCellRenderer.registerShape(mxShapeMockupContainersRRect.prototype.cst.RRECT, mxShapeMockupContainersRRect);
1837
1838//**********************************************************************************************************************************************************
1839//Anchor (a dummy shape without visuals used for anchoring)
1840//**********************************************************************************************************************************************************
1841/**
1842* Extends mxShape.
1843*/
1844function mxShapeMockupContainersAnchor(bounds, fill, stroke, strokewidth)
1845{
1846	mxShape.call(this);
1847	this.bounds = bounds;
1848};
1849
1850/**
1851* Extends mxShape.
1852*/
1853mxUtils.extend(mxShapeMockupContainersAnchor, mxShape);
1854
1855mxShapeMockupContainersAnchor.prototype.cst = {
1856		ANCHOR : 'mxgraph.mockup.containers.anchor'
1857};
1858
1859/**
1860* Function: paintVertexShape
1861*
1862* Paints the vertex shape.
1863*/
1864mxShapeMockupContainersAnchor.prototype.paintVertexShape = function(c, x, y, w, h)
1865{
1866};
1867
1868mxCellRenderer.registerShape(mxShapeMockupContainersAnchor.prototype.cst.ANCHOR, mxShapeMockupContainersAnchor);
1869
1870//**********************************************************************************************************************************************************
1871//Top Button
1872//**********************************************************************************************************************************************************
1873/**
1874* Extends mxShape.
1875*/
1876function mxShapeMockupContrainersTopButton(bounds, fill, stroke, strokewidth)
1877{
1878	mxShape.call(this);
1879	this.bounds = bounds;
1880	this.fill = fill;
1881	this.stroke = stroke;
1882	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1883};
1884
1885/**
1886* Extends mxShape.
1887*/
1888mxUtils.extend(mxShapeMockupContrainersTopButton, mxShape);
1889
1890mxShapeMockupContrainersTopButton.prototype.cst = {
1891		TOP_BUTTON : 'mxgraph.mockup.containers.topButton',
1892		R_SIZE : 'rSize'
1893};
1894
1895mxShapeMockupContrainersTopButton.prototype.customProperties = [
1896	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10},
1897];
1898
1899/**
1900* Function: paintVertexShape
1901*
1902* Paints the vertex shape.
1903*/
1904mxShapeMockupContrainersTopButton.prototype.paintVertexShape = function(c, x, y, w, h)
1905{
1906	c.translate(x, y);
1907
1908	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeMockupContrainersTopButton.prototype.cst.R_SIZE, '10'));
1909
1910	c.begin();
1911	c.moveTo(0, rSize);
1912	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
1913	c.lineTo(w - rSize, 0);
1914	c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
1915	c.lineTo(w, h);
1916	c.lineTo(0, h);
1917	c.close();
1918	c.fillAndStroke();
1919};
1920
1921mxCellRenderer.registerShape(mxShapeMockupContrainersTopButton.prototype.cst.TOP_BUTTON, mxShapeMockupContrainersTopButton);
1922
1923//**********************************************************************************************************************************************************
1924//Left Button
1925//**********************************************************************************************************************************************************
1926/**
1927* Extends mxShape.
1928*/
1929function mxShapeMockupContainersLeftButton(bounds, fill, stroke, strokewidth)
1930{
1931	mxShape.call(this);
1932	this.bounds = bounds;
1933	this.fill = fill;
1934	this.stroke = stroke;
1935	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1936};
1937
1938/**
1939* Extends mxShape.
1940*/
1941mxUtils.extend(mxShapeMockupContainersLeftButton, mxShape);
1942
1943mxShapeMockupContainersLeftButton.prototype.cst = {
1944		LEFT_BUTTON : 'mxgraph.mockup.containers.leftButton',
1945		R_SIZE : 'rSize'
1946};
1947
1948mxShapeMockupContainersLeftButton.prototype.customProperties = [
1949	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10},
1950];
1951
1952/**
1953* Function: paintVertexShape
1954*
1955* Paints the vertex shape.
1956*/
1957mxShapeMockupContainersLeftButton.prototype.paintVertexShape = function(c, x, y, w, h)
1958{
1959	c.translate(x, y);
1960
1961	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeMockupContainersLeftButton.prototype.cst.R_SIZE, '10'));
1962
1963	c.begin();
1964	c.moveTo(w, 0);
1965	c.lineTo(w, h);
1966	c.lineTo(rSize, h);
1967	c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
1968	c.lineTo(0, rSize);
1969	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
1970	c.close();
1971	c.fillAndStroke();
1972};
1973
1974mxCellRenderer.registerShape(mxShapeMockupContainersLeftButton.prototype.cst.LEFT_BUTTON, mxShapeMockupContainersLeftButton);
1975
1976//**********************************************************************************************************************************************************
1977//rect with margins
1978//**********************************************************************************************************************************************************
1979/**
1980* Extends mxShape.
1981*/
1982function mxShapeMockupContainersMarginRect(bounds, fill, stroke, strokewidth)
1983{
1984	mxShape.call(this);
1985	this.bounds = bounds;
1986	this.fill = fill;
1987	this.stroke = stroke;
1988	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1989};
1990
1991/**
1992* Extends mxShape.
1993*/
1994mxUtils.extend(mxShapeMockupContainersMarginRect, mxShape);
1995
1996mxShapeMockupContainersMarginRect.prototype.cst = {
1997		SHAPE_MARGIN_RECT : 'mxgraph.mockup.containers.marginRect',
1998		MARGIN : 'rectMargin',
1999		MARGIN_TOP : 'rectMarginTop',
2000		MARGIN_LEFT : 'rectMarginLeft',
2001		MARGIN_BOTTOM : 'rectMarginBottom',
2002		MARGIN_RIGHT : 'rectMarginRight'
2003};
2004
2005mxShapeMockupContainersMarginRect.prototype.customProperties = [
2006	{name: 'rectMargin', dispName: 'Global Margin', type: 'float', min:0, defVal:0},
2007	{name: 'rectMarginTop', dispName: 'Top Margin', type: 'float', min:0, defVal:0},
2008	{name: 'rectMarginLeft', dispName: 'Left Margin', type: 'float', min:0, defVal:0},
2009	{name: 'rectMarginBottom', dispName: 'Bottom Margin', type: 'float', min:0, defVal:0},
2010	{name: 'rectMarginRight', dispName: 'Right Margin', type: 'float', min:0, defVal:0}
2011];
2012
2013/**
2014* Function: paintVertexShape
2015*
2016* Paints the vertex shape.
2017*/
2018mxShapeMockupContainersMarginRect.prototype.paintVertexShape = function(c, x, y, w, h)
2019{
2020
2021	c.translate(x, y);
2022	this.background(c, x, y, w, h);
2023};
2024
2025mxShapeMockupContainersMarginRect.prototype.background = function(c, x, y, w, h, state)
2026{
2027	var margin = parseFloat(mxUtils.getValue(this.style, mxShapeMockupContainersMarginRect.prototype.cst.MARGIN, '0'));
2028	var marginTop = parseFloat(mxUtils.getValue(this.style, mxShapeMockupContainersMarginRect.prototype.cst.MARGIN_TOP, '0'));
2029	var marginLeft = parseFloat(mxUtils.getValue(this.style, mxShapeMockupContainersMarginRect.prototype.cst.MARGIN_LEFT, '0'));
2030	var marginBottom = parseFloat(mxUtils.getValue(this.style, mxShapeMockupContainersMarginRect.prototype.cst.MARGIN_BOTTOM, '0'));
2031	var marginRight = parseFloat(mxUtils.getValue(this.style, mxShapeMockupContainersMarginRect.prototype.cst.MARGIN_RIGHT, '0'));
2032
2033	var x1 = margin + marginLeft;
2034	var y1 = margin + marginTop;
2035	var w1 = w - marginRight - x1 - margin;
2036	var h1 = h - marginBottom - y1 - margin;
2037
2038	if (w1 >0 && h1 > 0)
2039	{
2040		c.begin();
2041		c.roundrect(x1, y1, w1, h1, 10, 10);
2042		c.fillAndStroke();
2043	}
2044};
2045
2046mxCellRenderer.registerShape(mxShapeMockupContainersMarginRect.prototype.cst.SHAPE_MARGIN_RECT, mxShapeMockupContainersMarginRect);
2047
2048//**********************************************************************************************************************************************************
2049//rect with margins (not rounded)
2050//**********************************************************************************************************************************************************
2051/**
2052* Extends mxShape.
2053*/
2054function mxShapeMockupContainersMarginRect2(bounds, fill, stroke, strokewidth)
2055{
2056	mxShape.call(this);
2057	this.bounds = bounds;
2058	this.fill = fill;
2059	this.stroke = stroke;
2060	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
2061};
2062
2063/**
2064* Extends mxShape.
2065*/
2066mxUtils.extend(mxShapeMockupContainersMarginRect2, mxShape);
2067
2068mxShapeMockupContainersMarginRect2.prototype.cst = {
2069		SHAPE_MARGIN_RECT : 'mxgraph.mockup.containers.marginRect2',
2070		MARGIN : 'rectMargin',
2071		MARGIN_TOP : 'rectMarginTop',
2072		MARGIN_LEFT : 'rectMarginLeft',
2073		MARGIN_BOTTOM : 'rectMarginBottom',
2074		MARGIN_RIGHT : 'rectMarginRight'
2075};
2076
2077mxShapeMockupContainersMarginRect2.prototype.customProperties = [
2078	{name: 'rectMargin', dispName: 'Global Margin', type: 'float', min:0, defVal:0},
2079	{name: 'rectMarginTop', dispName: 'Top Margin', type: 'float', min:0, defVal:0},
2080	{name: 'rectMarginLeft', dispName: 'Left Margin', type: 'float', min:0, defVal:0},
2081	{name: 'rectMarginBottom', dispName: 'Bottom Margin', type: 'float', min:0, defVal:0},
2082	{name: 'rectMarginRight', dispName: 'Right Margin', type: 'float', min:0, defVal:0}
2083];
2084
2085/**
2086* Function: paintVertexShape
2087*
2088* Paints the vertex shape.
2089*/
2090mxShapeMockupContainersMarginRect2.prototype.paintVertexShape = function(c, x, y, w, h)
2091{
2092
2093	c.translate(x, y);
2094	this.background(c, x, y, w, h);
2095};
2096
2097mxShapeMockupContainersMarginRect2.prototype.background = function(c, x, y, w, h, state)
2098{
2099	var margin = parseFloat(mxUtils.getValue(this.style, mxShapeMockupContainersMarginRect2.prototype.cst.MARGIN, '0'));
2100	var marginTop = parseFloat(mxUtils.getValue(this.style, mxShapeMockupContainersMarginRect2.prototype.cst.MARGIN_TOP, '0'));
2101	var marginLeft = parseFloat(mxUtils.getValue(this.style, mxShapeMockupContainersMarginRect2.prototype.cst.MARGIN_LEFT, '0'));
2102	var marginBottom = parseFloat(mxUtils.getValue(this.style, mxShapeMockupContainersMarginRect2.prototype.cst.MARGIN_BOTTOM, '0'));
2103	var marginRight = parseFloat(mxUtils.getValue(this.style, mxShapeMockupContainersMarginRect2.prototype.cst.MARGIN_RIGHT, '0'));
2104
2105	var x1 = margin + marginLeft;
2106	var y1 = margin + marginTop;
2107	var w1 = w - marginRight - x1 - margin;
2108	var h1 = h - marginBottom - y1 - margin;
2109
2110	if (w1 >0 && h1 > 0)
2111	{
2112		c.begin();
2113		c.rect(x1, y1, w1, h1);
2114		c.fillAndStroke();
2115	}
2116};
2117
2118mxCellRenderer.registerShape(mxShapeMockupContainersMarginRect2.prototype.cst.SHAPE_MARGIN_RECT, mxShapeMockupContainersMarginRect2);
2119
2120