1/**
2 * $Id: mxMockupForms.js,v 1.11 2013/05/24 05:21:33 mate Exp $
3 * Copyright (c) 2006-2010, JGraph Ltd
4 */
5
6//**********************************************************************************************************************************************************
7//Checkbox Group (LEGACY)
8//**********************************************************************************************************************************************************
9/**
10 * Extends mxShape.
11 */
12function mxShapeMockupCheckboxGroup(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};
20
21/**
22 * Extends mxShape.
23 */
24mxUtils.extend(mxShapeMockupCheckboxGroup, mxShape);
25
26mxShapeMockupCheckboxGroup.prototype.cst = {
27		MAIN_TEXT : 'mainText',
28		TEXT_SIZE : 'textSize',
29		TEXT_COLOR : 'textColor',
30		SELECTED : '+',				// must be 1 char
31		SHAPE_CHECKBOX_GROUP : 'mxgraph.mockup.forms.checkboxGroup'
32};
33
34/**
35 * Function: paintVertexShape
36 *
37 * Paints the vertex shape.
38 */
39mxShapeMockupCheckboxGroup.prototype.paintVertexShape = function(c, x, y, w, h)
40{
41	c.translate(x, y);
42
43	var fontColor = mxUtils.getValue(this.style, mxShapeMockupCheckboxGroup.prototype.cst.TEXT_COLOR, '#666666,#008cff').toString().split(',');
44	var fontSize = mxUtils.getValue(this.style, mxShapeMockupCheckboxGroup.prototype.cst.TEXT_SIZE, '17').toString();
45	var optionText = mxUtils.getValue(this.style, mxShapeMockupCheckboxGroup.prototype.cst.MAIN_TEXT, 'Option 1').toString().split(',');
46	var optionNum = optionText.length;
47	var buttonSize = 15;
48	var lineH = Math.max(fontSize * 1.5, buttonSize);
49	var maxTextWidth = 0;
50	var selected = -1;
51	var labelOffset = 2.5;
52	var minH = optionNum * lineH;
53	var trueH = Math.max(h, minH);
54
55	//get min width and selected option
56	for (var i = 0; i < optionNum; i++)
57	{
58		var currText = optionText[i];
59
60		if(currText.charAt(0) === mxShapeMockupCheckboxGroup.prototype.cst.SELECTED)
61		{
62			currText = optionText[i].substring(1);
63			selected = i;
64		}
65
66		var currWidth = mxUtils.getSizeForString(currText, fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
67
68		if (currWidth > maxTextWidth)
69		{
70			maxTextWidth = currWidth;
71		}
72	}
73
74	var minW = 2 * labelOffset + maxTextWidth + 2 * buttonSize;
75	var trueW = Math.max(w, minW);
76
77	//draw the background
78	c.rect(0, 0, trueW, trueH);
79	c.fillAndStroke();
80	c.setShadow(false);
81
82	c.setFontSize(fontSize);
83
84	for (var i = 0; i < optionNum; i++)
85	{
86		var currHeight = (i * lineH + lineH * 0.5) * trueH / minH;
87
88		var currText = optionText[i];
89
90		if(currText.charAt(0) === mxShapeMockupCheckboxGroup.prototype.cst.SELECTED)
91		{
92			c.setFontColor(fontColor[1]);
93			currText = optionText[i].substring(1);
94			selected = i;
95		}
96		else
97		{
98			c.setFontColor(fontColor[0]);
99		}
100
101		c.text(buttonSize * 2 + labelOffset, currHeight, 0, 0, currText, mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
102
103		var iconX = buttonSize * 0.5;
104		var iconY = currHeight - buttonSize * 0.5;
105		c.setFillColor('#dddddd');
106		c.setStrokeColor('#999999');
107
108		if (selected === i)
109		{
110			c.setGradient('#aaaaaa', '#666666', iconX, iconY, buttonSize, buttonSize, mxConstants.DIRECTION_SOUTH, 1, 1);
111			c.rect(iconX, iconY, buttonSize, buttonSize);
112			c.fillAndStroke();
113			c.setStrokeColor('#333333');
114			c.begin();
115			c.moveTo(iconX + buttonSize * 0.25, iconY + buttonSize * 0.5);
116			c.lineTo(iconX + buttonSize * 0.5, iconY + buttonSize * 0.75);
117			c.lineTo(iconX + buttonSize * 0.75, iconY + buttonSize * 0.25);
118			c.stroke();
119		}
120		else
121		{
122			c.setGradient('#eeeeee', '#cccccc', iconX, iconY, buttonSize, buttonSize, mxConstants.DIRECTION_SOUTH, 1, 1);
123			c.rect(iconX, iconY, buttonSize, buttonSize);
124			c.fillAndStroke();
125		}
126
127		selected = -1;
128	}
129};
130
131mxCellRenderer.registerShape(mxShapeMockupCheckboxGroup.prototype.cst.SHAPE_CHECKBOX_GROUP, mxShapeMockupCheckboxGroup);
132
133//**********************************************************************************************************************************************************
134//Radio Button Group
135//**********************************************************************************************************************************************************
136/**
137 * Extends mxShape.
138 */
139function mxShapeMockupRadioGroup(bounds, fill, stroke, strokewidth)
140{
141	mxShape.call(this);
142	this.bounds = bounds;
143	this.fill = fill;
144	this.stroke = stroke;
145	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
146};
147
148/**
149 * Extends mxShape.
150 */
151mxUtils.extend(mxShapeMockupRadioGroup, mxShape);
152
153mxShapeMockupRadioGroup.prototype.cst = {
154		MAIN_TEXT : 'mainText',
155		TEXT_SIZE : 'textSize',
156		TEXT_COLOR : 'textColor',
157		SELECTED : '+',				// must be 1 char
158		SHAPE_RADIO_GROUP : 'mxgraph.mockup.forms.radioGroup'
159};
160
161/**
162 * Function: paintVertexShape
163 *
164 * Paints the vertex shape.
165 */
166mxShapeMockupRadioGroup.prototype.paintVertexShape = function(c, x, y, w, h)
167{
168	c.translate(x, y);
169
170	var fontColor = mxUtils.getValue(this.style, mxShapeMockupRadioGroup.prototype.cst.TEXT_COLOR, '#666666,#008cff').toString().split(',');
171	var fontSize = mxUtils.getValue(this.style, mxShapeMockupRadioGroup.prototype.cst.TEXT_SIZE, '17').toString();
172	var optionText = mxUtils.getValue(this.style, mxShapeMockupRadioGroup.prototype.cst.MAIN_TEXT, 'Option 1').toString().split(',');
173	var optionNum = optionText.length;
174	var buttonSize = 15;
175	var lineH = Math.max(fontSize * 1.5, buttonSize);
176	var maxTextWidth = 0;
177	var selected = -1;
178	var labelOffset = 2.5;
179	var minH = optionNum * lineH;
180	var trueH = Math.max(h, minH);
181
182	//get min width and selected option
183	for (var i = 0; i < optionNum; i++)
184	{
185		var currText = optionText[i];
186
187		if(currText.charAt(0) === mxShapeMockupRadioGroup.prototype.cst.SELECTED)
188		{
189			currText = optionText[i].substring(1);
190			selected = i;
191		}
192
193		var currWidth = mxUtils.getSizeForString(currText, fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
194
195		if (currWidth > maxTextWidth)
196		{
197			maxTextWidth = currWidth;
198		}
199	}
200
201	var minW = 2 * labelOffset + maxTextWidth + 2 * buttonSize;
202	var trueW = Math.max(w, minW);
203
204	//draw the background
205	c.rect(0, 0, trueW, trueH);
206	c.fillAndStroke();
207	c.setShadow(false);
208
209	c.setFontSize(fontSize);
210
211	for (var i = 0; i < optionNum; i++)
212	{
213		var currHeight = (i * lineH + lineH * 0.5) * trueH / minH;
214
215		var currText = optionText[i];
216
217		if(currText.charAt(0) === mxShapeMockupRadioGroup.prototype.cst.SELECTED)
218		{
219			c.setFontColor(fontColor[1]);
220			currText = optionText[i].substring(1);
221			selected = i;
222		}
223		else
224		{
225			c.setFontColor(fontColor[0]);
226		}
227
228		c.text(buttonSize * 2 + labelOffset, currHeight, 0, 0, currText, mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
229
230		var iconX = buttonSize * 0.5;
231		var iconY = currHeight - buttonSize * 0.5;
232		c.setStrokeColor('#999999');
233
234		if (selected === i)
235		{
236			c.setGradient('#aaaaaa', '#666666', iconX, iconY, buttonSize, buttonSize, mxConstants.DIRECTION_SOUTH, 1, 1);
237			c.ellipse(iconX, iconY, buttonSize, buttonSize);
238			c.fillAndStroke();
239			c.setFillColor('#333333');
240			c.setStrokeColor('#333333');
241			c.ellipse(iconX + buttonSize * 0.25, iconY + buttonSize * 0.25, buttonSize * 0.5, buttonSize * 0.5);
242			c.fillAndStroke();
243		}
244		else
245		{
246			c.setGradient('#eeeeee', '#cccccc', iconX, iconY, buttonSize, buttonSize, mxConstants.DIRECTION_SOUTH, 1, 1);
247			c.ellipse(iconX, iconY, buttonSize, buttonSize);
248			c.fillAndStroke();
249		}
250	}
251};
252
253mxCellRenderer.registerShape(mxShapeMockupRadioGroup.prototype.cst.SHAPE_RADIO_GROUP, mxShapeMockupRadioGroup);
254
255//**********************************************************************************************************************************************************
256//Color Picker
257//**********************************************************************************************************************************************************
258/**
259 * Extends mxShape.
260 */
261function mxShapeMockupColorPicker(bounds, fill, stroke, strokewidth)
262{
263	mxShape.call(this);
264	this.bounds = bounds;
265	this.fill = fill;
266	this.stroke = stroke;
267	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
268};
269
270/**
271 * Extends mxShape.
272 */
273mxUtils.extend(mxShapeMockupColorPicker, mxShape);
274
275mxShapeMockupColorPicker.prototype.cst = {
276		COLOR : 'chosenColor',
277		SHAPE_COLOR_PICKER : 'mxgraph.mockup.forms.colorPicker'
278};
279
280mxShapeMockupColorPicker.prototype.customProperties = [
281	{name: 'chosenColor', dispName: 'Current Color', type: 'color'}
282];
283
284/**
285 * Function: paintVertexShape
286 *
287 * Paints the vertex shape.
288 */
289mxShapeMockupColorPicker.prototype.paintVertexShape = function(c, x, y, w, h)
290{
291	var chosenColor = mxUtils.getValue(this.style, mxShapeMockupColorPicker.prototype.cst.COLOR, '#aaddff');
292
293	c.translate(x, y);
294
295	c.setStrokeColor('#999999');
296	c.roundrect(0, 0, w, h, w * 0.05, h * 0.05);
297	c.fillAndStroke();
298	c.setShadow(false);
299
300	c.setFillColor(chosenColor);
301	c.rect(w * 0.1, h * 0.1, w * 0.8, h * 0.8);
302	c.fill();
303
304	c.setFillColor('#ffffff');
305	c.begin();
306	c.moveTo(w * 0.75, h * 0.75);
307	c.lineTo(w * 0.75, h);
308	c.lineTo(w * 0.95, h);
309	c.arcTo(w * 0.05, h * 0.05, 0, 0, 0, w, h * 0.95);
310	c.lineTo(w, h * 0.75);
311	c.close();
312	c.fill();
313
314	c.setFillColor('#999999');
315	c.begin();
316	c.moveTo(w * 0.77, h * 0.77);
317	c.lineTo(w * 0.875, h * 0.98);
318	c.lineTo(w * 0.98, h * 0.77);
319	c.close();
320	c.fill();
321
322	c.roundrect(0, 0, w, h, w * 0.05, h * 0.05);
323	c.stroke();
324};
325
326mxCellRenderer.registerShape(mxShapeMockupColorPicker.prototype.cst.SHAPE_COLOR_PICKER, mxShapeMockupColorPicker);
327
328//**********************************************************************************************************************************************************
329//Combo box
330//**********************************************************************************************************************************************************
331/**
332 * Extends mxShape.
333 */
334function mxShapeMockupComboBox(bounds, fill, stroke, strokewidth)
335{
336	mxShape.call(this);
337	this.bounds = bounds;
338	this.fill = fill;
339	this.stroke = stroke;
340	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
341};
342
343/**
344 * Extends mxShape.
345 */
346mxUtils.extend(mxShapeMockupComboBox, mxShape);
347
348mxShapeMockupComboBox.prototype.cst = {
349		MAIN_TEXT : 'mainText',
350		FILL_COLOR2 : 'fillColor2',
351		TEXT_COLOR : 'textColor',
352		TEXT_SIZE : 'textSize',
353		SHAPE_COMBO_BOX : 'mxgraph.mockup.forms.comboBox'
354};
355
356mxShapeMockupComboBox.prototype.customProperties = [
357	{name: 'fillColor2', dispName: 'Fill2 Color', type: 'color'}
358];
359
360/**
361 * Function: paintVertexShape
362 *
363 * Paints the vertex shape.
364 */
365mxShapeMockupComboBox.prototype.paintVertexShape = function(c, x, y, w, h)
366{
367	c.translate(x, y);
368	this.background(c, x, y, w, h);
369	c.setShadow(false);
370	this.foreground(c, x, y, w, h);
371	this.mainText(c, x, y, w, h);
372};
373
374mxShapeMockupComboBox.prototype.background = function(c, x, y, w, h)
375{
376	c.setFillColor('#ffffff');
377	c.roundrect(0, 0, w, h, 5, 5);
378	c.fillAndStroke();
379};
380
381mxShapeMockupComboBox.prototype.foreground = function(c, x, y, w, h)
382{
383	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '').toString();
384	var fillColor2 = mxUtils.getValue(this.style, mxShapeMockupComboBox.prototype.cst.FILL_COLOR2, '').toString();
385	c.setGradient(fillColor, fillColor2, w - 30, 0, 30, h, mxConstants.DIRECTION_SOUTH, 1, 1);
386	c.begin();
387	c.moveTo(w - 30, 0);
388	c.lineTo(w - 5, 0);
389	c.arcTo(5, 5, 0, 0, 1, w, 5);
390	c.lineTo(w, h - 5);
391	c.arcTo(5, 5, 0, 0, 1, w - 5, h);
392	c.lineTo(w - 30, h);
393	c.close();
394	c.fillAndStroke();
395
396	c.setFillColor('#ffffff');
397	c.begin();
398	c.moveTo(w - 22, h * 0.5 - 5);
399	c.lineTo(w - 15, h * 0.5 + 5);
400	c.lineTo(w - 8, h * 0.5 - 5);
401	c.fill();
402};
403
404mxShapeMockupComboBox.prototype.mainText = function(c, x, y, w, h)
405{
406	var mainText = mxUtils.getValue(this.style, mxShapeMockupComboBox.prototype.cst.MAIN_TEXT, 'Main Text');
407	var fontColor = mxUtils.getValue(this.style, mxShapeMockupComboBox.prototype.cst.TEXT_COLOR, '#666666').toString();
408	var fontSize = mxUtils.getValue(this.style, mxShapeMockupComboBox.prototype.cst.TEXT_SIZE, '17').toString();
409
410	c.begin();
411	c.setFontSize(fontSize);
412	c.setFontColor(fontColor);
413	c.text(5, h * 0.5, 0, 0, mainText, mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
414};
415
416mxCellRenderer.registerShape(mxShapeMockupComboBox.prototype.cst.SHAPE_COMBO_BOX, mxShapeMockupComboBox);
417
418//**********************************************************************************************************************************************************
419//Spinner
420//**********************************************************************************************************************************************************
421/**
422 * Extends mxShape.
423 */
424function mxShapeMockupSpinner(bounds, fill, stroke, strokewidth)
425{
426	mxShape.call(this);
427	this.bounds = bounds;
428	this.fill = fill;
429	this.stroke = stroke;
430	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
431};
432
433/**
434 * Extends mxShape.
435 */
436mxUtils.extend(mxShapeMockupSpinner, mxShape);
437
438mxShapeMockupSpinner.prototype.cst = {
439		LAYOUT : 'spinLayout',
440		SPINNER_STYLE : 'spinStyle',
441		ADJ_STYLE : 'adjStyle',
442		LAYOUT_RIGHT : 'right',
443		LAYOUT_LEFT : 'left',
444		LAYOUT_TOP : 'top',
445		LAYOUT_BOTTOM : 'bottom',
446		LAYOUT_VERTICAL : 'vertical',
447		LAYOUT_HORIZONTAL : 'horizontal',
448		SPINNER_MERGED : 'merged',
449		SPINNER_NORMAL : 'normal',
450		ADJ_TRIANGLE : 'triangle',
451		ADJ_PLUSMINUS : 'plusMinus',
452		ADJ_ARROW : 'arrow',
453
454		MAIN_TEXT : 'mainText',
455		TEXT_COLOR : 'textColor',
456		TEXT_SIZE : 'textSize',
457		SHAPE_SPINNER : 'mxgraph.mockup.forms.spinner'
458};
459
460mxShapeMockupSpinner.prototype.customProperties = [
461	{name: 'spinLayout', dispName: 'Layout', type: 'enum',
462		enumList: [{val: 'right', dispName: 'Right'}, {val: 'left', dispName: 'Left'}, {val: 'top', dispName: 'Top'}, {val: 'bottom', dispName: 'Bottom'}, {val: 'vertical', dispName: 'Vertical'}, {val: 'horizontal', dispName: 'Horizontal'}]
463	},
464	{name: 'spinStyle', dispName: 'Spinner Style', type: 'enum',
465		enumList: [{val: 'merged', dispName: 'Merged'}, {val: 'normal', dispName: 'Normal'}]
466	},
467	{name: 'adjStyle', dispName: 'Button Style', type: 'enum',
468		enumList: [{val: 'triangle', dispName: 'Triangle'}, {val: 'plusMinus', dispName: '+/-'}, {val: 'arrow', dispName: 'Arrow'}]
469	}
470];
471
472/**
473 * Function: paintVertexShape
474 *
475 * Paints the vertex shape.
476 */
477mxShapeMockupSpinner.prototype.paintVertexShape = function(c, x, y, w, h)
478{
479	var spinnerLayout = mxUtils.getValue(this.style, mxShapeMockupSpinner.prototype.cst.LAYOUT, mxShapeMockupSpinner.prototype.cst.LAYOUT_RIGHT);
480	c.translate(x, y);
481	this.background(c, w, h);
482	c.setShadow(false);
483	this.foreground(c, w, h, spinnerLayout);
484	this.mainText(c, w, h, spinnerLayout);
485};
486
487mxShapeMockupSpinner.prototype.background = function(c, w, h)
488{
489	c.setFillColor('#ffffff');
490	c.roundrect(0, 0, w, h, 10, 10);
491	c.fillAndStroke();
492};
493
494mxShapeMockupSpinner.prototype.foreground = function(c, w, h, spinnerLayout)
495{
496
497	var spinnerStyle = mxUtils.getValue(this.style, mxShapeMockupSpinner.prototype.cst.SPINNER_STYLE, mxShapeMockupSpinner.prototype.cst.SPINNER_NORMAL);
498	var adjStyle = mxUtils.getValue(this.style, mxShapeMockupSpinner.prototype.cst.ADJ_STYLE, mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE);
499	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
500
501	c.setFillColor(fillColor);
502
503	if (spinnerStyle === mxShapeMockupSpinner.prototype.cst.SPINNER_NORMAL)
504	{
505		if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_RIGHT)
506		{
507			c.begin();
508			c.moveTo(w - 20, 0);
509			c.lineTo(w - 20, h);
510			c.moveTo(w - 20, h * 0.5);
511			c.lineTo(w, h * 0.5);
512			c.stroke();
513		}
514		else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_LEFT)
515		{
516			c.begin();
517			c.moveTo(20, 0);
518			c.lineTo(20, h);
519			c.moveTo(20, h * 0.5);
520			c.lineTo(0, h * 0.5);
521			c.stroke();
522		}
523		else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_TOP)
524		{
525			c.begin();
526			c.moveTo(0, 15);
527			c.lineTo(w, 15);
528			c.moveTo(w * 0.5, 15);
529			c.lineTo(w * 0.5, 0);
530			c.stroke();
531		}
532		else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_BOTTOM)
533		{
534			c.begin();
535			c.moveTo(0, h - 15);
536			c.lineTo(w, h - 15);
537			c.moveTo(w * 0.5, h - 15);
538			c.lineTo(w * 0.5, h);
539			c.stroke();
540		}
541		else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_VERTICAL)
542		{
543			c.begin();
544			c.moveTo(0, 15);
545			c.lineTo(w, 15);
546			c.moveTo(0, h - 15);
547			c.lineTo(w, h - 15);
548			c.stroke();
549		}
550		else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_HORIZONTAL)
551		{
552			c.begin();
553			c.moveTo(20, 0);
554			c.lineTo(20, h);
555			c.moveTo(w - 20, 0);
556			c.lineTo(w - 20, h);
557			c.stroke();
558		}
559	}
560
561	c.setStrokeColor(fillColor);
562
563	if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_RIGHT)
564	{
565		if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE)
566		{
567			c.begin();
568			c.moveTo(w - 14, h * 0.25 + 4.5);
569			c.lineTo(w - 10, h * 0.25 - 2.5);
570			c.lineTo(w - 6, h * 0.25 + 4.5);
571			c.close();
572			c.fillAndStroke();
573		}
574		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_PLUSMINUS)
575		{
576			c.begin();
577			c.moveTo(w - 10, h * 0.25 - 4);
578			c.lineTo(w - 10, h * 0.25 + 4);
579			c.moveTo(w - 14, h * 0.25);
580			c.lineTo(w - 6, h * 0.25);
581			c.stroke();
582		}
583		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_ARROW)
584		{
585			c.begin();
586			c.moveTo(w - 14, h * 0.25 + 1.5);
587			c.lineTo(w - 10, h * 0.25 - 2.5);
588			c.lineTo(w - 6, h * 0.25 + 1.5);
589			c.close();
590			c.moveTo(w - 10, h * 0.25 + 4.5);
591			c.lineTo(w - 10, h * 0.25 - 2.5);
592			c.fillAndStroke();
593		}
594	}
595	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_LEFT)
596	{
597		if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE)
598		{
599			c.begin();
600			c.moveTo(14, h * 0.25 + 4.5);
601			c.lineTo(10, h * 0.25 - 2.5);
602			c.lineTo(6, h * 0.25 + 4.5);
603			c.close();
604			c.fillAndStroke();
605		}
606		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_PLUSMINUS)
607		{
608			c.begin();
609			c.moveTo(10, h * 0.25 - 4);
610			c.lineTo(10, h * 0.25 + 4);
611			c.moveTo(14, h * 0.25);
612			c.lineTo(6, h * 0.25);
613			c.stroke();
614		}
615		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_ARROW)
616		{
617			c.begin();
618			c.moveTo(14, h * 0.25 + 1.5);
619			c.lineTo(10, h * 0.25 - 2.5);
620			c.lineTo(6, h * 0.25 + 1.5);
621			c.close();
622			c.moveTo(10, h * 0.25 + 4.5);
623			c.lineTo(10, h * 0.25 - 2.5);
624			c.fillAndStroke();
625		}
626	}
627	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_TOP)
628	{
629		if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE)
630		{
631			c.begin();
632			c.moveTo(w * 0.75 + 4, 12);
633			c.lineTo(w * 0.75, 5);
634			c.lineTo(w * 0.75 - 4, 12);
635			c.close();
636			c.fillAndStroke();
637		}
638		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_PLUSMINUS)
639		{
640			c.begin();
641			c.moveTo(w * 0.75, 3.5);
642			c.lineTo(w * 0.75, 11.5);
643			c.moveTo(w * 0.75 + 4, 7.5);
644			c.lineTo(w * 0.75 - 4, 7.5);
645			c.stroke();
646		}
647		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_ARROW)
648		{
649			c.begin();
650			c.moveTo(w * 0.75 + 4, 9);
651			c.lineTo(w * 0.75, 5);
652			c.lineTo(w * 0.75 - 4, 9);
653			c.close();
654			c.moveTo(w * 0.75, 12);
655			c.lineTo(w * 0.75, 5);
656			c.fillAndStroke();
657		}
658	}
659	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_BOTTOM)
660	{
661		if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE)
662		{
663			c.begin();
664			c.moveTo(w * 0.75 + 4, h - 5);
665			c.lineTo(w * 0.75, h - 12);
666			c.lineTo(w * 0.75 - 4, h - 5);
667			c.close();
668			c.fillAndStroke();
669		}
670		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_PLUSMINUS)
671		{
672			c.begin();
673			c.moveTo(w * 0.75, h - 3.5);
674			c.lineTo(w * 0.75, h - 11.5);
675			c.moveTo(w * 0.75 + 4, h - 7.5);
676			c.lineTo(w * 0.75 - 4, h - 7.5);
677			c.stroke();
678		}
679		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_ARROW)
680		{
681			c.begin();
682			c.moveTo(w * 0.75 + 4, h - 6);
683			c.lineTo(w * 0.75, h - 10);
684			c.lineTo(w * 0.75 - 4, h - 6);
685			c.close();
686			c.moveTo(w * 0.75, h - 3);
687			c.lineTo(w * 0.75, h - 10);
688			c.fillAndStroke();
689		}
690	}
691	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_VERTICAL)
692	{
693		if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE)
694		{
695			c.begin();
696			c.moveTo(w * 0.5 + 4, 12);
697			c.lineTo(w * 0.5, 5);
698			c.lineTo(w * 0.5 - 4, 12);
699			c.close();
700			c.fillAndStroke();
701		}
702		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_PLUSMINUS)
703		{
704			c.begin();
705			c.moveTo(w * 0.5, 3.5);
706			c.lineTo(w * 0.5, 11.5);
707			c.moveTo(w * 0.5 + 4, 7.5);
708			c.lineTo(w * 0.5 - 4, 7.5);
709			c.stroke();
710		}
711		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_ARROW)
712		{
713			c.begin();
714			c.moveTo(w * 0.5 + 4, 9);
715			c.lineTo(w * 0.5, 5);
716			c.lineTo(w * 0.5 - 4, 9);
717			c.close();
718			c.moveTo(w * 0.5, 12);
719			c.lineTo(w * 0.5, 5);
720			c.fillAndStroke();
721		}
722	}
723	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_HORIZONTAL)
724	{
725		if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE)
726		{
727			c.begin();
728			c.moveTo(w - 6, h * 0.5 + 4.5);
729			c.lineTo(w - 10, h * 0.5 - 2.5);
730			c.lineTo(w - 14, h * 0.5 + 4.5);
731			c.close();
732			c.fillAndStroke();
733		}
734		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_PLUSMINUS)
735		{
736			c.begin();
737			c.moveTo(w - 10, h * 0.5 - 4);
738			c.lineTo(w - 10, h * 0.5 + 4);
739			c.moveTo(w - 14, h * 0.5);
740			c.lineTo(w - 6, h * 0.5);
741			c.stroke();
742		}
743		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_ARROW)
744		{
745			c.begin();
746			c.moveTo(w - 14, h * 0.5 + 1.5);
747			c.lineTo(w - 10, h * 0.5 - 2.5);
748			c.lineTo(w - 6, h * 0.5 + 1.5);
749			c.close();
750			c.moveTo(w - 10, h * 0.5 + 4.5);
751			c.lineTo(w - 10, h * 0.5 - 2.5);
752			c.fillAndStroke();
753		}
754	}
755
756	if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_RIGHT)
757	{
758		if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE)
759		{
760			c.begin();
761			c.moveTo(w - 14, h * 0.75 - 4.5);
762			c.lineTo(w - 10, h * 0.75 + 2.5);
763			c.lineTo(w - 6, h * 0.75 - 4.5);
764			c.close();
765			c.fillAndStroke();
766		}
767		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_PLUSMINUS)
768		{
769			c.begin();
770			c.moveTo(w - 14, h * 0.75);
771			c.lineTo(w - 6, h * 0.75);
772			c.stroke();
773		}
774		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_ARROW)
775		{
776			c.begin();
777			c.moveTo(w - 14, h * 0.75 - 1.5);
778			c.lineTo(w - 10, h * 0.75 + 2.5);
779			c.lineTo(w - 6, h * 0.75 - 1.5);
780			c.close();
781			c.moveTo(w - 10, h * 0.75 - 4.5);
782			c.lineTo(w - 10, h * 0.75 + 2.5);
783			c.fillAndStroke();
784		}
785	}
786	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_LEFT)
787	{
788		if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE)
789		{
790			c.begin();
791			c.moveTo(14, h * 0.75 - 4.5);
792			c.lineTo(10, h * 0.75 + 2.5);
793			c.lineTo(6, h * 0.75 - 4.5);
794			c.close();
795			c.fillAndStroke();
796		}
797		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_PLUSMINUS)
798		{
799			c.begin();
800			c.moveTo(14, h * 0.75);
801			c.lineTo(6, h * 0.75);
802			c.stroke();
803		}
804		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_ARROW)
805		{
806			c.begin();
807			c.moveTo(14, h * 0.75 - 1.5);
808			c.lineTo(10, h * 0.75 + 2.5);
809			c.lineTo(6, h * 0.75 - 1.5);
810			c.close();
811			c.moveTo(10, h * 0.75 - 4.5);
812			c.lineTo(10, h * 0.75 + 2.5);
813			c.fillAndStroke();
814		}
815	}
816	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_TOP)
817	{
818		if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE)
819		{
820			c.begin();
821			c.moveTo(w * 0.25 + 4, 5);
822			c.lineTo(w * 0.25, 12);
823			c.lineTo(w * 0.25 - 4, 5);
824			c.close();
825			c.fillAndStroke();
826		}
827		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_PLUSMINUS)
828		{
829			c.begin();
830			c.moveTo(w * 0.25 + 4, 7.5);
831			c.lineTo(w * 0.25 - 4, 7.5);
832			c.stroke();
833		}
834		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_ARROW)
835		{
836			c.begin();
837			c.moveTo(w * 0.25 + 4, 6);
838			c.lineTo(w * 0.25, 10);
839			c.lineTo(w * 0.25 - 4, 6);
840			c.close();
841			c.moveTo(w * 0.25, 3);
842			c.lineTo(w * 0.25, 10);
843			c.fillAndStroke();
844		}
845	}
846	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_BOTTOM)
847	{
848		if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE)
849		{
850			c.begin();
851			c.moveTo(w * 0.25 + 4, h - 12);
852			c.lineTo(w * 0.25, h - 5);
853			c.lineTo(w * 0.25 - 4, h - 12);
854			c.close();
855			c.fillAndStroke();
856		}
857		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_PLUSMINUS)
858		{
859			c.begin();
860			c.moveTo(w * 0.25 + 4, h - 7.5);
861			c.lineTo(w * 0.25 - 4, h - 7.5);
862			c.stroke();
863		}
864		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_ARROW)
865		{
866			c.begin();
867			c.moveTo(w * 0.25 + 4, h - 9);
868			c.lineTo(w * 0.25, h - 5);
869			c.lineTo(w * 0.25 - 4, h - 9);
870			c.close();
871			c.moveTo(w * 0.25, h - 12);
872			c.lineTo(w * 0.25, h - 5);
873			c.fillAndStroke();
874		}
875	}
876	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_VERTICAL)
877	{
878		if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE)
879		{
880			c.begin();
881			c.moveTo(w * 0.5 + 4, h - 12);
882			c.lineTo(w * 0.5, h - 5);
883			c.lineTo(w * 0.5 - 4, h - 12);
884			c.close();
885			c.fillAndStroke();
886		}
887		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_PLUSMINUS)
888		{
889			c.begin();
890			c.moveTo(w * 0.5 + 4, h - 7.5);
891			c.lineTo(w * 0.5 - 4, h - 7.5);
892			c.stroke();
893		}
894		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_ARROW)
895		{
896			c.begin();
897			c.moveTo(w * 0.5 + 4, h - 9);
898			c.lineTo(w * 0.5, h - 5);
899			c.lineTo(w * 0.5 - 4, h - 9);
900			c.close();
901			c.moveTo(w * 0.5, h - 12);
902			c.lineTo(w * 0.5, h - 5);
903			c.fillAndStroke();
904		}
905	}
906	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_HORIZONTAL)
907	{
908		if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_TRIANGLE)
909		{
910			c.begin();
911			c.moveTo(6, h * 0.5 - 4.5);
912			c.lineTo(10, h * 0.5 + 2.5);
913			c.lineTo(14, h * 0.5 - 4.5);
914			c.close();
915			c.fillAndStroke();
916		}
917		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_PLUSMINUS)
918		{
919			c.begin();
920			c.moveTo(14, h * 0.5);
921			c.lineTo(6, h * 0.5);
922			c.stroke();
923		}
924		else if(adjStyle === mxShapeMockupSpinner.prototype.cst.ADJ_ARROW)
925		{
926			c.begin();
927			c.moveTo(14, h * 0.5 - 1.5);
928			c.lineTo(10, h * 0.5 + 2.5);
929			c.lineTo(6, h * 0.5 - 1.5);
930			c.close();
931			c.moveTo(10, h * 0.5 - 4.5);
932			c.lineTo(10, h * 0.5 + 2.5);
933			c.fillAndStroke();
934		}
935	}
936};
937
938mxShapeMockupSpinner.prototype.mainText = function(c, w, h, spinnerLayout)
939{
940	var spinnerText = mxUtils.getValue(this.style, mxShapeMockupSpinner.prototype.cst.MAIN_TEXT, '100').toString();
941	var fontSize = mxUtils.getValue(this.style, mxShapeMockupSpinner.prototype.cst.TEXT_SIZE, '17');
942	var fontColor = mxUtils.getValue(this.style, mxShapeMockupSpinner.prototype.cst.TEXT_COLOR, '#666666');
943	c.setFontSize(fontSize);
944	c.setFontColor(fontColor);
945
946	if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_RIGHT)
947	{
948		c.text((w - 20) * 0.5, h * 0.5, 0, 0, spinnerText, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
949	}
950	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_LEFT)
951	{
952		c.text((w + 20) * 0.5, h * 0.5, 0, 0, spinnerText, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
953	}
954	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_TOP)
955	{
956		c.text(w * 0.5, (h + 15) * 0.5, 0, 0, spinnerText, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
957	}
958	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_BOTTOM)
959	{
960		c.text(w * 0.5, (h - 15) * 0.5, 0, 0, spinnerText, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
961	}
962	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_VERTICAL)
963	{
964		c.text(w * 0.5, h * 0.5, 0, 0, spinnerText, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
965	}
966	else if (spinnerLayout === mxShapeMockupSpinner.prototype.cst.LAYOUT_HORIZONTAL)
967	{
968		c.text(w * 0.5, h * 0.5, 0, 0, spinnerText, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
969	}
970};
971
972mxCellRenderer.registerShape(mxShapeMockupSpinner.prototype.cst.SHAPE_SPINNER, mxShapeMockupSpinner);
973
974//**********************************************************************************************************************************************************
975//Menu Bar (LEGACY)
976//**********************************************************************************************************************************************************
977/**
978 * Extends mxShape.
979 */
980function mxShapeMockupMenuBar(bounds, fill, stroke, strokewidth)
981{
982	mxShape.call(this);
983	this.bounds = bounds;
984	this.fill = fill;
985	this.stroke = stroke;
986	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
987};
988
989/**
990 * Extends mxShape.
991 */
992mxUtils.extend(mxShapeMockupMenuBar, mxShape);
993
994mxShapeMockupMenuBar.prototype.cst = {
995		MAIN_TEXT : 'mainText',
996		SHAPE_MENU_BAR : 'mxgraph.mockup.forms.menuBar',
997		TEXT_COLOR : 'textColor',
998		TEXT_COLOR2 : 'textColor2',
999		STROKE_COLOR2 : 'strokeColor2',
1000		FILL_COLOR2 : 'fillColor2',
1001		SELECTED : '+',			//must be 1 char
1002		TEXT_SIZE : 'textSize'
1003};
1004
1005/**
1006 * Function: paintVertexShape
1007 *
1008 * Paints the vertex shape.
1009 */
1010mxShapeMockupMenuBar.prototype.paintVertexShape = function(c, x, y, w, h)
1011{
1012	var textStrings = mxUtils.getValue(this.style, mxShapeMockupMenuBar.prototype.cst.MAIN_TEXT, '+Menu 1, Menu 2, Menu 3').toString().split(',');
1013	var fontColor = mxUtils.getValue(this.style, mxShapeMockupMenuBar.prototype.cst.TEXT_COLOR, '#666666');
1014	var selectedFontColor = mxUtils.getValue(this.style, mxShapeMockupMenuBar.prototype.cst.TEXT_COLOR2, '#ffffff');
1015	var fontSize = mxUtils.getValue(this.style, mxShapeMockupMenuBar.prototype.cst.TEXT_SIZE, '17').toString();
1016	var frameColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#666666');
1017	var separatorColor = mxUtils.getValue(this.style, mxShapeMockupMenuBar.prototype.cst.STROKE_COLOR2, '#c4c4c4');
1018	var bgColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
1019	var selectedFillColor = mxUtils.getValue(this.style, mxShapeMockupMenuBar.prototype.cst.FILL_COLOR2, '#008cff');
1020	var buttonNum = textStrings.length;
1021	var buttonWidths = new Array(buttonNum);
1022	var buttonTotalWidth = 0;
1023	var selectedButton = -1;
1024	var rSize = 10; //rounding size
1025	var labelOffset = 5;
1026
1027	for (var i = 0; i < buttonNum; i++)
1028	{
1029		var buttonText = textStrings[i];
1030
1031		if(buttonText.charAt(0) === mxShapeMockupMenuBar.prototype.cst.SELECTED)
1032		{
1033			buttonText = textStrings[i].substring(1);
1034			selectedButton = i;
1035		}
1036
1037		buttonWidths[i] = mxUtils.getSizeForString(buttonText, fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
1038
1039		buttonTotalWidth += buttonWidths[i];
1040	}
1041
1042	var trueH = Math.max(h, fontSize * 1.5, 20);
1043	var minW = 2 * labelOffset * buttonNum + buttonTotalWidth;
1044	var trueW = Math.max(w, minW);
1045
1046	c.translate(x, y);
1047	this.background(c, trueW, trueH, rSize, buttonNum, buttonWidths, labelOffset, minW, frameColor, separatorColor, bgColor, selectedFillColor, selectedButton);
1048	c.setShadow(false);
1049
1050	var currWidth = 0;
1051
1052	for (var i = 0; i < buttonNum; i++)
1053	{
1054		if (i === selectedButton)
1055		{
1056			c.setFontColor(selectedFontColor);
1057		}
1058		else
1059		{
1060			c.setFontColor(fontColor);
1061		}
1062
1063		currWidth = currWidth + labelOffset;
1064		this.buttonText(c, currWidth, trueH, textStrings[i], buttonWidths[i], fontSize, minW, trueW);
1065		currWidth = currWidth + buttonWidths[i] + labelOffset;
1066	}
1067};
1068
1069mxShapeMockupMenuBar.prototype.background = function(c, w, h, rSize, buttonNum, buttonWidths, labelOffset, minW, frameColor, separatorColor, bgColor, selectedFillColor, selectedButton)
1070{
1071	//draw the frame
1072	c.setStrokeColor(frameColor);
1073	c.setFillColor(bgColor);
1074	c.rect(0, 0, w, h);
1075	c.fillAndStroke();
1076
1077	//draw the button separators
1078	c.setStrokeColor(separatorColor);
1079	c.begin();
1080
1081	for (var i = 1; i < buttonNum; i++)
1082	{
1083		if (i !== selectedButton && i !== (selectedButton + 1))
1084		{
1085			var currWidth = 0;
1086
1087			for (var j = 0; j < i; j++)
1088			{
1089				currWidth += buttonWidths[j] + 2 * labelOffset;
1090			}
1091
1092			currWidth = currWidth * w / minW;
1093			c.moveTo(currWidth, 0);
1094			c.lineTo(currWidth, h);
1095		}
1096	}
1097
1098	c.stroke();
1099
1100	//draw the selected menu
1101	if (selectedButton !== -1)
1102	{
1103		var buttonLeft = 0;
1104		c.setFillColor(selectedFillColor);
1105
1106		for (var i = 0; i < selectedButton; i++)
1107		{
1108			buttonLeft += buttonWidths[i] + 2 * labelOffset;
1109		}
1110
1111		buttonLeft = buttonLeft * w / minW;
1112		var buttonRight = (buttonWidths[selectedButton] + 2 * labelOffset) * w / minW;
1113		buttonRight += buttonLeft;
1114
1115		c.rect(buttonLeft, 0, buttonRight - buttonLeft, h);
1116		c.fill();
1117	}
1118
1119	//draw the frame again, for a nicer effect
1120	c.setStrokeColor(frameColor);
1121	c.setFillColor(bgColor);
1122	c.rect(0, 0, w, h);
1123	c.stroke();
1124};
1125
1126mxShapeMockupMenuBar.prototype.buttonText = function(c, w, h, textString, buttonWidth, fontSize, minW, trueW)
1127{
1128	if(textString.charAt(0) === mxShapeMockupMenuBar.prototype.cst.SELECTED)
1129	{
1130		textString = textString.substring(1);
1131	}
1132
1133	c.setFontSize(fontSize);
1134	c.text((w + buttonWidth * 0.5) * trueW / minW, h * 0.5, 0, 0, textString, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1135};
1136
1137mxCellRenderer.registerShape(mxShapeMockupMenuBar.prototype.cst.SHAPE_MENU_BAR, mxShapeMockupMenuBar);
1138
1139//**********************************************************************************************************************************************************
1140//Horizontal Slider
1141//**********************************************************************************************************************************************************
1142/**
1143 * Extends mxShape.
1144 */
1145function mxShapeMockupHorSlider(bounds, fill, stroke, strokewidth)
1146{
1147	mxShape.call(this);
1148	this.bounds = bounds;
1149	this.fill = fill;
1150	this.stroke = stroke;
1151	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1152};
1153
1154/**
1155 * Extends mxShape.
1156 */
1157mxUtils.extend(mxShapeMockupHorSlider, mxShape);
1158
1159mxShapeMockupHorSlider.prototype.cst = {
1160		STYLE : 'sliderStyle',
1161		SLIDER_BASIC : 'basic',
1162		SLIDER_FANCY : 'fancy',
1163		SLIDER_POS : 'sliderPos',
1164		HANDLE_TRIANGLE : 'triangle',
1165		HANDLE_CIRCLE : 'circle',
1166		HANDLE_HANDLE : 'handle',
1167		HANDLE_STYLE : 'handleStyle',
1168		FILL_COLOR2 : 'fillColor2',
1169		SHAPE_HOR_SLIDER : 'mxgraph.mockup.forms.horSlider'
1170};
1171
1172mxShapeMockupHorSlider.prototype.customProperties = [
1173	{name: 'sliderStyle', dispName: 'Slider Style', type: 'enum',
1174		enumList: [{val: 'basic', dispName: 'Basic'}, {val: 'fancy', dispName: 'Fancy'}]
1175	},
1176	{name: 'handleStyle', dispName: 'Handle Style', type: 'enum',
1177		enumList: [{val: 'triangle', dispName: 'Triangle'}, {val: 'circle', dispName: 'Circle'}, {val: 'handle', dispName: 'Handle'}]
1178	},
1179	{name: 'sliderPos', dispName: 'Handle Position', type: 'float'},
1180	{name: 'fillColor2', dispName: 'Fill2 Color', type: 'color'},
1181];
1182
1183/**
1184 * Function: paintVertexShape
1185 *
1186 * Paints the vertex shape.
1187 */
1188mxShapeMockupHorSlider.prototype.paintVertexShape = function(c, x, y, w, h)
1189{
1190	var sliderStyle = mxUtils.getValue(this.style, mxShapeMockupHorSlider.prototype.cst.STYLE, mxShapeMockupHorSlider.prototype.cst.SLIDER_BASIC);
1191	var rSize = 5;
1192
1193	c.translate(x, y);
1194	this.background(c, w, h, rSize, sliderStyle);
1195	c.setShadow(false);
1196	this.foreground(c, w, h, rSize, sliderStyle);
1197	this.sliderPos = 20;
1198};
1199
1200mxShapeMockupHorSlider.prototype.background = function(c, w, h, rSize, sliderStyle)
1201{
1202
1203	if (sliderStyle === mxShapeMockupHorSlider.prototype.cst.SLIDER_BASIC)
1204	{
1205		c.begin();
1206		c.moveTo(0, h * 0.5);
1207		c.lineTo(w, h * 0.5);
1208		c.stroke();
1209	}
1210	else if (sliderStyle === mxShapeMockupHorSlider.prototype.cst.SLIDER_FANCY)
1211	{
1212		c.roundrect(0, h * 0.5 - rSize, w, 2 * rSize, rSize, rSize);
1213		c.fillAndStroke();
1214	}
1215};
1216
1217mxShapeMockupHorSlider.prototype.foreground = function(c, w, h, rSize, sliderStyle)
1218{
1219	var sliderPos = mxUtils.getValue(this.style, mxShapeMockupHorSlider.prototype.cst.SLIDER_POS, '20');
1220	var handleStyle = mxUtils.getValue(this.style, mxShapeMockupHorSlider.prototype.cst.HANDLE_STYLE, mxShapeMockupHorSlider.prototype.cst.HANDLE_CIRCLE);
1221	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
1222	var fillColor2 = mxUtils.getValue(this.style, mxShapeMockupHorSlider.prototype.cst.FILL_COLOR2, '#ddeeff');
1223	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#999999');
1224	sliderPos = Math.min(100, sliderPos);
1225	sliderPos = Math.max(0, sliderPos);
1226
1227	if (sliderStyle === mxShapeMockupHorSlider.prototype.cst.SLIDER_BASIC)
1228	{
1229		c.setStrokeColor(fillColor2);
1230		var barCenterPos = w * sliderPos / 100;
1231		c.begin();
1232		c.moveTo(0, h * 0.5);
1233		c.lineTo(barCenterPos, h * 0.5);
1234		c.stroke();
1235		c.setStrokeColor(strokeColor);
1236	}
1237	else if (sliderStyle === mxShapeMockupHorSlider.prototype.cst.SLIDER_FANCY)
1238	{
1239		var barCenterPos = 10 + (w - 10) * sliderPos / 100;
1240		c.setFillColor(fillColor2);
1241		c.roundrect(0, h * 0.5 - rSize, barCenterPos, 2 * rSize, rSize, rSize);
1242		c.fillAndStroke();
1243		c.setFillColor(fillColor);
1244	}
1245
1246	var handleCenterPos = 5 + (w - 10) * sliderPos / 100;
1247
1248	if (handleStyle === mxShapeMockupHorSlider.prototype.cst.HANDLE_CIRCLE)
1249	{
1250		c.ellipse(handleCenterPos - 10, h * 0.5 - 10, 20, 20);
1251		c.fillAndStroke();
1252	}
1253	else if (handleStyle === mxShapeMockupHorSlider.prototype.cst.HANDLE_TRIANGLE)
1254	{
1255		c.begin();
1256		c.moveTo(handleCenterPos - 10, h * 0.5 + 10);
1257		c.lineTo(handleCenterPos, h * 0.5 - 10);
1258		c.lineTo(handleCenterPos + 10, h * 0.5 + 10);
1259		c.close();
1260		c.fillAndStroke();
1261	}
1262	else if (handleStyle === mxShapeMockupHorSlider.prototype.cst.HANDLE_HANDLE)
1263	{
1264		c.begin();
1265		c.moveTo(handleCenterPos - 7, h * 0.5 + 10);
1266		c.lineTo(handleCenterPos - 7, h * 0.5);
1267		c.lineTo(handleCenterPos, h * 0.5 - 10);
1268		c.lineTo(handleCenterPos + 7, h * 0.5);
1269		c.lineTo(handleCenterPos + 7, h * 0.5 + 10);
1270		c.close();
1271		c.fillAndStroke();
1272	}
1273};
1274
1275mxCellRenderer.registerShape(mxShapeMockupHorSlider.prototype.cst.SHAPE_HOR_SLIDER, mxShapeMockupHorSlider);
1276
1277Graph.handleFactory[mxShapeMockupHorSlider.prototype.cst.SHAPE_HOR_SLIDER] = function(state)
1278{
1279	var handles = [Graph.createHandle(state, ['sliderPos'], function(bounds)
1280			{
1281				var sliderPos = Math.max(0, Math.min(100, parseFloat(mxUtils.getValue(this.state.style, 'sliderPos', this.sliderPos))));
1282
1283				return new mxPoint(bounds.x + ((bounds.width - 10) * sliderPos / bounds.width) / 100 * bounds.width + 5, bounds.y + bounds.height / 2);
1284			}, function(bounds, pt)
1285			{
1286				this.state.style['sliderPos'] = Math.round(1000 * Math.max(0, Math.min(100, (pt.x - bounds.x) * 100 / bounds.width))) / 1000;
1287			})];
1288
1289	return handles;
1290}
1291
1292//**********************************************************************************************************************************************************
1293//List Box (LEGACY)
1294//**********************************************************************************************************************************************************
1295/**
1296 * Extends mxShape.
1297 */
1298function mxShapeMockupListBox(bounds, fill, stroke, strokewidth)
1299{
1300	mxShape.call(this);
1301	this.bounds = bounds;
1302	this.fill = fill;
1303	this.stroke = stroke;
1304	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1305};
1306
1307/**
1308 * Extends mxShape.
1309 */
1310mxUtils.extend(mxShapeMockupListBox, mxShape);
1311
1312mxShapeMockupListBox.prototype.cst = {
1313		MAIN_TEXT : 'mainText',
1314		SUB_TEXT : 'subText',
1315		BUTTON_TEXT : 'buttonText',
1316		TEXT_SIZE : 'textSize',
1317		TEXT_COLOR : 'textColor',
1318		STROKE_COLOR2 : 'strokeColor2',
1319		STROKE_COLOR3 : 'strokeColor3',
1320		SELECTED_COLOR : 'selectedColor',
1321		SELECTED : '+',			//must be 1 char
1322		SHAPE_LIST_BOX : 'mxgraph.mockup.forms.listBox'
1323};
1324
1325/**
1326 * Function: paintVertexShape
1327 *
1328 * Paints the vertex shape.
1329 */
1330mxShapeMockupListBox.prototype.paintVertexShape = function(c, x, y, w, h)
1331{
1332	var bgColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
1333	var frameColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#666666');
1334	var fontSize = mxUtils.getValue(this.style, mxShapeMockupListBox.prototype.cst.TEXT_SIZE, '17').toString();
1335
1336	var selectedButton = -1;
1337	var maxShapeWidth = w;
1338	var subText = mxUtils.getValue(this.style, mxShapeMockupListBox.prototype.cst.SUB_TEXT, 'Sub Text').toString().split(',');
1339
1340	for (var i = 0; i < subText.length; i++)
1341	{
1342		var itemText = subText[i];
1343
1344		if(itemText.charAt(0) === mxShapeMockupListBox.prototype.cst.SELECTED)
1345		{
1346			itemText = subText[i].substring(1);
1347			selectedButton = i;
1348		}
1349
1350		var currWidth = mxUtils.getSizeForString(itemText, fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
1351
1352		if (currWidth > maxShapeWidth)
1353		{
1354			maxShapeWidth = currWidth;
1355		}
1356	}
1357
1358
1359
1360	c.translate(x, y);
1361
1362	w = Math.min(w, maxShapeWidth);
1363	h = Math.max(h, 30 + subText.length * fontSize * 1.5);
1364
1365	this.background(c, w, h, bgColor, frameColor);
1366	c.setShadow(false);
1367	this.foreground(c, w, h, frameColor, selectedButton, subText, fontSize);
1368};
1369
1370mxShapeMockupListBox.prototype.background = function(c, w, h, bgColor, frameColor)
1371{
1372	c.setFillColor(bgColor);
1373	c.setStrokeColor(frameColor);
1374	c.rect(0, 0, w, h);
1375	c.fillAndStroke();
1376};
1377
1378mxShapeMockupListBox.prototype.foreground = function(c, w, h, frameColor, selectedButton, subText, fontSize)
1379{
1380	var strokeWidth = mxUtils.getValue(this.style, mxConstants.STYLE_STROKEWIDTH, '1');
1381	var selectedColor = mxUtils.getValue(this.style, mxShapeMockupListBox.prototype.cst.SELECTED_COLOR, '#ddeeff');
1382
1383	if(selectedButton !== -1)
1384	{
1385		c.setFillColor(selectedColor);
1386		c.rect(0, 30 + selectedButton * fontSize * 1.5, w, fontSize * 1.5);
1387		c.fill();
1388	}
1389
1390	c.begin();
1391	c.moveTo(0, 30);
1392	c.lineTo(w, 30);
1393	c.stroke();
1394
1395	//buttons
1396	var windowTitle = mxUtils.getValue(this.style, mxShapeMockupListBox.prototype.cst.MAIN_TEXT, 'Window Title').toString();
1397	var fontColor = mxUtils.getValue(this.style, mxShapeMockupListBox.prototype.cst.TEXT_COLOR, '#666666,#008cff').toString().split(',');
1398
1399	c.setFontColor(fontColor[1]);
1400	c.setFontSize(fontSize);
1401	c.text(10, 15, 0, 0, windowTitle, mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1402	c.setFontColor(fontColor[0]);
1403
1404	for (var i = 0; i < subText.length; i++)
1405	{
1406		var currText = subText[i];
1407
1408		if(currText.charAt(0) === mxShapeMockupListBox.prototype.cst.SELECTED)
1409		{
1410			currText = subText[i].substring(1);
1411		}
1412
1413		c.text(10, 30 + fontSize * (i * 1.5 + 0.75), 0, 0, currText, mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1414	}
1415
1416	c.rect(0, 0, w, h);
1417	c.stroke();
1418};
1419
1420mxCellRenderer.registerShape(mxShapeMockupListBox.prototype.cst.SHAPE_LIST_BOX, mxShapeMockupListBox);
1421
1422//**********************************************************************************************************************************************************
1423//Password Field
1424//**********************************************************************************************************************************************************
1425/**
1426 * Extends mxShape.
1427 */
1428function mxShapeMockupPwField(bounds, fill, stroke, strokewidth)
1429{
1430	mxShape.call(this);
1431	this.bounds = bounds;
1432	this.fill = fill;
1433	this.stroke = stroke;
1434	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1435};
1436
1437/**
1438 * Extends mxShape.
1439 */
1440mxUtils.extend(mxShapeMockupPwField, mxShape);
1441
1442mxShapeMockupPwField.prototype.cst = {
1443		MAIN_TEXT : 'mainText',
1444		TEXT_COLOR : 'textColor',
1445		TEXT_SIZE : 'textSize',
1446		SHAPE_PW_FIELD : 'mxgraph.mockup.forms.pwField'
1447};
1448
1449/**
1450 * Function: paintVertexShape
1451 *
1452 * Paints the vertex shape.
1453 */
1454mxShapeMockupPwField.prototype.paintVertexShape = function(c, x, y, w, h)
1455{
1456	c.translate(x, y);
1457	this.background(c, w, h);
1458	c.setShadow(false);
1459	this.foreground(c, w, h);
1460};
1461
1462mxShapeMockupPwField.prototype.background = function(c, w, h)
1463{
1464	c.rect(0, 0, w, h);
1465	c.fillAndStroke();
1466};
1467
1468mxShapeMockupPwField.prototype.foreground = function(c, w, h)
1469{
1470	var mainText = mxUtils.getValue(this.style, mxShapeMockupPwField.prototype.cst.MAIN_TEXT, '******');
1471	var fontColor = mxUtils.getValue(this.style, mxShapeMockupPwField.prototype.cst.TEXT_COLOR, '#666666');
1472	var fontSize = mxUtils.getValue(this.style, mxShapeMockupPwField.prototype.cst.TEXT_SIZE, '17');
1473
1474	c.setFontColor(fontColor);
1475	c.setFontSize(fontSize);
1476
1477	c.text(5, h * 0.5, 0, 0, mainText, mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1478};
1479
1480mxCellRenderer.registerShape(mxShapeMockupPwField.prototype.cst.SHAPE_PW_FIELD, mxShapeMockupPwField);
1481
1482//**********************************************************************************************************************************************************
1483//Splitter
1484//**********************************************************************************************************************************************************
1485/**
1486 * Extends mxShape.
1487 */
1488function mxShapeMockupSplitter(bounds, fill, stroke, strokewidth)
1489{
1490	mxShape.call(this);
1491	this.bounds = bounds;
1492	this.fill = fill;
1493	this.stroke = stroke;
1494	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1495};
1496
1497/**
1498 * Extends mxShape.
1499 */
1500mxUtils.extend(mxShapeMockupSplitter, mxShape);
1501
1502mxShapeMockupSplitter.prototype.cst = {
1503		MAIN_TEXT : 'mainText',
1504		TEXT_COLOR : 'textColor',
1505		TEXT_SIZE : 'textSize',
1506		SHAPE_SPLITTER : 'mxgraph.mockup.forms.splitter'
1507};
1508
1509/**
1510 * Function: paintVertexShape
1511 *
1512 * Paints the vertex shape.
1513 */
1514mxShapeMockupSplitter.prototype.paintVertexShape = function(c, x, y, w, h)
1515{
1516	w = Math.max(w, 35);
1517	c.translate(x, y);
1518	this.background(c, w, h);
1519	c.setShadow(false);
1520	this.foreground(c, w, h);
1521};
1522
1523mxShapeMockupSplitter.prototype.background = function(c, w, h)
1524{
1525	c.begin();
1526	c.moveTo(0, h * 0.5 - 5);
1527	c.lineTo(w, h * 0.5 - 5);
1528	c.lineTo(w, h * 0.5 + 5);
1529	c.lineTo(0, h * 0.5 + 5);
1530	c.close();
1531	c.fill();
1532};
1533
1534mxShapeMockupSplitter.prototype.foreground = function(c, w, h)
1535{
1536	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#999999');
1537
1538	c.begin();
1539	c.moveTo(0, h * 0.5 - 5);
1540	c.lineTo(w, h * 0.5 - 5);
1541	c.moveTo(w, h * 0.5 + 5);
1542	c.lineTo(0, h * 0.5 + 5);
1543	c.stroke();
1544
1545	c.setFillColor(strokeColor);
1546	c.ellipse(w * 0.5 - 17, h * 0.5 - 2, 4, 4);
1547	c.fill();
1548	c.ellipse(w * 0.5 - 2, h * 0.5 - 2, 4, 4);
1549	c.fill();
1550	c.ellipse(w * 0.5 + 13, h * 0.5 - 2, 4, 4);
1551	c.fill();
1552};
1553
1554mxCellRenderer.registerShape(mxShapeMockupSplitter.prototype.cst.SHAPE_SPLITTER, mxShapeMockupSplitter);
1555
1556//**********************************************************************************************************************************************************
1557//Wedge Bar (LEGACY)
1558//**********************************************************************************************************************************************************
1559/**
1560 * Extends mxShape.
1561 */
1562function mxShapeMockupWedgeBar(bounds, fill, stroke, strokewidth)
1563{
1564	mxShape.call(this);
1565	this.bounds = bounds;
1566	this.fill = fill;
1567	this.stroke = stroke;
1568	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1569};
1570
1571/**
1572 * Extends mxShape.
1573 */
1574mxUtils.extend(mxShapeMockupWedgeBar, mxShape);
1575
1576mxShapeMockupWedgeBar.prototype.cst = {
1577		BLOCK : 'block',
1578		CONE : 'cone',
1579		HALF_CONE : 'halfCone',
1580		ROUND : 'round',
1581		TEXT_SIZE : 'textSize',
1582		TAB_NAMES : 'tabs',
1583		TAB_STYLE : 'tabStyle',
1584		STYLE_FILLCOLOR2 : 'fillColor2',
1585		TEXT_COLOR : 'textColor',
1586		SEL_TEXT_COLOR : 'textColor2',
1587		SHAPE_WEDGE_BAR : 'mxgraph.mockup.forms.wedgeBar'
1588};
1589
1590/**
1591 * Function: paintVertexShape
1592 *
1593 * Paints the vertex shape.
1594 */
1595mxShapeMockupWedgeBar.prototype.paintVertexShape = function(c, x, y, w, h)
1596{
1597	var fontSize = mxUtils.getValue(this.style, mxShapeMockupWedgeBar.prototype.cst.TEXT_SIZE, '17').toString();
1598	var tabNames = mxUtils.getValue(this.style, mxShapeMockupWedgeBar.prototype.cst.TAB_NAMES, 'Tab 1,+Tab 2,Tab 3').toString().split(',');
1599
1600	var tabH = fontSize * 1.5;
1601	var startOffset = 10;
1602	var tabOffset = 5;
1603	var labelOffset = 10;
1604	var tabCount = tabNames.length;
1605	var minW = 2 * startOffset + (tabCount - 1) * tabOffset + tabCount * 2 * labelOffset;
1606	var rSize = 5;
1607	var labelWidths = new Array();
1608	var selectedTab = -1;
1609
1610	for (var i = 0; i < tabCount; i++)
1611	{
1612		var currLabel = tabNames[i];
1613
1614		if(currLabel.charAt(0) === '+')
1615		{
1616			currLabel = currLabel.substring(1);
1617			selectedTab = i;
1618		}
1619
1620		var currW = mxUtils.getSizeForString(currLabel, fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
1621
1622		if (currW === 0)
1623		{
1624			labelWidths[i] = 42;
1625		}
1626		else
1627		{
1628			labelWidths[i] = currW;
1629		}
1630
1631		minW = minW + labelWidths[i];
1632	}
1633
1634	w = Math.max(w, minW);
1635	h = Math.max(h, tabH + rSize);
1636
1637	c.translate(x, y);
1638
1639	c.setShadow(false);
1640	this.backTabs(c, w, h, rSize, tabH, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab);
1641	this.focusTab(c, w, h, rSize, tabH, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab);
1642	this.tabText(c, w, h, rSize, tabH, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab, tabNames);
1643};
1644
1645mxShapeMockupWedgeBar.prototype.backTabs = function(c, w, h, rSize, tabH, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab)
1646{
1647	var tabStyle = mxUtils.getValue(this.style, mxShapeMockupWedgeBar.prototype.cst.TAB_STYLE, mxShapeMockupWedgeBar.prototype.cst.BLOCK);
1648
1649	var currW = startOffset;
1650	for (var i=0; i < tabCount; i++)
1651	{
1652		var tabW = labelWidths[i] + 2 * labelOffset;
1653
1654		if (selectedTab !== i)
1655		{
1656			if (tabStyle === mxShapeMockupWedgeBar.prototype.cst.BLOCK)
1657			{
1658				c.begin();
1659				c.moveTo(currW, tabH);
1660				c.lineTo(currW, 0);
1661				c.lineTo(currW + tabW, 0);
1662				c.lineTo(currW + tabW, tabH);
1663			}
1664			else if (tabStyle === mxShapeMockupWedgeBar.prototype.cst.CONE)
1665			{
1666				c.begin();
1667				c.moveTo(currW, tabH);
1668				c.lineTo(currW + labelOffset * 0.5, 0);
1669				c.lineTo(currW + tabW - labelOffset * 0.5, 0);
1670				c.lineTo(currW + tabW, tabH);
1671			}
1672			else if (tabStyle === mxShapeMockupWedgeBar.prototype.cst.HALF_CONE)
1673			{
1674				c.begin();
1675				c.moveTo(currW, tabH);
1676				c.lineTo(currW + labelOffset * 0.5, 0);
1677				c.lineTo(currW + tabW, 0);
1678				c.lineTo(currW + tabW, tabH);
1679			}
1680			else if (tabStyle === mxShapeMockupWedgeBar.prototype.cst.ROUND)
1681			{
1682				c.begin();
1683				c.moveTo(currW - rSize, tabH);
1684				c.arcTo(rSize, rSize, 0, 0, 0, currW, tabH - rSize);
1685				c.lineTo(currW, rSize);
1686				c.arcTo(rSize, rSize, 0, 0, 1, currW + rSize, 0);
1687				c.lineTo(currW + tabW - rSize, 0);
1688				c.arcTo(rSize, rSize, 0, 0, 1, currW + tabW, rSize);
1689				c.lineTo(currW + tabW, tabH - rSize);
1690				c.arcTo(rSize, rSize, 0, 0, 0, currW + tabW + rSize, tabH);
1691			}
1692
1693			c.fillAndStroke();
1694		}
1695
1696		currW = currW + tabW + tabOffset;
1697	}
1698};
1699
1700mxShapeMockupWedgeBar.prototype.focusTab = function(c, w, h, rSize, tabH, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab)
1701{
1702	var tabStyle = mxUtils.getValue(this.style, mxShapeMockupWedgeBar.prototype.cst.TAB_STYLE, mxShapeMockupWedgeBar.prototype.cst.BLOCK);
1703	var selectedFill = mxUtils.getValue(this.style, mxShapeMockupWedgeBar.prototype.cst.STYLE_FILLCOLOR2, '#008cff');
1704
1705	var currW = startOffset;
1706	c.setStrokeColor(selectedFill);
1707	c.setFillColor(selectedFill);
1708
1709	for (var i=0; i <= selectedTab; i++)
1710	{
1711		var tabW = labelWidths[i] + 2 * labelOffset;
1712
1713		if (selectedTab === i)
1714		{
1715			if (tabStyle === mxShapeMockupWedgeBar.prototype.cst.BLOCK)
1716			{
1717				c.begin();
1718				c.moveTo(currW, tabH);
1719				c.lineTo(currW, 0);
1720				c.lineTo(currW + tabW, 0);
1721				c.lineTo(currW + tabW, tabH);
1722			}
1723			else if (tabStyle === mxShapeMockupWedgeBar.prototype.cst.CONE)
1724			{
1725				c.begin();
1726				c.moveTo(currW, tabH);
1727				c.lineTo(currW + labelOffset * 0.5, 0);
1728				c.lineTo(currW + tabW - labelOffset * 0.5, 0);
1729				c.lineTo(currW + tabW, tabH);
1730			}
1731			else if (tabStyle === mxShapeMockupWedgeBar.prototype.cst.HALF_CONE)
1732			{
1733				c.begin();
1734				c.moveTo(currW, tabH);
1735				c.lineTo(currW + labelOffset * 0.5, 0);
1736				c.lineTo(currW + tabW, 0);
1737				c.lineTo(currW + tabW, tabH);
1738			}
1739			else if (tabStyle === mxShapeMockupWedgeBar.prototype.cst.ROUND)
1740			{
1741				c.begin();
1742				c.moveTo(currW - rSize, tabH);
1743				c.arcTo(rSize, rSize, 0, 0, 0, currW, tabH - rSize);
1744				c.lineTo(currW, rSize);
1745				c.arcTo(rSize, rSize, 0, 0, 1, currW + rSize, 0);
1746				c.lineTo(currW + tabW - rSize, 0);
1747				c.arcTo(rSize, rSize, 0, 0, 1, currW + tabW, rSize);
1748				c.lineTo(currW + tabW, tabH - rSize);
1749				c.arcTo(rSize, rSize, 0, 0, 0, currW + tabW + rSize, tabH);
1750			}
1751
1752			c.fillAndStroke();
1753		}
1754
1755		currW = currW + tabW + tabOffset;
1756	}
1757};
1758
1759mxShapeMockupWedgeBar.prototype.tabText = function(c, w, h, rSize, tabH, startOffset, tabOffset, labelOffset, tabCount, labelWidths, selectedTab, tabNames)
1760{
1761	var fontColor = mxUtils.getValue(this.style, mxShapeMockupWedgeBar.prototype.cst.TEXT_COLOR, '#666666');
1762	var selFontColor = mxUtils.getValue(this.style, mxShapeMockupWedgeBar.prototype.cst.SEL_TEXT_COLOR, '#ffffff');
1763	var fontSize = mxUtils.getValue(this.style, mxShapeMockupWedgeBar.prototype.cst.TEXT_SIZE, '17').toString();
1764
1765	c.setFontColor(fontColor);
1766	c.setFontSize(fontSize);
1767
1768	var currW = startOffset;
1769
1770	for (var i=0; i < tabCount; i++)
1771	{
1772		var currLabel = tabNames[i];
1773
1774		if (i === selectedTab)
1775		{
1776			c.setFontColor(selFontColor);
1777		}
1778
1779		if (currLabel.charAt(0) === '+')
1780		{
1781			currLabel = currLabel.substring(1);
1782		}
1783
1784		var tabW = labelWidths[i] + 2 * labelOffset;
1785
1786		c.text(currW + labelOffset, tabH * 0.5, 0, 0, currLabel, mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1787
1788		currW = currW + tabW + tabOffset;
1789
1790		if (i === selectedTab)
1791		{
1792			c.setFontColor(fontColor);
1793		}
1794	}
1795
1796};
1797
1798mxCellRenderer.registerShape(mxShapeMockupWedgeBar.prototype.cst.SHAPE_WEDGE_BAR, mxShapeMockupWedgeBar);
1799
1800//**********************************************************************************************************************************************************
1801//Search Box
1802//**********************************************************************************************************************************************************
1803/**
1804 * Extends mxShape.
1805 */
1806function mxShapeMockupSearchBox(bounds, fill, stroke, strokewidth)
1807{
1808	mxShape.call(this);
1809	this.bounds = bounds;
1810	this.fill = fill;
1811	this.stroke = stroke;
1812	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1813};
1814
1815/**
1816 * Extends mxShape.
1817 */
1818mxUtils.extend(mxShapeMockupSearchBox, mxShape);
1819
1820mxShapeMockupSearchBox.prototype.cst = {
1821		MAIN_TEXT : 'mainText',
1822		TEXT_COLOR : 'textColor',
1823		TEXT_SIZE : 'textSize',
1824		STROKE_COLOR2 : 'strokeColor2',
1825		SHAPE_SEARCH_BOX : 'mxgraph.mockup.forms.searchBox'
1826};
1827
1828mxShapeMockupSearchBox.prototype.customProperties = [
1829	{name: 'strokeColor2', dispName: 'Icon Color', type: 'color'},
1830];
1831
1832/**
1833 * Function: paintVertexShape
1834 *
1835 * Paints the vertex shape.
1836 */
1837mxShapeMockupSearchBox.prototype.paintVertexShape = function(c, x, y, w, h)
1838{
1839	c.translate(x, y);
1840	this.background(c, w, h);
1841	c.setShadow(false);
1842	this.foreground(c, w, h);
1843};
1844
1845mxShapeMockupSearchBox.prototype.background = function(c, w, h)
1846{
1847	c.rect(0, 0, w, h);
1848	c.fillAndStroke();
1849};
1850
1851mxShapeMockupSearchBox.prototype.foreground = function(c, w, h)
1852{
1853	var mainText = mxUtils.getValue(this.style, mxShapeMockupSearchBox.prototype.cst.MAIN_TEXT, 'Search');
1854	var fontColor = mxUtils.getValue(this.style, mxShapeMockupSearchBox.prototype.cst.TEXT_COLOR, '#666666');
1855	var strokeColor2 = mxUtils.getValue(this.style, mxShapeMockupSearchBox.prototype.cst.STROKE_COLOR2, '#008cff');
1856	var fontSize = mxUtils.getValue(this.style, mxShapeMockupSearchBox.prototype.cst.TEXT_SIZE, '17');
1857
1858	c.setFontColor(fontColor);
1859	c.setFontSize(fontSize);
1860
1861	c.text(5, h * 0.5, 0, 0, mainText, mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1862
1863	c.setStrokeColor(strokeColor2);
1864	c.ellipse(w - 15, h * 0.5 - 8, 10, 10);
1865	c.stroke();
1866	c.begin();
1867	c.moveTo(w - 19, h * 0.5 + 9);
1868	c.lineTo(w - 13, h * 0.5 + 1);
1869	c.stroke();
1870};
1871
1872mxCellRenderer.registerShape(mxShapeMockupSearchBox.prototype.cst.SHAPE_SEARCH_BOX, mxShapeMockupSearchBox);
1873
1874//**********************************************************************************************************************************************************
1875//Sign In (LEGACY)
1876//**********************************************************************************************************************************************************
1877/**
1878 * Extends mxShape.
1879 */
1880function mxShapeMockupSignIn(bounds, fill, stroke, strokewidth)
1881{
1882	mxShape.call(this);
1883	this.bounds = bounds;
1884	this.fill = fill;
1885	this.stroke = stroke;
1886	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
1887};
1888
1889/**
1890 * Extends mxShape.
1891 */
1892mxUtils.extend(mxShapeMockupSignIn, mxShape);
1893
1894mxShapeMockupSignIn.prototype.cst = {
1895		MAIN_TEXT : 'mainText',
1896		TEXT_COLOR : 'textColor',
1897		TEXT_COLOR2 : 'textColor2',
1898		TEXT_SIZE : 'textSize',
1899		TEXT_SIZE2 : 'textSize2',
1900		STROKE_COLOR2 : 'strokeColor2',
1901		FILL_COLOR2 : 'fillColor2',
1902		SHAPE_SIGN_IN : 'mxgraph.mockup.forms.signIn'
1903};
1904
1905/**
1906 * Function: paintVertexShape
1907 *
1908 * Paints the vertex shape.
1909 */
1910mxShapeMockupSignIn.prototype.paintVertexShape = function(c, x, y, w, h)
1911{
1912	c.translate(x, y);
1913	this.background(c, w, h);
1914	c.setShadow(false);
1915	this.foreground(c, w, h);
1916};
1917
1918mxShapeMockupSignIn.prototype.background = function(c, w, h)
1919{
1920	c.rect(0, 0, w, h);
1921	c.fillAndStroke();
1922};
1923
1924mxShapeMockupSignIn.prototype.foreground = function(c, w, h)
1925{
1926	var mainText = mxUtils.getValue(this.style, mxShapeMockupSignIn.prototype.cst.MAIN_TEXT, 'Sign In,User Name:,johndoe,Password:,********,Forgot Password?,New User,SIGN IN,SIGN UP').toString().split(',');
1927	var fontColor = mxUtils.getValue(this.style, mxShapeMockupSignIn.prototype.cst.TEXT_COLOR, '#666666');
1928	var fontColor2 = mxUtils.getValue(this.style, mxShapeMockupSignIn.prototype.cst.TEXT_COLOR2, '#ffffff');
1929	var fontSize = mxUtils.getValue(this.style, mxShapeMockupSignIn.prototype.cst.TEXT_SIZE, '12');
1930	var fontSize2 = mxUtils.getValue(this.style, mxShapeMockupSignIn.prototype.cst.TEXT_SIZE2, '15');
1931	var strokeColor2 = mxUtils.getValue(this.style, mxShapeMockupSignIn.prototype.cst.STROKE_COLOR2, '#ddeeff');
1932	var fillColor2 = mxUtils.getValue(this.style, mxShapeMockupSignIn.prototype.cst.FILL_COLOR2, '#66bbff');
1933
1934	c.setFillColor(fillColor2);
1935	c.roundrect(w * 0.09, h * 0.52, w * 0.36, h * 0.09, 5, 5);
1936	c.fill();
1937
1938	c.roundrect(w * 0.09, h * 0.84, w * 0.36, h * 0.09, 5, 5);
1939	c.fill();
1940
1941	c.rect(w * 0.05, h * 0.22, w * 0.75, h * 0.08);
1942	c.stroke();
1943
1944	c.rect(w * 0.05, h * 0.4, w * 0.75, h * 0.08);
1945	c.stroke();
1946
1947
1948	c.setStrokeColor(strokeColor2);
1949	c.setStrokeWidth(2);
1950
1951	c.begin();
1952	c.moveTo(w * 0.05, h * 0.12);
1953	c.lineTo(w * 0.95, h * 0.12);
1954	c.moveTo(w * 0.05, h * 0.72);
1955	c.lineTo(w * 0.95, h * 0.72);
1956	c.stroke();
1957
1958
1959	c.setFontColor(fontColor);
1960	c.setFontSize(fontSize);
1961	c.text(w * 0.05, h * 0.1, 0, 0, mainText[0], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_BOTTOM, 0, null, 0, 0, 0);
1962	c.text(w * 0.05, h * 0.2, 0, 0, mainText[1], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_BOTTOM, 0, null, 0, 0, 0);
1963	c.text(w * 0.075, h * 0.26, 0, 0, mainText[2], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1964	c.text(w * 0.05, h * 0.38, 0, 0, mainText[3], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_BOTTOM, 0, null, 0, 0, 0);
1965	c.text(w * 0.075, h * 0.44, 0, 0, mainText[4], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1966	c.text(w * 0.05, h * 0.8, 0, 0, mainText[6], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1967
1968	c.setStrokeWidth(1);
1969	c.setFontColor('#9999ff');
1970	c.setStrokeColor('#9999ff');
1971	var forgotW = mxUtils.getSizeForString(mainText[5], fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
1972	c.text(w * 0.05, h * 0.7, 0, 0, mainText[5], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_BOTTOM, 0, null, 0, 0, 0);
1973
1974	c.begin();
1975	c.moveTo(w * 0.05, h * 0.7);
1976	c.lineTo(w * 0.05 + forgotW, h * 0.7);
1977	c.stroke();
1978
1979	c.setFontColor(fontColor2);
1980	c.setFontStyle(mxConstants.FONT_BOLD);
1981	c.setFontSize(fontSize2);
1982	c.text(w * 0.27, h * 0.565, 0, 0, mainText[7], mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1983	c.text(w * 0.27, h * 0.885, 0, 0, mainText[8], mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
1984};
1985
1986mxCellRenderer.registerShape(mxShapeMockupSignIn.prototype.cst.SHAPE_SIGN_IN, mxShapeMockupSignIn);
1987
1988//**********************************************************************************************************************************************************
1989//Calendar (LEGACY)
1990//**********************************************************************************************************************************************************
1991/**
1992 * Extends mxShape.
1993 */
1994function mxShapeMockupCalendar(bounds, fill, stroke, strokewidth)
1995{
1996	mxShape.call(this);
1997	this.bounds = bounds;
1998	this.fill = fill;
1999	this.stroke = stroke;
2000	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
2001};
2002
2003/**
2004 * Extends mxShape.
2005 */
2006mxUtils.extend(mxShapeMockupCalendar, mxShape);
2007
2008mxShapeMockupCalendar.prototype.cst = {
2009		SHAPE_CALENDAR : 'mxgraph.mockup.forms.calendar',
2010		DAYS : 'days',
2011		SELECTED_DAY : 'selDay',
2012		PREV_DAYS : 'prevDays',
2013		FIRST_DAY : 'firstDay',
2014		START_ON : 'startOn',
2015		DAY_NAMES : 'dayNames',
2016		MAIN_TEXT : 'mainText',
2017		TEXT_SIZE : 'textSize',
2018		TEXT_COLOR : 'textColor',
2019		TEXT_COLOR2 : 'textColor2',
2020		STROKE_COLOR2 : 'strokeColor2',
2021		FILL_COLOR2 : 'fillColor2'
2022};
2023
2024/**
2025 * Function: paintVertexShape
2026 *
2027 * Paints the vertex shape.
2028 */
2029mxShapeMockupCalendar.prototype.paintVertexShape = function(c, x, y, w, h)
2030{
2031	c.translate(x, y);
2032	this.background(c, w, h);
2033	c.setShadow(false);
2034	this.foreground(c, w, h);
2035};
2036
2037mxShapeMockupCalendar.prototype.background = function(c, w, h)
2038{
2039	c.roundrect(0, 0, w, h, w * 0.0312, h * 0.0286);
2040	c.fillAndStroke();
2041};
2042
2043mxShapeMockupCalendar.prototype.foreground = function(c, w, h)
2044{
2045	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#999999');
2046	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
2047	var strokeColor2 = mxUtils.getValue(this.style, mxShapeMockupCalendar.prototype.cst.STROKE_COLOR2, '#008cff');
2048	var fillColor2 = mxUtils.getValue(this.style, mxShapeMockupCalendar.prototype.cst.FILL_COLOR2, '#ddeeff');
2049	var mainText = mxUtils.getValue(this.style, mxShapeMockupCalendar.prototype.cst.MAIN_TEXT, '');
2050	var textSize = mxUtils.getValue(this.style, mxShapeMockupCalendar.prototype.cst.TEXT_SIZE, '15');
2051	var textColor = mxUtils.getValue(this.style, mxShapeMockupCalendar.prototype.cst.TEXT_COLOR, '#999999');
2052	var textColor2 = mxUtils.getValue(this.style, mxShapeMockupCalendar.prototype.cst.TEXT_COLOR2, '#ffffff');
2053	var days = parseInt(mxUtils.getValue(this.style, mxShapeMockupCalendar.prototype.cst.DAYS, '30'), 10);
2054	var prevDays = parseInt(mxUtils.getValue(this.style, mxShapeMockupCalendar.prototype.cst.PREV_DAYS, '31'), 10);
2055	//month starts on Monday
2056	var firstDay = parseInt(mxUtils.getValue(this.style, mxShapeMockupCalendar.prototype.cst.FIRST_DAY, '0'), 10);
2057	//week starts with Monday
2058	var startOn = parseInt(mxUtils.getValue(this.style, mxShapeMockupCalendar.prototype.cst.START_ON, '6', 10));
2059	var dayNames = mxUtils.getValue(this.style, mxShapeMockupCalendar.prototype.cst.DAY_NAMES, 'Mo,Tu,We,Th,Fr,Sa,Su').toString().split(',');
2060	var selDay = parseInt(mxUtils.getValue(this.style, mxShapeMockupCalendar.prototype.cst.SELECTED_DAY, '24'), 10);
2061
2062	fistDay = Math.max(firstDay, 0);
2063	startOn = Math.max(startOn, 0);
2064	fistDay = Math.min(firstDay, 6);
2065	startOn = Math.min(startOn, 6);
2066
2067	//buttons
2068	c.roundrect(w * 0.05, h * 0.0457, w * 0.1438, h * 0.1029, w * 0.025, h * 0.0229);
2069	c.stroke();
2070	c.roundrect(w * 0.8125, h * 0.0457, w * 0.1438, h * 0.1029, w * 0.025, h * 0.0229);
2071	c.stroke();
2072
2073	//button markers
2074	c.setStrokeWidth(2);
2075	c.setStrokeColor(strokeColor2);
2076	c.begin();
2077	c.moveTo(w * 0.1438, h * 0.0743);
2078	c.lineTo(w * 0.1, h * 0.0971);
2079	c.lineTo(w * 0.1438, h * 0.12);
2080	c.moveTo(w * 0.8625, h * 0.0743);
2081	c.lineTo(w * 0.9062, h * 0.0971);
2082	c.lineTo(w * 0.8625, h * 0.12);
2083	c.stroke();
2084
2085	c.setFontSize(textSize);
2086	c.setFontColor(textColor);
2087	c.text(w * 0.5, h * 0.0971, 0, 0, mainText, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2088
2089	//write day names
2090	var range = w * 0.875;
2091	var cellSize = range / 7;
2092
2093	for (var i = 0; i < 7; i++)
2094	{
2095		var currX = w * 0.0625 + cellSize * 0.5 + i * cellSize;
2096		var j = i + startOn;
2097
2098		if (j > 6)
2099		{
2100			j = j - 7;
2101		}
2102
2103		c.text(currX, h * 0.2114, 0, 0, dayNames[j], mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2104	}
2105
2106	c.setStrokeWidth(1);
2107	//1st day is on first weekday as default
2108	var x = 0;
2109	var selX = -1;
2110	var selY = -1;
2111
2112	//check if we need to write days from previous month
2113	if (firstDay !== startOn)
2114	{
2115		c.setStrokeColor(strokeColor);
2116		c.setFillColor(fillColor2);
2117
2118		var diff = firstDay - startOn;
2119		if (diff < 0)
2120		{
2121			diff = diff + 7;
2122		}
2123
2124		for (var i = 0; i < diff; i++)
2125		{
2126			var currX = w * 0.0625 + i * cellSize;
2127			c.rect(currX, h * 0.2686, cellSize, h * 0.1143);
2128			c.fillAndStroke();
2129			var tmp = prevDays - diff + i + 1;
2130
2131			c.text(currX + cellSize * 0.5, h * 0.2686 + cellSize * 0.5, 0, 0, tmp.toString(), mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2132		}
2133
2134		x = diff;
2135	}
2136
2137	//now we need to write the actual month days...
2138	c.setFillColor(fillColor);
2139	c.setStrokeColor(strokeColor);
2140	//week begins in first row
2141	var y = 0;
2142
2143	for (var i = 0; i < days; i++)
2144	{
2145		var d = i + 1;
2146		var currX = w * 0.0625 + x * cellSize;
2147		var currY = h * 0.2686 + y * h * 0.1143;
2148
2149		if (d === selDay)
2150		{
2151			selX = currX;
2152			selY = currY;
2153		}
2154		else
2155		{
2156			c.rect(currX, currY, cellSize, h * 0.1143);
2157			c.fillAndStroke();
2158			c.text(currX + cellSize * 0.5, currY + cellSize * 0.5, 0, 0, d.toString(), mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2159		}
2160
2161		if (x < 6)
2162		{
2163			x++;
2164		}
2165		else
2166		{
2167			x = 0;
2168			y++;
2169		}
2170	}
2171
2172	var i = 1;
2173	c.setFillColor(fillColor2);
2174
2175	while (y < 6)
2176	{
2177		var currX = w * 0.0625 + x * cellSize;
2178		var currY = h * 0.2686 + y * h * 0.1143;
2179		c.rect(currX, currY, cellSize, h * 0.1143);
2180		c.fillAndStroke();
2181
2182		c.text(currX + cellSize * 0.5, currY + cellSize * 0.5, 0, 0, i.toString(), mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2183
2184		if (x < 6)
2185		{
2186			x++;
2187		}
2188		else
2189		{
2190			x = 0;
2191			y++;
2192		}
2193
2194		i++;
2195	}
2196
2197	if (selX >= 0)
2198	{
2199		c.setStrokeColor('#ff0000');
2200		c.setStrokeWidth(2);
2201		c.setFillColor(strokeColor2);
2202		c.setFontColor(textColor2);
2203
2204		c.rect(selX, selY, cellSize, h * 0.1143);
2205		c.fillAndStroke();
2206		c.text(selX + cellSize * 0.5, selY + cellSize * 0.5, 0, 0, selDay.toString(), mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2207	}
2208};
2209
2210mxCellRenderer.registerShape(mxShapeMockupCalendar.prototype.cst.SHAPE_CALENDAR, mxShapeMockupCalendar);
2211
2212//**********************************************************************************************************************************************************
2213//Email Form
2214//**********************************************************************************************************************************************************
2215/**
2216 * Extends mxShape.
2217 */
2218function mxShapeMockupEmailForm(bounds, fill, stroke, strokewidth)
2219{
2220	mxShape.call(this);
2221	this.bounds = bounds;
2222	this.fill = fill;
2223	this.stroke = stroke;
2224	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
2225};
2226
2227/**
2228 * Extends mxShape.
2229 */
2230mxUtils.extend(mxShapeMockupEmailForm, mxShape);
2231
2232mxShapeMockupEmailForm.prototype.cst = {
2233		MAIN_TEXT : 'mainText',
2234		TEXT_COLOR : 'textColor',
2235		SHOW_CC : 'showCC',
2236		SHOW_BCC : 'showBCC',
2237		TEXT_SIZE : 'textSize',
2238		SHAPE_EMAIL_FORM : 'mxgraph.mockup.forms.emailForm'
2239};
2240
2241/**
2242 * Function: paintVertexShape
2243 *
2244 * Paints the vertex shape.
2245 */
2246mxShapeMockupEmailForm.prototype.paintVertexShape = function(c, x, y, w, h)
2247{
2248	var fontSize = mxUtils.getValue(this.style, mxShapeMockupEmailForm.prototype.cst.TEXT_SIZE, '12');
2249	var showCC = mxUtils.getValue(this.style, mxShapeMockupEmailForm.prototype.cst.SHOW_CC, 'true');
2250	var showBCC = mxUtils.getValue(this.style, mxShapeMockupEmailForm.prototype.cst.SHOW_BCC, 'true');
2251	var tabX = fontSize * 4;
2252
2253	var optCount = 0;
2254
2255	if (showCC === 'true')
2256	{
2257		optCount++;
2258	}
2259
2260	if (showBCC === 'true')
2261	{
2262		optCount++;
2263	}
2264
2265	w = Math.max(w, fontSize * 5);
2266	h = Math.max(h, fontSize * 10.5 + optCount * fontSize * 3);
2267
2268	c.translate(x, y);
2269	this.background(c, w, h, fontSize, tabX, showCC, showBCC);
2270	c.setShadow(false);
2271	this.foreground(c, w, h, fontSize, tabX, showCC, showBCC);
2272};
2273
2274mxShapeMockupEmailForm.prototype.background = function(c, w, h, fontSize, tabX, showCC, showBCC)
2275{
2276	var messX = fontSize * 9;
2277
2278	if (showCC === 'true')
2279	{
2280		messX = messX + fontSize * 3;
2281		c.rect(tabX, fontSize * 9, w - tabX, fontSize * 1.5);
2282		c.fillAndStroke();
2283	}
2284
2285	if (showBCC === 'true')
2286	{
2287		c.rect(tabX, messX, w - tabX, fontSize * 1.5);
2288		messX = messX + fontSize * 3;
2289		c.fillAndStroke();
2290	}
2291
2292	c.rect(tabX, 0, w - tabX, fontSize * 1.5);
2293	c.fillAndStroke();
2294	c.rect(tabX, fontSize * 3, w - tabX, fontSize * 1.5);
2295	c.fillAndStroke();
2296	c.rect(tabX, fontSize * 6, w - tabX, fontSize * 1.5);
2297	c.fillAndStroke();
2298	c.rect(0, messX, w, h - messX);
2299	c.fillAndStroke();
2300};
2301
2302mxShapeMockupEmailForm.prototype.foreground = function(c, w, h, fontSize, tabX, showCC, showBCC)
2303{
2304	var mainText = mxUtils.getValue(this.style, mxShapeMockupEmailForm.prototype.cst.MAIN_TEXT, 'john@jgraph.com,Greeting,fred@jgraph.com,,,Lorem ipsum').toString().split(',');
2305	var fontColor = mxUtils.getValue(this.style, mxShapeMockupEmailForm.prototype.cst.TEXT_COLOR, '#666666');
2306
2307	c.setFontColor(fontColor);
2308	c.setFontSize(fontSize);
2309
2310	c.text(tabX - fontSize * 0.5, fontSize * 0.75, 0, 0, 'From', mxConstants.ALIGN_RIGHT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2311	c.text(tabX - fontSize * 0.5, fontSize * 3.75, 0, 0, 'Subject', mxConstants.ALIGN_RIGHT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2312	c.text(tabX - fontSize * 0.5, fontSize * 6.75, 0, 0, 'To', mxConstants.ALIGN_RIGHT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2313
2314	c.text(tabX + fontSize * 0.5, fontSize * 0.75, 0, 0, mainText[0], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2315	c.text(tabX + fontSize * 0.5, fontSize * 3.75, 0, 0, mainText[1], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2316	c.text(tabX + fontSize * 0.5, fontSize * 6.75, 0, 0, mainText[2], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2317
2318	var messX = fontSize * 9;
2319
2320	if (showCC === 'true')
2321	{
2322		messX = messX + fontSize * 3;
2323		c.text(tabX - fontSize * 0.5, fontSize * 9.75, 0, 0, 'CC', mxConstants.ALIGN_RIGHT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2324		c.text(tabX + fontSize * 0.5, fontSize * 9.75, 0, 0, mainText[3], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2325	}
2326
2327	if (showBCC === 'true')
2328	{
2329		c.text(tabX - fontSize * 0.5, messX + fontSize * 0.75, 0, 0, 'BCC', mxConstants.ALIGN_RIGHT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2330		c.text(tabX + fontSize * 0.5, messX + fontSize * 0.75, 0, 0, mainText[4], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2331		messX = messX + fontSize * 3;
2332	}
2333
2334	c.text(fontSize * 0.5, messX + fontSize * 0.75, 0, 0, mainText[5], mxConstants.ALIGN_LEFT, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
2335};
2336
2337mxCellRenderer.registerShape(mxShapeMockupEmailForm.prototype.cst.SHAPE_EMAIL_FORM, mxShapeMockupEmailForm);
2338
2339//**********************************************************************************************************************************************************
2340//Rounded rectangle (adjustable rounding)
2341//**********************************************************************************************************************************************************
2342/**
2343* Extends mxShape.
2344*/
2345function mxShapeMockupFormsRRect(bounds, fill, stroke, strokewidth)
2346{
2347	mxShape.call(this);
2348	this.bounds = bounds;
2349	this.fill = fill;
2350	this.stroke = stroke;
2351	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
2352};
2353
2354/**
2355* Extends mxShape.
2356*/
2357mxUtils.extend(mxShapeMockupFormsRRect, mxShape);
2358
2359mxShapeMockupFormsRRect.prototype.cst = {
2360		RRECT : 'mxgraph.mockup.forms.rrect',
2361		R_SIZE : 'rSize'
2362};
2363
2364mxShapeMockupFormsRRect.prototype.customProperties = [
2365	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10},
2366];
2367
2368/**
2369* Function: paintVertexShape
2370*
2371* Paints the vertex shape.
2372*/
2373mxShapeMockupFormsRRect.prototype.paintVertexShape = function(c, x, y, w, h)
2374{
2375	c.translate(x, y);
2376
2377	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeMockupFormsRRect.prototype.cst.R_SIZE, '10'));
2378	c.roundrect(0, 0, w, h, rSize);
2379	c.fillAndStroke();
2380};
2381
2382mxCellRenderer.registerShape(mxShapeMockupFormsRRect.prototype.cst.RRECT, mxShapeMockupFormsRRect);
2383
2384//**********************************************************************************************************************************************************
2385//Anchor (a dummy shape without visuals used for anchoring)
2386//**********************************************************************************************************************************************************
2387/**
2388* Extends mxShape.
2389*/
2390function mxShapeMockupFormsAnchor(bounds, fill, stroke, strokewidth)
2391{
2392	mxShape.call(this);
2393	this.bounds = bounds;
2394};
2395
2396/**
2397* Extends mxShape.
2398*/
2399mxUtils.extend(mxShapeMockupFormsAnchor, mxShape);
2400
2401mxShapeMockupFormsAnchor.prototype.cst = {
2402		ANCHOR : 'mxgraph.mockup.forms.anchor'
2403};
2404
2405/**
2406* Function: paintVertexShape
2407*
2408* Paints the vertex shape.
2409*/
2410mxShapeMockupFormsAnchor.prototype.paintVertexShape = function(c, x, y, w, h)
2411{
2412};
2413
2414mxCellRenderer.registerShape(mxShapeMockupFormsAnchor.prototype.cst.ANCHOR, mxShapeMockupFormsAnchor);
2415
2416//**********************************************************************************************************************************************************
2417//Checkbox
2418//**********************************************************************************************************************************************************
2419/**
2420* Extends mxShape.
2421*/
2422function mxShapeMockupFormsCheckbox(bounds, fill, stroke, strokewidth)
2423{
2424	mxShape.call(this);
2425	this.bounds = bounds;
2426	this.fill = fill;
2427	this.stroke = stroke;
2428	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
2429};
2430
2431/**
2432* Extends mxShape.
2433*/
2434mxUtils.extend(mxShapeMockupFormsCheckbox, mxShape);
2435
2436mxShapeMockupFormsCheckbox.prototype.cst = {
2437		CHECKBOX : 'mxgraph.mockup.forms.checkbox'
2438};
2439
2440/**
2441* Function: paintVertexShape
2442*
2443* Paints the vertex shape.
2444*/
2445mxShapeMockupFormsCheckbox.prototype.paintVertexShape = function(c, x, y, w, h)
2446{
2447	c.translate(x, y);
2448
2449	c.rect(0, 0, w, h);
2450	c.fillAndStroke();
2451
2452	c.begin();
2453	c.moveTo(w * 0.8, h * 0.2);
2454	c.lineTo(w * 0.4, h * 0.8);
2455	c.lineTo(w * 0.25, h * 0.6);
2456	c.stroke();
2457};
2458
2459mxCellRenderer.registerShape(mxShapeMockupFormsCheckbox.prototype.cst.CHECKBOX, mxShapeMockupFormsCheckbox);
2460
2461//**********************************************************************************************************************************************************
2462//U Rect
2463//**********************************************************************************************************************************************************
2464/**
2465* Extends mxShape.
2466*/
2467function mxShapeMockupFormsURect(bounds, fill, stroke, strokewidth)
2468{
2469	mxShape.call(this);
2470	this.bounds = bounds;
2471	this.fill = fill;
2472	this.stroke = stroke;
2473	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
2474};
2475
2476/**
2477* Extends mxShape.
2478*/
2479mxUtils.extend(mxShapeMockupFormsURect, mxShape);
2480
2481mxShapeMockupFormsURect.prototype.cst = {
2482		U_RECT : 'mxgraph.mockup.forms.uRect'
2483};
2484
2485/**
2486* Function: paintVertexShape
2487*
2488* Paints the vertex shape.
2489*/
2490mxShapeMockupFormsURect.prototype.paintVertexShape = function(c, x, y, w, h)
2491{
2492	c.translate(x, y);
2493
2494	c.begin();
2495	c.moveTo(0, h);
2496	c.lineTo(0, 0);
2497	c.lineTo(w, 0);
2498	c.lineTo(w, h);
2499	c.fillAndStroke();
2500};
2501
2502mxCellRenderer.registerShape(mxShapeMockupFormsURect.prototype.cst.U_RECT, mxShapeMockupFormsURect);
2503
2504