1/**
2 * $Id: mxMockupButtons.js,v 1.8 2013/05/16 06:09:21 mate Exp $
3 * Copyright (c) 2006-2010, JGraph Ltd
4 */
5
6//**********************************************************************************************************************************************************
7//Multiline Button
8//**********************************************************************************************************************************************************
9/**
10 * Extends mxShape.
11 */
12function mxShapeMockupMultiButton(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(mxShapeMockupMultiButton, mxShape);
25
26mxShapeMockupMultiButton.prototype.cst = {
27		MAIN_TEXT : 'mainText',
28		SHAPE_MULTILINE_BUTTON : 'mxgraph.mockup.buttons.multiButton',
29		SUB_TEXT : 'subText',
30		TEXT_COLOR : 'textColor',
31		TEXT_SIZE : 'textSize',
32		BUTTON_STYLE : 'buttonStyle',
33		ROUND : 'round',
34		CHEVRON : 'chevron'
35};
36
37mxShapeMockupMultiButton.prototype.customProperties = [
38	{name: 'buttonStyle', dispName: 'Style', type: 'enum', defVal:'round',
39		enumList: [{val: 'round', dispName: 'Round'}, {val: 'chevron', dispName: 'Chevron'}]
40	}
41];
42
43/**
44 * Function: paintVertexShape
45 *
46 * Paints the vertex shape.
47 */
48mxShapeMockupMultiButton.prototype.paintVertexShape = function(c, x, y, w, h)
49{
50	var mainText = mxUtils.getValue(this.style, mxShapeMockupMultiButton.prototype.cst.MAIN_TEXT, 'Main Text');
51	var subText = mxUtils.getValue(this.style, mxShapeMockupMultiButton.prototype.cst.SUB_TEXT, 'Sub Text');
52	var fontColor = mxUtils.getValue(this.style, mxShapeMockupMultiButton.prototype.cst.TEXT_COLOR, '#666666');
53	var fontSize = mxUtils.getValue(this.style, mxShapeMockupMultiButton.prototype.cst.TEXT_SIZE, '17');
54	c.translate(x, y);
55	this.background(c, x, y, w, h);
56	c.setShadow(false);
57	c.setFontStyle(mxConstants.FONT_BOLD);
58	this.mainText(c, x, y, w, h, mainText, fontSize, fontColor);
59	this.subText(c, x, y, w, h, subText, fontSize / 1.4, fontColor);
60};
61
62mxShapeMockupMultiButton.prototype.background = function(c, x, y, w, h)
63{
64	var buttonStyle = mxUtils.getValue(this.style, mxShapeMockupMultiButton.prototype.cst.BUTTON_STYLE, mxShapeMockupMultiButton.prototype.cst.ROUND).toString();
65	var rSize = 10;
66	c.begin();
67
68	if (buttonStyle === mxShapeMockupMultiButton.prototype.cst.ROUND)
69	{
70		c.moveTo(0, rSize);
71		c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
72		c.lineTo(w - rSize, 0);
73		c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
74		c.lineTo(w, h - rSize);
75		c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
76		c.lineTo(rSize, h);
77		c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
78	}
79	else if (buttonStyle === mxShapeMockupMultiButton.prototype.cst.CHEVRON)
80	{
81		c.moveTo(0, h * 0.1);
82		c.arcTo(w * 0.0372, h * 0.1111, 0, 0, 1, w * 0.0334, 0);
83		c.lineTo(w * 0.768, 0);
84		c.arcTo(w * 0.0722, h * 0.216, 0, 0, 1, w * 0.8014, h * 0.0399);
85		c.lineTo(w * 0.99, h * 0.4585);
86		c.arcTo(w * 0.09, h * 0.1, 0, 0, 1, w * 0.99, h * 0.5415);
87		c.lineTo(w * 0.8014, h * 0.9568);
88		c.arcTo(w * 0.0722, h * 0.216, 0, 0, 1, w * 0.768, h);
89		c.lineTo(w * 0.0334, h);
90		c.arcTo(w * 0.0372, h * 0.1111, 0, 0, 1, 0, h * 0.9);
91	}
92
93	c.close();
94	c.fillAndStroke();
95};
96
97mxShapeMockupMultiButton.prototype.mainText = function(c, x, y, w, h, text, fontSize, fontColor)
98{
99	c.begin();
100	c.setFontSize(fontSize);
101	c.setFontColor(fontColor);
102	c.text(w * 0.5, h * 0.4, 0, 0, text, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
103};
104
105mxShapeMockupMultiButton.prototype.subText = function(c, x, y, w, h, text, fontSize, fontColor)
106{
107	c.begin();
108	c.setFontSize(fontSize);
109	c.text(w * 0.5, h * 0.7, 0, 0, text, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
110};
111
112mxCellRenderer.registerShape(mxShapeMockupMultiButton.prototype.cst.SHAPE_MULTILINE_BUTTON, mxShapeMockupMultiButton);
113
114//**********************************************************************************************************************************************************
115//Button
116//**********************************************************************************************************************************************************
117/**
118 * Extends mxShape.
119 */
120function mxShapeMockupButton(bounds, fill, stroke, strokewidth)
121{
122	mxShape.call(this);
123	this.bounds = bounds;
124	this.fill = fill;
125	this.stroke = stroke;
126	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
127};
128
129/**
130 * Extends mxShape.
131 */
132mxUtils.extend(mxShapeMockupButton, mxShape);
133
134mxShapeMockupButton.prototype.cst = {
135		MAIN_TEXT : 'mainText',
136		SHAPE_BUTTON : 'mxgraph.mockup.buttons.button',
137		TEXT_COLOR : 'textColor',
138		TEXT_SIZE : 'textSize',
139		BUTTON_STYLE : 'buttonStyle',
140		ROUND : 'round',
141		CHEVRON : 'chevron'
142};
143
144mxShapeMockupButton.prototype.customProperties = [
145	{name: 'buttonStyle', dispName: 'Style', type: 'enum', defVal:'round',
146		enumList: [{val: 'round', dispName: 'Round'}, {val: 'chevron', dispName: 'Chevron'}]
147	}
148];
149
150/**
151 * Function: paintVertexShape
152 *
153 * Paints the vertex shape.
154 */
155mxShapeMockupButton.prototype.paintVertexShape = function(c, x, y, w, h)
156{
157	var mainText = mxUtils.getValue(this.style, mxShapeMockupButton.prototype.cst.MAIN_TEXT, 'Main Text');
158	var fontColor = mxUtils.getValue(this.style, mxShapeMockupButton.prototype.cst.TEXT_COLOR, '#666666').toString();
159	var fontSize = mxUtils.getValue(this.style, mxShapeMockupButton.prototype.cst.TEXT_SIZE, '17').toString();
160	c.translate(x, y);
161	this.background(c, x, y, w, h);
162	c.setShadow(false);
163	this.mainText(c, x, y, w, h, mainText, fontSize, fontColor);
164};
165
166mxShapeMockupButton.prototype.background = function(c, x, y, w, h)
167{
168	var buttonStyle = mxUtils.getValue(this.style, mxShapeMockupButton.prototype.cst.BUTTON_STYLE, mxShapeMockupButton.prototype.cst.ROUND).toString();
169	var rSize = 10;
170	c.begin();
171
172	if (buttonStyle === mxShapeMockupButton.prototype.cst.ROUND)
173	{
174		c.moveTo(0, rSize);
175		c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
176		c.lineTo(w - rSize, 0);
177		c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
178		c.lineTo(w, h - rSize);
179		c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
180		c.lineTo(rSize, h);
181		c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
182	}
183	else if (buttonStyle === mxShapeMockupButton.prototype.cst.CHEVRON)
184	{
185		c.moveTo(0, h * 0.1);
186		c.arcTo(w * 0.0372, h * 0.1111, 0, 0, 1, w * 0.0334, 0);
187		c.lineTo(w * 0.768, 0);
188		c.arcTo(w * 0.0722, h * 0.216, 0, 0, 1, w * 0.8014, h * 0.0399);
189		c.lineTo(w * 0.99, h * 0.4585);
190		c.arcTo(w * 0.09, h * 0.1, 0, 0, 1, w * 0.99, h * 0.5415);
191		c.lineTo(w * 0.8014, h * 0.9568);
192		c.arcTo(w * 0.0722, h * 0.216, 0, 0, 1, w * 0.768, h);
193		c.lineTo(w * 0.0334, h);
194		c.arcTo(w * 0.0372, h * 0.1111, 0, 0, 1, 0, h * 0.9);
195	}
196
197	c.close();
198	c.fillAndStroke();
199};
200
201mxShapeMockupButton.prototype.mainText = function(c, x, y, w, h, text, fontSize, fontColor)
202{
203	c.begin();
204	c.setFontSize(fontSize);
205	c.setFontColor(fontColor);
206	c.setFontStyle(mxConstants.FONT_BOLD);
207	c.text(w / 2, h / 2, 0, 0, text, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
208};
209
210mxCellRenderer.registerShape(mxShapeMockupButton.prototype.cst.SHAPE_BUTTON, mxShapeMockupButton);
211
212//**********************************************************************************************************************************************************
213//Horizontal Button Bar
214//**********************************************************************************************************************************************************
215/**
216 * Extends mxShape.
217 */
218function mxShapeMockupHorButtonBar(bounds, fill, stroke, strokewidth)
219{
220	mxShape.call(this);
221	this.bounds = bounds;
222	this.fill = fill;
223	this.stroke = stroke;
224	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
225};
226
227/**
228 * Extends mxShape.
229 */
230mxUtils.extend(mxShapeMockupHorButtonBar, mxShape);
231
232mxShapeMockupHorButtonBar.prototype.cst = {
233		MAIN_TEXT : 'mainText',
234		SHAPE_HOR_BUTTON_BAR : 'mxgraph.mockup.buttons.horButtonBar',
235		TEXT_COLOR : 'textColor',
236		TEXT_COLOR2 : 'textColor2',
237		STROKE_COLOR2 : 'strokeColor2',
238		FILL_COLOR2 : 'fillColor2',
239		SELECTED : '+',			//must be 1 char
240		TEXT_SIZE : 'textSize'
241};
242
243/**
244 * Function: paintVertexShape
245 *
246 * Paints the vertex shape.
247 */
248mxShapeMockupHorButtonBar.prototype.paintVertexShape = function(c, x, y, w, h)
249{
250	var textStrings = mxUtils.getValue(this.style, mxShapeMockupHorButtonBar.prototype.cst.MAIN_TEXT, '+Button 1, Button 2, Button 3').toString().split(',');
251	var fontColor = mxUtils.getValue(this.style, mxShapeMockupHorButtonBar.prototype.cst.TEXT_COLOR, '#666666');
252	var selectedFontColor = mxUtils.getValue(this.style, mxShapeMockupHorButtonBar.prototype.cst.TEXT_COLOR2, '#ffffff');
253	var fontSize = mxUtils.getValue(this.style, mxShapeMockupHorButtonBar.prototype.cst.TEXT_SIZE, '17').toString();
254	var frameColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#666666');
255	var separatorColor = mxUtils.getValue(this.style, mxShapeMockupHorButtonBar.prototype.cst.STROKE_COLOR2, '#c4c4c4');
256	var bgColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
257	var selectedFillColor = mxUtils.getValue(this.style, mxShapeMockupHorButtonBar.prototype.cst.FILL_COLOR2, '#008cff');
258	var buttonNum = textStrings.length;
259	var buttonWidths = new Array(buttonNum);
260	var buttonTotalWidth = 0;
261	var selectedButton = -1;
262	var rSize = 10; //rounding size
263	var labelOffset = 5;
264
265	for (var i = 0; i < buttonNum; i++)
266	{
267		var buttonText = textStrings[i];
268
269		if(buttonText.charAt(0) === mxShapeMockupHorButtonBar.prototype.cst.SELECTED)
270		{
271			buttonText = textStrings[i].substring(1);
272			selectedButton = i;
273		}
274
275		buttonWidths[i] = mxUtils.getSizeForString(buttonText, fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
276
277		buttonTotalWidth += buttonWidths[i];
278	}
279
280	var trueH = Math.max(h, fontSize * 1.5, 20);
281	var minW = 2 * labelOffset * buttonNum + buttonTotalWidth;
282	var trueW = Math.max(w, minW);
283
284	c.translate(x, y);
285	this.background(c, trueW, trueH, rSize, buttonNum, buttonWidths, labelOffset, minW, frameColor, separatorColor, bgColor, selectedFillColor, selectedButton);
286	c.setShadow(false);
287
288	c.setFontStyle(mxConstants.FONT_BOLD);
289	var currWidth = 0;
290
291	for (var i = 0; i < buttonNum; i++)
292	{
293		if (i === selectedButton)
294		{
295			c.setFontColor(selectedFontColor);
296		}
297		else
298		{
299			c.setFontColor(fontColor);
300		}
301
302		currWidth = currWidth + labelOffset;
303		this.buttonText(c, currWidth, trueH, textStrings[i], buttonWidths[i], fontSize, minW, trueW);
304		currWidth = currWidth + buttonWidths[i] + labelOffset;
305	}
306};
307
308mxShapeMockupHorButtonBar.prototype.background = function(c, w, h, rSize, buttonNum, buttonWidths, labelOffset, minW, frameColor, separatorColor, bgColor, selectedFillColor, selectedButton)
309{
310	c.begin();
311
312	//draw the frame
313	c.setStrokeColor(frameColor);
314	c.setFillColor(bgColor);
315	c.moveTo(0, rSize);
316	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
317	c.lineTo(w - rSize, 0);
318	c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
319	c.lineTo(w, h - rSize);
320	c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
321	c.lineTo(rSize, h);
322	c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
323	c.close();
324	c.fillAndStroke();
325
326	//draw the button separators
327	c.setStrokeColor(separatorColor);
328	c.begin();
329	for (var i = 1; i < buttonNum; i++)
330	{
331		if (i !== selectedButton && i !== (selectedButton + 1))
332		{
333			var currWidth = 0;
334
335			for (var j = 0; j < i; j++)
336			{
337				currWidth += buttonWidths[j] + 2 * labelOffset;
338			}
339
340			currWidth = currWidth * w / minW;
341			c.moveTo(currWidth, 0);
342			c.lineTo(currWidth, h);
343		}
344	}
345
346	c.stroke();
347
348	//draw the selected button
349	var buttonLeft = 0;
350	c.setFillColor(selectedFillColor);
351
352	for (var i = 0; i < selectedButton; i++)
353	{
354		buttonLeft += buttonWidths[i] + 2 * labelOffset;
355	}
356
357	buttonLeft = buttonLeft * w / minW;
358	var buttonRight = (buttonWidths[selectedButton] + 2 * labelOffset) * w / minW;
359	buttonRight += buttonLeft;
360
361	if (selectedButton === 0)
362	{
363		c.begin();
364		// we draw a path for the first button
365		c.moveTo(0, rSize);
366		c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
367		c.lineTo(buttonRight, 0);
368		c.lineTo(buttonRight, h);
369		c.lineTo(rSize, h);
370		c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
371		c.close();
372		c.fill();
373	}
374	else if (selectedButton === buttonNum - 1)
375	{
376		c.begin();
377		// we draw a path for the last button
378		c.moveTo(buttonLeft, 0);
379		c.lineTo(buttonRight - rSize, 0);
380		c.arcTo(rSize, rSize, 0, 0, 1, buttonRight, rSize);
381		c.lineTo(buttonRight, h - rSize);
382		c.arcTo(rSize, rSize, 0, 0, 1, buttonRight - rSize, h);
383		c.lineTo(buttonLeft, h);
384		c.close();
385		c.fill();
386	}
387	else if (selectedButton !== -1)
388	{
389		c.begin();
390		// we draw a path rectangle for one of the buttons in the middle
391		c.moveTo(buttonLeft, 0);
392		c.lineTo(buttonRight, 0);
393		c.lineTo(buttonRight, h);
394		c.lineTo(buttonLeft, h);
395		c.close();
396		c.fill();
397	}
398
399	//draw the frame again, to achieve a nicer effect
400	c.setStrokeColor(frameColor);
401	c.setFillColor(bgColor);
402	c.begin();
403	c.moveTo(0, rSize);
404	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
405	c.lineTo(w - rSize, 0);
406	c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
407	c.lineTo(w, h - rSize);
408	c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
409	c.lineTo(rSize, h);
410	c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
411	c.close();
412	c.stroke();
413};
414
415mxShapeMockupHorButtonBar.prototype.buttonText = function(c, w, h, textString, buttonWidth, fontSize, minW, trueW)
416{
417	if(textString.charAt(0) === mxShapeMockupHorButtonBar.prototype.cst.SELECTED)
418	{
419		textString = textString.substring(1);
420	}
421
422	c.begin();
423	c.setFontSize(fontSize);
424	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);
425};
426
427mxCellRenderer.registerShape(mxShapeMockupHorButtonBar.prototype.cst.SHAPE_HOR_BUTTON_BAR, mxShapeMockupHorButtonBar);
428
429//**********************************************************************************************************************************************************
430//Vertical Button Bar
431//**********************************************************************************************************************************************************
432/**
433 * Extends mxShape.
434 */
435function mxShapeMockupVerButtonBar(bounds, fill, stroke, strokewidth)
436{
437	mxShape.call(this);
438	this.bounds = bounds;
439	this.fill = fill;
440	this.stroke = stroke;
441	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
442};
443
444/**
445 * Extends mxShape.
446 */
447mxUtils.extend(mxShapeMockupVerButtonBar, mxShape);
448
449mxShapeMockupVerButtonBar.prototype.cst = {
450		MAIN_TEXT : 'mainText',
451		SHAPE_VER_BUTTON_BAR : 'mxgraph.mockup.buttons.verButtonBar',
452		TEXT_COLOR : 'textColor',
453		TEXT_COLOR2 : 'textColor2',
454		STROKE_COLOR2 : 'strokeColor2',
455		FILL_COLOR2 : 'fillColor2',
456		SELECTED : '+',			//must be 1 char
457		TEXT_SIZE : 'textSize'
458};
459
460/**
461 * Function: paintVertexShape
462 *
463 * Paints the vertex shape.
464 */
465mxShapeMockupVerButtonBar.prototype.paintVertexShape = function(c, x, y, w, h)
466{
467	var textStrings = mxUtils.getValue(this.style, mxShapeMockupVerButtonBar.prototype.cst.MAIN_TEXT, '+Button 1, Button 2, Button 3').toString().split(',');
468	var fontColor = mxUtils.getValue(this.style, mxShapeMockupVerButtonBar.prototype.cst.TEXT_COLOR, '#666666');
469	var selectedFontColor = mxUtils.getValue(this.style, mxShapeMockupVerButtonBar.prototype.cst.TEXT_COLOR2, '#ffffff');
470	var fontSize = mxUtils.getValue(this.style, mxShapeMockupVerButtonBar.prototype.cst.TEXT_SIZE, '17').toString();
471	var frameColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#666666');
472	var separatorColor = mxUtils.getValue(this.style, mxShapeMockupVerButtonBar.prototype.cst.STROKE_COLOR2, '#c4c4c4');
473	var bgColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#ffffff');
474	var selectedFillColor = mxUtils.getValue(this.style, mxShapeMockupVerButtonBar.prototype.cst.FILL_COLOR2, '#008cff');
475	var buttonNum = textStrings.length;
476	var maxButtonWidth = 0;
477	var selectedButton = -1;
478	var rSize = 10; //rounding size
479	var labelOffset = 5;
480
481	for (var i = 0; i < buttonNum; i++)
482	{
483		var buttonText = textStrings[i];
484
485		if(buttonText.charAt(0) === mxShapeMockupVerButtonBar.prototype.cst.SELECTED)
486		{
487			buttonText = textStrings[i].substring(1);
488			selectedButton = i;
489		}
490
491		var currWidth = mxUtils.getSizeForString(buttonText, fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
492
493		if (currWidth > maxButtonWidth)
494		{
495			maxButtonWidth = currWidth;
496		}
497	}
498
499	var minButtonHeight =  fontSize * 1.5;
500	var minH = buttonNum * minButtonHeight;
501	var trueH = Math.max(h, minH);
502	var minW = 2 * labelOffset + maxButtonWidth;
503	var trueW = Math.max(w, minW);
504
505	c.translate(x, y);
506
507	this.background(c, trueW, trueH, rSize, buttonNum, labelOffset, buttonNum * minButtonHeight, frameColor, separatorColor, bgColor, selectedFillColor, selectedButton, minButtonHeight);
508	c.setShadow(false);
509
510	var currWidth = 0;
511	c.setFontStyle(mxConstants.FONT_BOLD);
512
513	for (var i = 0; i < buttonNum; i++)
514	{
515		if (i === selectedButton)
516		{
517			c.setFontColor(selectedFontColor);
518		}
519		else
520		{
521			c.setFontColor(fontColor);
522		}
523
524		currWidth = currWidth + labelOffset;
525		var currHeight = (i * minButtonHeight + minButtonHeight * 0.5) * trueH / minH;
526		this.buttonText(c, trueW, currHeight, textStrings[i], fontSize);
527	}
528};
529
530mxShapeMockupVerButtonBar.prototype.background = function(c, w, h, rSize, buttonNum, labelOffset, minH, frameColor, separatorColor, bgColor, selectedFillColor, selectedButton, minButtonHeight)
531{
532	c.begin();
533
534	//draw the frame
535	c.setStrokeColor(frameColor);
536	c.setFillColor(bgColor);
537	c.moveTo(0, rSize);
538	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
539	c.lineTo(w - rSize, 0);
540	c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
541	c.lineTo(w, h - rSize);
542	c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
543	c.lineTo(rSize, h);
544	c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
545	c.close();
546	c.fillAndStroke();
547
548	//draw the button separators
549	c.setStrokeColor(separatorColor);
550	c.begin();
551
552	for (var i = 1; i < buttonNum; i++)
553	{
554		if (i !== selectedButton && i !== (selectedButton + 1))
555		{
556			var currHeight = i * minButtonHeight * h / minH;
557
558			c.moveTo(0, currHeight);
559			c.lineTo(w, currHeight);
560		}
561	}
562
563	c.stroke();
564
565	//draw the selected button
566	c.setFillColor(selectedFillColor);
567
568	if (selectedButton === 0)
569	{
570		// we draw a path for the first button
571		c.begin();
572		var buttonBottom = minButtonHeight * h / minH;
573		c.moveTo(0, rSize);
574		c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
575		c.lineTo(w - rSize, 0);
576		c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
577		c.lineTo(w, buttonBottom);
578		c.lineTo(0, buttonBottom);
579		c.close();
580		c.fill();
581	}
582	else if (selectedButton === buttonNum - 1)
583	{
584		// we draw a path for the last button
585		c.begin();
586		var buttonTop = h - minButtonHeight * h / minH;
587		c.moveTo(0, buttonTop);
588		c.lineTo(w, buttonTop);
589		c.lineTo(w, h - rSize);
590		c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
591		c.lineTo(rSize, h);
592		c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
593		c.close();
594		c.fill();
595	}
596	else if (selectedButton !== -1)
597	{
598		// we draw a path rectangle for one of the buttons in the middle
599		c.begin();
600		var buttonTop = minButtonHeight * selectedButton * h / minH;
601		var buttonBottom = minButtonHeight * (selectedButton + 1) * h / minH;
602		c.moveTo(0, buttonTop);
603		c.lineTo(w, buttonTop);
604		c.lineTo(w, buttonBottom);
605		c.lineTo(0, buttonBottom);
606		c.close();
607		c.fill();
608	}
609
610//	//draw the frame again, to achieve a nicer effect
611	c.begin();
612	c.setStrokeColor(frameColor);
613	c.setFillColor(bgColor);
614	c.moveTo(0, rSize);
615	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
616	c.lineTo(w - rSize, 0);
617	c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
618	c.lineTo(w, h - rSize);
619	c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
620	c.lineTo(rSize, h);
621	c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
622	c.close();
623	c.stroke();
624};
625
626mxShapeMockupVerButtonBar.prototype.buttonText = function(c, w, h, textString, fontSize)
627{
628	if(textString.charAt(0) === mxShapeMockupVerButtonBar.prototype.cst.SELECTED)
629	{
630		textString = textString.substring(1);
631	}
632
633	c.begin();
634	c.setFontSize(fontSize);
635	c.text((w * 0.5), h, 0, 0, textString, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
636};
637
638mxCellRenderer.registerShape(mxShapeMockupVerButtonBar.prototype.cst.SHAPE_VER_BUTTON_BAR, mxShapeMockupVerButtonBar);
639
640//**********************************************************************************************************************************************************
641//On-Off Button
642//**********************************************************************************************************************************************************
643/**
644 * Extends mxShape.
645 */
646function mxShapeMockupOnOffButton(bounds, fill, stroke, strokewidth)
647{
648	mxShape.call(this);
649	this.bounds = bounds;
650	this.fill = fill;
651	this.stroke = stroke;
652	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
653};
654
655/**
656 * Extends mxShape.
657 */
658mxUtils.extend(mxShapeMockupOnOffButton, mxShape);
659
660mxShapeMockupOnOffButton.prototype.cst = {
661		SHAPE_ON_OFF_BUTTON : 'mxgraph.mockup.buttons.onOffButton',
662		BUTTON_STATE : 'buttonState',
663		STATE_ON : 'on',
664		STATE_OFF : 'off',
665		FILL_COLOR2 : 'fillColor2',
666		MAIN_TEXT : 'mainText',
667		TEXT_COLOR : 'textColor',
668		TEXT_SIZE : 'textSize'
669};
670
671mxShapeMockupOnOffButton.prototype.customProperties = [
672	{name: 'buttonState', dispName: 'Button State', type: 'enum',
673		enumList: [{val: 'on', dispName: 'On'}, {val: 'off', dispName: 'Off'}]
674	}
675];
676
677/**
678 * Function: paintVertexShape
679 *
680 * Paints the vertex shape.
681 */
682mxShapeMockupOnOffButton.prototype.paintVertexShape = function(c, x, y, w, h)
683{
684	c.translate(x, y);
685	w = Math.max(w, 10);
686	h = Math.max(h, 10);
687
688	this.background(c, x, y, w, h);
689	c.setShadow(false);
690	this.foreground(c, x, y, w, h);
691};
692
693mxShapeMockupOnOffButton.prototype.background = function(c, x, y, w, h)
694{
695	c.roundrect(0, 0, w, h, 10, 10);
696	c.fillAndStroke();
697
698};
699
700mxShapeMockupOnOffButton.prototype.foreground = function(c, x, y, w, h)
701{
702	var state = mxUtils.getValue(this.style, mxShapeMockupOnOffButton.prototype.cst.BUTTON_STATE, mxShapeMockupOnOffButton.prototype.cst.STATE_ON);
703	var fillColor2 = mxUtils.getValue(this.style, mxShapeMockupOnOffButton.prototype.cst.FILL_COLOR2, '#008cff');
704	var textColor = mxUtils.getValue(this.style, mxShapeMockupOnOffButton.prototype.cst.TEXT_COLOR, '#ffffff,#999999').toString().split(',');
705	var mainText = mxUtils.getValue(this.style, mxShapeMockupOnOffButton.prototype.cst.MAIN_TEXT, 'ON,OFF').toString().split(',');
706	var textSize = mxUtils.getValue(this.style, mxShapeMockupOnOffButton.prototype.cst.TEXT_SIZE, '17');
707
708	if (state === mxShapeMockupOnOffButton.prototype.cst.STATE_ON)
709	{
710		c.setFillColor(fillColor2);
711		c.setFontColor(textColor[0]);
712		c.roundrect(0, 0, w * 0.75, h, 10, 10);
713	}
714	else
715	{
716		c.setFontColor(textColor[1]);
717		c.roundrect(w * 0.25, 0, w * 0.75, h, 10, 10);
718	}
719
720	c.fillAndStroke();
721	c.setFontSize(textSize);
722	c.setFontStyle(mxConstants.FONT_BOLD);
723
724	if(state === mxShapeMockupOnOffButton.prototype.cst.STATE_ON)
725	{
726		c.text(w * 0.375, h * 0.5, 0, 0, mainText[0], mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
727	}
728	else if (state === mxShapeMockupOnOffButton.prototype.cst.STATE_OFF)
729	{
730		c.text(w * 0.625, h * 0.5, 0, 0, mainText[1], mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
731	}
732};
733
734mxCellRenderer.registerShape(mxShapeMockupOnOffButton.prototype.cst.SHAPE_ON_OFF_BUTTON, mxShapeMockupOnOffButton);
735
736//**********************************************************************************************************************************************************
737//Rounded rectangle (adjustable rounding)
738//**********************************************************************************************************************************************************
739/**
740* Extends mxShape.
741*/
742function mxShapeMockupRRect(bounds, fill, stroke, strokewidth)
743{
744	mxShape.call(this);
745	this.bounds = bounds;
746	this.fill = fill;
747	this.stroke = stroke;
748	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
749};
750
751/**
752* Extends mxShape.
753*/
754mxUtils.extend(mxShapeMockupRRect, mxShape);
755
756mxShapeMockupRRect.prototype.cst = {
757		RRECT : 'mxgraph.mockup.rrect',
758		R_SIZE : 'rSize'
759};
760
761mxShapeMockupRRect.prototype.customProperties = [
762	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10}
763];
764
765/**
766* Function: paintVertexShape
767*
768* Paints the vertex shape.
769*/
770mxShapeMockupRRect.prototype.paintVertexShape = function(c, x, y, w, h)
771{
772	c.translate(x, y);
773
774	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeMockupRRect.prototype.cst.R_SIZE, '10'));
775	c.roundrect(0, 0, w, h, rSize);
776	c.fillAndStroke();
777};
778
779mxCellRenderer.registerShape(mxShapeMockupRRect.prototype.cst.RRECT, mxShapeMockupRRect);
780
781//**********************************************************************************************************************************************************
782//Anchor (a dummy shape without visuals used for anchoring)
783//**********************************************************************************************************************************************************
784/**
785* Extends mxShape.
786*/
787function mxShapeMockupAnchor(bounds, fill, stroke, strokewidth)
788{
789	mxShape.call(this);
790	this.bounds = bounds;
791};
792
793/**
794* Extends mxShape.
795*/
796mxUtils.extend(mxShapeMockupAnchor, mxShape);
797
798mxShapeMockupAnchor.prototype.cst = {
799		ANCHOR : 'mxgraph.mockup.anchor'
800};
801
802mxShapeMockupAnchor.prototype.customProperties = [
803	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10}
804];
805
806/**
807* Function: paintVertexShape
808*
809* Paints the vertex shape.
810*/
811mxShapeMockupAnchor.prototype.paintVertexShape = function(c, x, y, w, h)
812{
813};
814
815mxCellRenderer.registerShape(mxShapeMockupAnchor.prototype.cst.ANCHOR, mxShapeMockupAnchor);
816
817//**********************************************************************************************************************************************************
818//Top Button
819//**********************************************************************************************************************************************************
820/**
821* Extends mxShape.
822*/
823function mxShapeMockupTopButton(bounds, fill, stroke, strokewidth)
824{
825	mxShape.call(this);
826	this.bounds = bounds;
827	this.fill = fill;
828	this.stroke = stroke;
829	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
830};
831
832/**
833* Extends mxShape.
834*/
835mxUtils.extend(mxShapeMockupTopButton, mxShape);
836
837mxShapeMockupTopButton.prototype.cst = {
838		TOP_BUTTON : 'mxgraph.mockup.topButton',
839		R_SIZE : 'rSize'
840};
841
842mxShapeMockupTopButton.prototype.customProperties = [
843	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10}
844];
845
846/**
847* Function: paintVertexShape
848*
849* Paints the vertex shape.
850*/
851mxShapeMockupTopButton.prototype.paintVertexShape = function(c, x, y, w, h)
852{
853	c.translate(x, y);
854
855	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeMockupTopButton.prototype.cst.R_SIZE, '10'));
856
857	c.begin();
858	c.moveTo(0, rSize);
859	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
860	c.lineTo(w - rSize, 0);
861	c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
862	c.lineTo(w, h);
863	c.lineTo(0, h);
864	c.close();
865	c.fillAndStroke();
866};
867
868mxCellRenderer.registerShape(mxShapeMockupTopButton.prototype.cst.TOP_BUTTON, mxShapeMockupTopButton);
869
870//**********************************************************************************************************************************************************
871//Bottom Button
872//**********************************************************************************************************************************************************
873/**
874* Extends mxShape.
875*/
876function mxShapeMockupBottomButton(bounds, fill, stroke, strokewidth)
877{
878	mxShape.call(this);
879	this.bounds = bounds;
880	this.fill = fill;
881	this.stroke = stroke;
882	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
883};
884
885/**
886* Extends mxShape.
887*/
888mxUtils.extend(mxShapeMockupBottomButton, mxShape);
889
890mxShapeMockupBottomButton.prototype.cst = {
891		BOTTOM_BUTTON : 'mxgraph.mockup.bottomButton',
892		R_SIZE : 'rSize'
893};
894
895mxShapeMockupBottomButton.prototype.customProperties = [
896	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10}
897];
898
899/**
900* Function: paintVertexShape
901*
902* Paints the vertex shape.
903*/
904mxShapeMockupBottomButton.prototype.paintVertexShape = function(c, x, y, w, h)
905{
906	c.translate(x, y);
907
908	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeMockupBottomButton.prototype.cst.R_SIZE, '10'));
909
910	c.begin();
911	c.moveTo(0, 0);
912	c.lineTo(w, 0);
913	c.lineTo(w, h - rSize);
914	c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
915	c.lineTo(rSize, h);
916	c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
917	c.close();
918	c.fillAndStroke();
919};
920
921mxCellRenderer.registerShape(mxShapeMockupBottomButton.prototype.cst.BOTTOM_BUTTON, mxShapeMockupBottomButton);
922
923//**********************************************************************************************************************************************************
924//Right Button
925//**********************************************************************************************************************************************************
926/**
927* Extends mxShape.
928*/
929function mxShapeMockupRightButton(bounds, fill, stroke, strokewidth)
930{
931	mxShape.call(this);
932	this.bounds = bounds;
933	this.fill = fill;
934	this.stroke = stroke;
935	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
936};
937
938/**
939* Extends mxShape.
940*/
941mxUtils.extend(mxShapeMockupRightButton, mxShape);
942
943mxShapeMockupRightButton.prototype.cst = {
944		RIGHT_BUTTON : 'mxgraph.mockup.rightButton',
945		R_SIZE : 'rSize'
946};
947
948mxShapeMockupRightButton.prototype.customProperties = [
949	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10}
950];
951
952/**
953* Function: paintVertexShape
954*
955* Paints the vertex shape.
956*/
957mxShapeMockupRightButton.prototype.paintVertexShape = function(c, x, y, w, h)
958{
959	c.translate(x, y);
960
961	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeMockupRightButton.prototype.cst.R_SIZE, '10'));
962
963	c.begin();
964	c.moveTo(0, 0);
965	c.lineTo(w - rSize, 0);
966	c.arcTo(rSize, rSize, 0, 0, 1, w, rSize);
967	c.lineTo(w, h - rSize);
968	c.arcTo(rSize, rSize, 0, 0, 1, w - rSize, h);
969	c.lineTo(0, h);
970	c.close();
971	c.fillAndStroke();
972};
973
974mxCellRenderer.registerShape(mxShapeMockupRightButton.prototype.cst.RIGHT_BUTTON, mxShapeMockupRightButton);
975
976//**********************************************************************************************************************************************************
977//Left Button
978//**********************************************************************************************************************************************************
979/**
980* Extends mxShape.
981*/
982function mxShapeMockupLeftButton(bounds, fill, stroke, strokewidth)
983{
984	mxShape.call(this);
985	this.bounds = bounds;
986	this.fill = fill;
987	this.stroke = stroke;
988	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
989};
990
991/**
992* Extends mxShape.
993*/
994mxUtils.extend(mxShapeMockupLeftButton, mxShape);
995
996mxShapeMockupLeftButton.prototype.cst = {
997		LEFT_BUTTON : 'mxgraph.mockup.leftButton',
998		R_SIZE : 'rSize'
999};
1000
1001mxShapeMockupLeftButton.prototype.customProperties = [
1002	{name: 'rSize', dispName: 'Arc Size', type: 'float', min:0, defVal:10}
1003];
1004
1005/**
1006* Function: paintVertexShape
1007*
1008* Paints the vertex shape.
1009*/
1010mxShapeMockupLeftButton.prototype.paintVertexShape = function(c, x, y, w, h)
1011{
1012	c.translate(x, y);
1013
1014	var rSize = parseInt(mxUtils.getValue(this.style, mxShapeMockupLeftButton.prototype.cst.R_SIZE, '10'));
1015
1016	c.begin();
1017	c.moveTo(w, 0);
1018	c.lineTo(w, h);
1019	c.lineTo(rSize, h);
1020	c.arcTo(rSize, rSize, 0, 0, 1, 0, h - rSize);
1021	c.lineTo(0, rSize);
1022	c.arcTo(rSize, rSize, 0, 0, 1, rSize, 0);
1023	c.close();
1024	c.fillAndStroke();
1025};
1026
1027mxCellRenderer.registerShape(mxShapeMockupLeftButton.prototype.cst.LEFT_BUTTON, mxShapeMockupLeftButton);
1028
1029