1/**
2 * $Id: mxMockupNavigation.js,v 1.5 2014/01/21 13:11:15 gaudenz Exp $
3 * Copyright (c) 2006-2010, JGraph Ltd
4 */
5
6//**********************************************************************************************************************************************************
7//Breadcrumb (LEGACY)
8//**********************************************************************************************************************************************************
9/**
10 * Extends mxShape.
11 */
12function mxShapeMockupBreadcrumb(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(mxShapeMockupBreadcrumb, mxShape);
25
26mxShapeMockupBreadcrumb.prototype.cst = {
27		SHAPE_BREADCRUMB : 'mxgraph.mockup.navigation.breadcrumb',
28		MAIN_TEXT : 'mainText',
29		TEXT_SIZE : 'textSize',
30		TEXT_COLOR : 'textColor',
31		TEXT_COLOR2 : 'textColor2'
32};
33
34/**
35 * Function: paintVertexShape
36 *
37 * Paints the vertex shape.
38 */
39mxShapeMockupBreadcrumb.prototype.paintVertexShape = function(c, x, y, w, h)
40{
41	var textStrings = mxUtils.getValue(this.style, mxShapeMockupBreadcrumb.prototype.cst.MAIN_TEXT, 'Layer 1, Layer 2, Layer 3').toString().split(',');
42	var fontColor = mxUtils.getValue(this.style, mxShapeMockupBreadcrumb.prototype.cst.TEXT_COLOR, '#666666');
43	var selectedFontColor = mxUtils.getValue(this.style, mxShapeMockupBreadcrumb.prototype.cst.TEXT_COLOR2, '#008cff');
44	var fontSize = mxUtils.getValue(this.style, mxShapeMockupBreadcrumb.prototype.cst.TEXT_SIZE, '17').toString();
45	var separatorColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#c4c4c4');
46	var buttonNum = textStrings.length;
47	var buttonWidths = new Array(buttonNum);
48	var buttonTotalWidth = 0;
49	var labelOffset = 10;
50
51	for (var i = 0; i < buttonNum; i++)
52	{
53		buttonWidths[i] = mxUtils.getSizeForString(textStrings[i], fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
54		buttonTotalWidth += buttonWidths[i];
55	}
56
57	var trueH = Math.max(h, fontSize * 1.5, 20);
58	var minW = 2 * labelOffset * buttonNum + buttonTotalWidth;
59	var trueW = Math.max(w, minW);
60	c.translate(x, y);
61	c.setShadow(false);
62
63	this.separators(c, trueW, trueH, buttonNum, buttonWidths, labelOffset, minW, separatorColor);
64	var currWidth = 0;
65
66	for (var i = 0; i < buttonNum; i++)
67	{
68		if (i + 1 === buttonNum)
69		{
70			c.setFontColor(selectedFontColor);
71		}
72		else
73		{
74			c.setFontColor(fontColor);
75		}
76
77		currWidth = currWidth + labelOffset;
78		this.buttonText(c, currWidth, trueH, textStrings[i], buttonWidths[i], fontSize, minW, trueW);
79		currWidth = currWidth + buttonWidths[i] + labelOffset;
80	}
81};
82
83mxShapeMockupBreadcrumb.prototype.separators = function(c, w, h, buttonNum, buttonWidths, labelOffset, minW, separatorColor)
84{
85	//draw the button separators
86	c.setStrokeColor(separatorColor);
87	var midY = h * 0.5;
88	var size = 5;
89	c.begin();
90
91	for (var i = 1; i < buttonNum; i++)
92	{
93		var currWidth = 0;
94
95		for (var j = 0; j < i; j++)
96		{
97			currWidth += buttonWidths[j] + 2 * labelOffset;
98		}
99
100		currWidth = currWidth * w / minW;
101		c.moveTo(currWidth - size * 0.5, midY - size);
102		c.lineTo(currWidth + size * 0.5, midY);
103		c.lineTo(currWidth - size * 0.5, midY + size);
104	}
105	c.stroke();
106};
107
108mxShapeMockupBreadcrumb.prototype.buttonText = function(c, w, h, textString, buttonWidth, fontSize, minW, trueW)
109{
110	c.begin();
111	c.setFontSize(fontSize);
112	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);
113};
114
115mxCellRenderer.registerShape(mxShapeMockupBreadcrumb.prototype.cst.SHAPE_BREADCRUMB, mxShapeMockupBreadcrumb);
116
117//**********************************************************************************************************************************************************
118//Step Bar
119//**********************************************************************************************************************************************************
120/**
121 * Extends mxShape.
122 */
123function mxShapeMockupStepBar(bounds, fill, stroke, strokewidth)
124{
125	mxShape.call(this);
126	this.bounds = bounds;
127	this.fill = fill;
128	this.stroke = stroke;
129	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
130};
131
132/**
133 * Extends mxShape.
134 */
135mxUtils.extend(mxShapeMockupStepBar, mxShape);
136
137mxShapeMockupStepBar.prototype.cst = {
138		SHAPE_STEP_BAR : 'mxgraph.mockup.navigation.stepBar',
139		SELECTED : '+',			//must be 1 char
140		MAIN_TEXT : 'mainText',
141		TEXT_SIZE : 'textSize',
142		TEXT_COLOR : 'textColor',
143		TEXT_COLOR2 : 'textColor2'
144};
145
146mxShapeMockupStepBar.prototype.customProperties = [
147	{name: 'mainText', dispName: 'Text', type: 'string'},
148	{name: 'textSize', dispName: 'Text Size', type: 'float'},
149	{name: 'textColor', dispName: 'Text Color', type: 'color'},
150	{name: 'textColor2', dispName: 'Text2 Color', type: 'color'}
151];
152
153/**
154 * Function: paintVertexShape
155 *
156 * Paints the vertex shape.
157 */
158mxShapeMockupStepBar.prototype.paintVertexShape = function(c, x, y, w, h)
159{
160	var textStrings = mxUtils.getValue(this.style, mxShapeMockupStepBar.prototype.cst.MAIN_TEXT, 'Step 1, Step 2, Step 3').toString().split(',');
161	var fontColor = mxUtils.getValue(this.style, mxShapeMockupStepBar.prototype.cst.TEXT_COLOR, '#666666');
162	var currColor = mxUtils.getValue(this.style, mxShapeMockupStepBar.prototype.cst.TEXT_COLOR2, '#008cff');
163	var fontSize = mxUtils.getValue(this.style, mxShapeMockupStepBar.prototype.cst.TEXT_SIZE, '17').toString();
164	var bgColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#c4c4c4');
165	var doneColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#666666');
166	var buttonNum = textStrings.length;
167	var buttonWidths = new Array(buttonNum);
168	var buttonTotalWidth = 0;
169	var labelOffset = 10;
170	var selectedButton = -1;
171
172	for (var i = 0; i < buttonNum; i++)
173	{
174		var buttonText = textStrings[i];
175
176		if(buttonText.charAt(0) === mxShapeMockupStepBar.prototype.cst.SELECTED)
177		{
178			buttonText = textStrings[i].substring(1);
179			selectedButton = i;
180		}
181
182		buttonWidths[i] = mxUtils.getSizeForString(buttonText, fontSize, mxConstants.DEFAULT_FONTFAMILY).width;
183
184		buttonTotalWidth += buttonWidths[i];
185	}
186
187	var trueH = Math.max(h, fontSize * 1.5, 20);
188	var minW = 2 * labelOffset * buttonNum + buttonTotalWidth;
189	var trueW = Math.max(w, minW);
190	c.translate(x, y);
191
192	this.stepLineBg(c, trueW, trueH, buttonNum, buttonWidths, labelOffset, minW, bgColor, fontSize, trueW);
193	c.setShadow(false);
194
195	this.stepLineFg(c, trueW, trueH, buttonNum, buttonWidths, labelOffset, minW, bgColor, doneColor, currColor, fontSize, trueW, selectedButton);
196	var currWidth = 0;
197
198	for (var i = 0; i < buttonNum; i++)
199	{
200		if (i >= selectedButton)
201		{
202			c.setFontColor(currColor);
203		}
204		else
205		{
206			c.setFontColor(fontColor);
207		}
208
209		currWidth = currWidth + labelOffset;
210		this.buttonText(c, currWidth, trueH, textStrings[i], buttonWidths[i], fontSize, minW, trueW);
211		currWidth = currWidth + buttonWidths[i] + labelOffset;
212	}
213};
214
215mxShapeMockupStepBar.prototype.stepLineBg = function(c, w, h, buttonNum, buttonWidths, labelOffset, minW, bgColor, fontSize, trueW)
216{
217	//draw the button separators
218	c.setStrokeColor(bgColor);
219	c.setFillColor(bgColor);
220	var midY = fontSize * 2;
221	var size = 10;
222	var startX = 0;
223	var endX = 0;
224
225	for (var i = 0; i < buttonNum; i++)
226	{
227		var currWidth = 0;
228
229		for (var j = 0; j < i; j++)
230		{
231			currWidth += buttonWidths[j] + 2 * labelOffset;
232		}
233
234		currWidth += buttonWidths[i] * 0.5 + labelOffset;
235
236		currWidth = currWidth * w / minW;
237
238		if (i === 0)
239		{
240			startX = currWidth;
241		}
242		else if (i + 1 === buttonNum)
243		{
244			endX = currWidth;
245		}
246
247		c.begin();
248		c.ellipse(currWidth - size, midY - size, 2 * size, 2 * size);
249		c.fillAndStroke();
250	}
251
252	c.begin();
253	c.rect(startX, midY - size * 0.2, endX - startX, size * 0.4);
254	c.fillAndStroke();
255};
256
257mxShapeMockupStepBar.prototype.stepLineFg = function(c, w, h, buttonNum, buttonWidths, labelOffset, minW, bgColor, doneColor, currColor, fontSize, trueW, selectedButton)
258{
259	//draw the button separators
260	c.setStrokeColor(doneColor);
261	var midY = fontSize * 2;
262	var size = 10 * 0.75;
263	var startX = 0;
264	var endX = 0;
265	var strokeWidth = mxUtils.getValue(this.style, mxConstants.STYLE_STROKEWIDTH, '1');
266
267	for (var i = 0; i <= selectedButton; i++)
268	{
269		var currWidth = 0;
270
271		for (var j = 0; j < i; j++)
272		{
273			currWidth += buttonWidths[j] + 2 * labelOffset;
274		}
275
276		currWidth += buttonWidths[i] * 0.5 + labelOffset;
277
278		currWidth = currWidth * w / minW;
279
280		if (i === 0)
281		{
282			startX = currWidth;
283		}
284		else if (i === selectedButton)
285		{
286			endX = currWidth;
287		}
288	}
289
290	c.setFillColor(doneColor);
291	c.begin();
292	c.rect(startX, midY - size * 0.15, endX - startX, size * 0.3);
293	c.fill();
294	c.setFillColor(bgColor);
295
296	for (var i = 0; i <= selectedButton; i++)
297	{
298		var currWidth = 0;
299
300		for (var j = 0; j < i; j++)
301		{
302			currWidth += buttonWidths[j] + 2 * labelOffset;
303		}
304
305		currWidth += buttonWidths[i] * 0.5 + labelOffset;
306
307		currWidth = currWidth * w / minW;
308
309		if (i === 0)
310		{
311			startX = currWidth;
312		}
313		else if (i + 1 === selectedButton)
314		{
315			endX = currWidth;
316		}
317
318		if (i < selectedButton)
319		{
320			c.setStrokeWidth(strokeWidth);
321			c.begin();
322			c.ellipse(currWidth - size, midY - size, 2 * size, 2 * size);
323			c.fillAndStroke();
324
325			c.setStrokeWidth(strokeWidth * 0.5);
326			c.begin();
327			c.ellipse(currWidth - size * 0.6, midY - size * 0.6, 2 * size * 0.6, 2 * size * 0.6);
328			c.fillAndStroke();
329		}
330		else
331		{
332			c.setStrokeWidth(strokeWidth);
333			c.setFillColor(bgColor);
334			c.setStrokeColor(bgColor);
335			c.begin();
336			c.ellipse(currWidth - size / 0.75, midY - size / 0.75, 2 * size / 0.75, 2 * size / 0.75);
337			c.fillAndStroke();
338
339			c.setStrokeWidth(strokeWidth);
340			c.setFillColor('#ffffff');
341			c.setStrokeColor('#ffffff');
342			c.begin();
343			c.ellipse(currWidth - size, midY - size, 2 * size, 2 * size);
344			c.fillAndStroke();
345
346			c.setFillColor(currColor);
347			c.setStrokeColor(currColor);
348			c.setStrokeWidth(strokeWidth * 0.5);
349			c.begin();
350			c.ellipse(currWidth - size * 0.7, midY - size * 0.7, 2 * size * 0.7, 2 * size * 0.7);
351			c.fillAndStroke();
352		}
353	}
354};
355
356mxShapeMockupStepBar.prototype.buttonText = function(c, w, h, textString, buttonWidth, fontSize, minW, trueW)
357{
358	if(textString.charAt(0) === mxShapeMockupStepBar.prototype.cst.SELECTED)
359	{
360		textString = textString.substring(1);
361	}
362
363	c.begin();
364	c.setFontSize(fontSize);
365	c.text((w + buttonWidth * 0.5) * trueW / minW, fontSize * 0.5, 0, 0, textString, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
366};
367
368mxCellRenderer.registerShape(mxShapeMockupStepBar.prototype.cst.SHAPE_STEP_BAR, mxShapeMockupStepBar);
369
370//**********************************************************************************************************************************************************
371//Cover Flow
372//**********************************************************************************************************************************************************
373/**
374* Extends mxShape.
375*/
376function mxShapeMockupCoverFlow(bounds, fill, stroke, strokewidth)
377{
378	mxShape.call(this);
379	this.bounds = bounds;
380	this.fill = fill;
381	this.stroke = stroke;
382	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
383};
384
385/**
386* Extends mxShape.
387*/
388mxUtils.extend(mxShapeMockupCoverFlow, mxShape);
389
390mxShapeMockupCoverFlow.prototype.cst = {
391		SHAPE_COVER_FLOW : 'mxgraph.mockup.navigation.coverFlow'
392};
393
394/**
395* Function: paintVertexShape
396*
397* Paints the vertex shape.
398*/
399mxShapeMockupCoverFlow.prototype.paintVertexShape = function(c, x, y, w, h)
400{
401	c.translate(x, y);
402
403	c.begin();
404	c.moveTo(w * 0.0924, h * 0.07);
405	c.lineTo(w * 0.005, h * 0.01);
406	c.lineTo(w * 0.005, h * 0.99);
407	c.lineTo(w * 0.0924, h * 0.93);
408
409	c.moveTo(w * 0.1774, h * 0.09);
410	c.lineTo(w * 0.0924, h * 0.01);
411	c.lineTo(w * 0.0924, h * 0.99);
412	c.lineTo(w * 0.1774, h * 0.91);
413
414	c.moveTo(w * 0.3373, h * 0.22);
415	c.lineTo(w * 0.1774, h * 0.01);
416	c.lineTo(w * 0.1774, h * 0.99);
417	c.lineTo(w * 0.3373, h * 0.78);
418
419	c.moveTo(w * 0.912, h * 0.07);
420	c.lineTo(w * 0.998, h * 0.01);
421	c.lineTo(w * 0.998, h * 0.99);
422	c.lineTo(w * 0.912, h * 0.93);
423
424	c.moveTo(w * 0.8271, h * 0.09);
425	c.lineTo(w * 0.912, h * 0.01);
426	c.lineTo(w * 0.912, h * 0.99);
427	c.lineTo(w * 0.8271, h * 0.91);
428
429	c.moveTo(w * 0.6672, h * 0.22);
430	c.lineTo(w * 0.8271, h * 0.01);
431	c.lineTo(w * 0.8271, h * 0.99);
432	c.lineTo(w * 0.6672, h * 0.78);
433
434	c.moveTo(w * 0.3373, h * 0.005);
435	c.lineTo(w * 0.3373, h * 0.995);
436	c.lineTo(w * 0.6672, h * 0.995);
437	c.lineTo(w * 0.6672, h * 0.005);
438	c.close();
439	c.fillAndStroke();
440};
441
442mxCellRenderer.registerShape(mxShapeMockupCoverFlow.prototype.cst.SHAPE_COVER_FLOW, mxShapeMockupCoverFlow);
443
444//**********************************************************************************************************************************************************
445//Scroll Bar
446//**********************************************************************************************************************************************************
447/**
448* Extends mxShape.
449*/
450function mxShapeMockupScrollBar(bounds, fill, stroke, strokewidth)
451{
452	mxShape.call(this);
453	this.bounds = bounds;
454	this.fill = fill;
455	this.stroke = stroke;
456	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
457};
458
459/**
460* Extends mxShape.
461*/
462mxUtils.extend(mxShapeMockupScrollBar, mxShape);
463
464mxShapeMockupScrollBar.prototype.cst = {
465		SHAPE_SCROLL_BAR : 'mxgraph.mockup.navigation.scrollBar',
466		FILL_COLOR2 : 'fillColor2',
467		STROKE_COLOR2 : 'strokeColor2',
468		BAR_POS : 'barPos'
469};
470
471mxShapeMockupScrollBar.prototype.customProperties = [
472	{name: 'barPos', dispName: 'Handle Position', type: 'float'},
473	{name: 'fillColor2', dispName: 'Fill2 Color', type: 'color'},
474	{name: 'strokeColor2', dispName: 'Stroke2 Color', type: 'color'}
475];
476
477/**
478* Function: paintVertexShape
479*
480* Paints the vertex shape.
481*/
482mxShapeMockupScrollBar.prototype.paintVertexShape = function(c, x, y, w, h)
483{
484	h = 20;
485	var buttonX = 20;
486	w = Math.max(w, 2 * buttonX);
487
488	c.translate(x, y);
489	this.background(c, w, h, buttonX);
490	c.setShadow(false);
491	this.foreground(c, w, h, buttonX);
492	this.barPos = 20;
493};
494
495mxShapeMockupScrollBar.prototype.background = function(c, w, h, buttonX)
496{
497	c.rect(0, 0, w, h);
498	c.fillAndStroke();
499	c.begin();
500	c.moveTo(buttonX, 0);
501	c.lineTo(buttonX, h);
502	c.moveTo(w - buttonX, 0);
503	c.lineTo(w - buttonX, h);
504	c.stroke();
505}
506
507mxShapeMockupScrollBar.prototype.foreground = function(c, w, h, buttonX)
508{
509	var barPos = mxUtils.getValue(this.style, mxShapeMockupScrollBar.prototype.cst.BAR_POS, '20');
510	var fillColor2 = mxUtils.getValue(this.style, mxShapeMockupScrollBar.prototype.cst.FILL_COLOR2, '#99ddff');
511	var strokeColor2 = mxUtils.getValue(this.style, mxShapeMockupScrollBar.prototype.cst.STROKE_COLOR2, 'none');
512
513	barPos = Math.max(0, barPos);
514	barPos = Math.min(100, barPos);
515
516	c.setStrokeColor(strokeColor2);
517	c.setFillColor(fillColor2);
518
519	c.begin();
520	c.moveTo(buttonX * 0.2, h * 0.5);
521	c.lineTo(buttonX * 0.8, h * 0.2);
522	c.lineTo(buttonX * 0.8, h * 0.8);
523	c.close();
524	c.moveTo(w - buttonX * 0.2, h * 0.5);
525	c.lineTo(w - buttonX * 0.8, h * 0.2);
526	c.lineTo(w - buttonX * 0.8, h * 0.8);
527	c.close();
528	c.fillAndStroke();
529
530	//draw the handle based on arg.barPos
531	var barWidth = 60;
532	var barMin = buttonX;
533	var barMax = w - buttonX;
534	barWidth = Math.min(barWidth, barMax - barMin);
535	var barCenterMin = barMin + barWidth / 2;
536	var barCenterMax = barMax - barWidth / 2;
537	var barCenterRange = barCenterMax - barCenterMin;
538	var barCenterPos = barCenterRange * barPos / 100;
539	var barStart = barMin + barCenterPos;
540
541	c.roundrect(barStart, h * 0.15, barWidth, h * 0.7, 5, 5);
542	c.fillAndStroke();
543};
544
545mxCellRenderer.registerShape(mxShapeMockupScrollBar.prototype.cst.SHAPE_SCROLL_BAR, mxShapeMockupScrollBar);
546
547Graph.handleFactory[mxShapeMockupScrollBar.prototype.cst.SHAPE_SCROLL_BAR] = function(state)
548{
549	var handles = [Graph.createHandle(state, ['barPos'], function(bounds)
550			{
551				var barPos = Math.max(0, Math.min(100, parseFloat(mxUtils.getValue(this.state.style, 'barPos', this.barPos))));
552
553				return new mxPoint(bounds.x + ((bounds.width - 100) * barPos / bounds.width) / 100 * bounds.width + 50, bounds.y + 10);
554			}, function(bounds, pt)
555			{
556				this.state.style['barPos'] = Math.round(1000 * Math.max(0, Math.min(100, (pt.x - bounds.x - 50) * 100 / (bounds.width - 100)))) / 1000;
557			})];
558
559	return handles;
560}
561
562//**********************************************************************************************************************************************************
563//Pagination
564//**********************************************************************************************************************************************************
565/**
566* Extends mxShape.
567*/
568function mxShapeMockupPagination(bounds, fill, stroke, strokewidth)
569{
570	mxShape.call(this);
571	this.bounds = bounds;
572	this.fill = fill;
573	this.stroke = stroke;
574	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
575};
576
577/**
578* Extends mxShape.
579*/
580mxUtils.extend(mxShapeMockupPagination, mxShape);
581
582mxShapeMockupPagination.prototype.cst = {
583		MAIN_TEXT : 'linkText',
584		TEXT_SIZE : 'textSize',
585		TEXT_COLOR : 'textColor',
586		SHAPE_PAGINATION : 'mxgraph.mockup.navigation.pagination'
587};
588
589/**
590* Function: paintVertexShape
591*
592* Paints the vertex shape.
593*/
594mxShapeMockupPagination.prototype.paintVertexShape = function(c, x, y, w, h)
595{
596	var mainText = mxUtils.getValue(this.style, mxShapeMockupPagination.prototype.cst.MAIN_TEXT, '0-9 A B C D E F G H I J K L M N O P Q R S T U V X Y Z');
597	var textSize = mxUtils.getValue(this.style, mxShapeMockupPagination.prototype.cst.TEXT_SIZE, '17');
598	var textColor = mxUtils.getValue(this.style, mxShapeMockupPagination.prototype.cst.TEXT_COLOR, '#0000ff');
599
600	c.translate(x, y);
601	var width = mxUtils.getSizeForString(mainText, textSize, mxConstants.DEFAULT_FONTFAMILY).width;
602	c.setStrokeColor(textColor);
603	c.setFontSize(textSize);
604	c.setFontColor(textColor);
605	c.text(w * 0.5, h * 0.5, 0, 0, mainText, mxConstants.ALIGN_CENTER, mxConstants.ALIGN_MIDDLE, 0, null, 0, 0, 0);
606	c.begin();
607	c.moveTo(w * 0.5 - width * 0.5, (h + parseInt(textSize, 10)) * 0.5);
608	c.lineTo(w * 0.5 + width * 0.5, (h + parseInt(textSize, 10)) * 0.5);
609	c.stroke();
610};
611
612mxCellRenderer.registerShape(mxShapeMockupPagination.prototype.cst.SHAPE_PAGINATION, mxShapeMockupPagination);
613
614//**********************************************************************************************************************************************************
615//Page Control
616//**********************************************************************************************************************************************************
617/**
618* Extends mxShape.
619*/
620function mxShapeMockupPageControl(bounds, fill, stroke, strokewidth)
621{
622	mxShape.call(this);
623	this.bounds = bounds;
624	this.fill = fill;
625	this.stroke = stroke;
626	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
627};
628
629/**
630* Extends mxShape.
631*/
632mxUtils.extend(mxShapeMockupPageControl, mxShape);
633
634mxShapeMockupPageControl.prototype.cst = {
635		SHAPE_PAGE_CONTROL : 'mxgraph.mockup.navigation.pageControl'
636};
637
638/**
639* Function: paintVertexShape
640*
641* Paints the vertex shape.
642*/
643mxShapeMockupPageControl.prototype.paintVertexShape = function(c, x, y, w, h)
644{
645	c.translate(x, y);
646
647
648	var fillColor = mxUtils.getValue(this.style, mxConstants.STYLE_FILLCOLOR, '#000000');
649	var strokeColor = mxUtils.getValue(this.style, mxConstants.STYLE_STROKECOLOR, '#000000');
650
651	var rSize = Math.min(h * 0.5, w * 0.05);
652	c.setFillColor(strokeColor);
653	c.ellipse(0, h * 0.5 - rSize, 2 * rSize, 2 * rSize);
654	c.fill();
655	c.setFillColor(fillColor);
656	c.ellipse(w * 0.35 - rSize, h * 0.5 - rSize, 2 * rSize, 2 * rSize);
657	c.fill();
658	c.ellipse(w * 0.65 - rSize, h * 0.5 - rSize, 2 * rSize, 2 * rSize);
659	c.fill();
660	c.ellipse(w - 2 * rSize, h * 0.5 - rSize, 2 * rSize, 2 * rSize);
661	c.fill();
662};
663
664mxCellRenderer.registerShape(mxShapeMockupPageControl.prototype.cst.SHAPE_PAGE_CONTROL, mxShapeMockupPageControl);
665
666//**********************************************************************************************************************************************************
667//Map Navigator
668//**********************************************************************************************************************************************************
669/**
670* Extends mxShape.
671*/
672function mxShapeMockupMapNavigator(bounds, fill, stroke, strokewidth)
673{
674	mxShape.call(this);
675	this.bounds = bounds;
676	this.fill = fill;
677	this.stroke = stroke;
678	this.strokewidth = (strokewidth != null) ? strokewidth : 1;
679};
680
681/**
682* Extends mxShape.
683*/
684mxUtils.extend(mxShapeMockupMapNavigator, mxShape);
685
686mxShapeMockupMapNavigator.prototype.cst = {
687		SHAPE_MAP_NAVIGATOR : 'mxgraph.mockup.navigation.mapNavigator',
688		FILL_COLOR2 : 'fillColor2',
689		STROKE_COLOR2 : 'strokeColor2',
690		STROKE_COLOR3 : 'strokeColor3'
691};
692
693mxShapeMockupMapNavigator.prototype.customProperties = [
694	{name: 'fillColor2', dispName: 'Fill2 Color', type: 'color'},
695	{name: 'strokeColor2', dispName: 'Stroke2 Color', type: 'color'},
696	{name: 'strokeColor3', dispName: 'Stroke3 Color', type: 'color'}
697];
698
699/**
700* Function: paintVertexShape
701*
702* Paints the vertex shape.
703*/
704mxShapeMockupMapNavigator.prototype.paintVertexShape = function(c, x, y, w, h)
705{
706	c.translate(x, y);
707	this.background(c, w, h);
708	c.setShadow(false);
709	this.foreground(c, w, h);
710};
711
712mxShapeMockupMapNavigator.prototype.background = function(c, w, h)
713{
714	c.ellipse(0, 0, w, h * 0.6);
715	c.fillAndStroke();
716
717	c.begin();
718	c.moveTo(w * 0.35, h * 0.584);
719	c.lineTo(w * 0.35, h * 0.95);
720	c.arcTo(w * 0.083, h * 0.05, 0, 0, 0, w * 0.43, h);
721	c.lineTo(w * 0.56, h);
722	c.arcTo(w * 0.083, h * 0.05, 0, 0, 0, w * 0.65, h * 0.95);
723	c.lineTo(w * 0.65, h * 0.584);
724	c.fillAndStroke();
725}
726
727mxShapeMockupMapNavigator.prototype.foreground = function(c, w, h)
728{
729	var fillColor2 = mxUtils.getValue(this.style, mxShapeMockupMapNavigator.prototype.cst.FILL_COLOR2, '#99ddff');
730	var strokeColor2 = mxUtils.getValue(this.style, mxShapeMockupMapNavigator.prototype.cst.STROKE_COLOR2, 'none');
731	var strokeColor3 = mxUtils.getValue(this.style, mxShapeMockupMapNavigator.prototype.cst.STROKE_COLOR3, '#ffffff');
732
733	c.setFillColor(fillColor2);
734	c.setStrokeColor(strokeColor2);
735	c.ellipse(w * 0.4, h * 0.65, w * 0.2, h * 0.12);
736	c.fillAndStroke();
737	c.ellipse(w * 0.4, h * 0.85, w * 0.2, h * 0.12);
738	c.fillAndStroke();
739
740	c.begin();
741	c.moveTo(w * 0.1806, h * 0.34);
742	c.lineTo(w * 0.1357, h * 0.366);
743	c.lineTo(w * 0.0228, h * 0.3);
744	c.lineTo(w * 0.1357, h * 0.234);
745	c.lineTo(w * 0.1806, h * 0.26);
746	c.lineTo(w * 0.1142, h * 0.3);
747	c.close();
748	c.fillAndStroke();
749
750	c.begin();
751	c.moveTo(w * 0.433, h * 0.108);
752	c.lineTo(w * 0.3881, h * 0.08);
753	c.lineTo(w * 0.4994, h * 0.012);
754	c.lineTo(w * 0.6123, h * 0.08);
755	c.lineTo(w * 0.5658, h * 0.108);
756	c.lineTo(w * 0.4994, h * 0.068);
757	c.close();
758	c.fillAndStroke();
759
760	c.begin();
761	c.moveTo(w * 0.8198, h * 0.262);
762	c.lineTo(w * 0.868, h * 0.233);
763	c.lineTo(w * 0.9776, h * 0.3);
764	c.lineTo(w * 0.868, h * 0.367);
765	c.lineTo(w * 0.8198, h * 0.341);
766	c.lineTo(w * 0.8863, h * 0.3);
767	c.close();
768	c.fillAndStroke();
769
770	c.begin();
771	c.moveTo(w * 0.5641, h * 0.493);
772	c.lineTo(w * 0.6123, h * 0.522);
773	c.lineTo(w * 0.4994, h * 0.588);
774	c.lineTo(w * 0.3881, h * 0.521);
775	c.lineTo(w * 0.4363, h * 0.493);
776	c.lineTo(w * 0.4994, h * 0.533);
777	c.close();
778	c.fillAndStroke();
779
780	c.begin();
781	c.moveTo(w * 0.3333, h * 0.32);
782	c.lineTo(w * 0.3333, h * 0.28);
783	c.lineTo(w * 0.4163, h * 0.3);
784	c.close();
785	c.moveTo(w * 0.4662, h * 0.2);
786	c.lineTo(w * 0.5326, h * 0.2);
787	c.lineTo(w * 0.4994, h * 0.25);
788	c.close()
789	c.moveTo(w * 0.6654, h * 0.28);
790	c.lineTo(w * 0.6654, h * 0.32);
791	c.lineTo(w * 0.5824, h * 0.3);
792	c.close();
793	c.moveTo(w * 0.5326, h * 0.4);
794	c.lineTo(w * 0.4662, h * 0.4);
795	c.lineTo(w * 0.4994, h * 0.35);
796	c.close();
797	c.fillAndStroke();
798
799	c.setStrokeWidth(2);
800	c.setStrokeColor(strokeColor3);
801
802	c.begin();
803	c.moveTo(w * 0.5, h * 0.67);
804	c.lineTo(w * 0.5, h * 0.75);
805	c.moveTo(w * 0.43, h * 0.71);
806	c.lineTo(w * 0.57, h * 0.71);
807	c.moveTo(w * 0.43, h * 0.91);
808	c.lineTo(w * 0.57, h * 0.91);
809	c.stroke();
810};
811
812mxCellRenderer.registerShape(mxShapeMockupMapNavigator.prototype.cst.SHAPE_MAP_NAVIGATOR, mxShapeMockupMapNavigator);
813
814//**********************************************************************************************************************************************************
815//Anchor (a dummy shape without visuals used for anchoring)
816//**********************************************************************************************************************************************************
817/**
818* Extends mxShape.
819*/
820function mxShapeMockupNavigationAnchor(bounds, fill, stroke, strokewidth)
821{
822	mxShape.call(this);
823	this.bounds = bounds;
824};
825
826/**
827* Extends mxShape.
828*/
829mxUtils.extend(mxShapeMockupNavigationAnchor, mxShape);
830
831mxShapeMockupNavigationAnchor.prototype.cst = {
832		ANCHOR : 'mxgraph.mockup.navigation.anchor'
833};
834
835/**
836* Function: paintVertexShape
837*
838* Paints the vertex shape.
839*/
840mxShapeMockupNavigationAnchor.prototype.paintVertexShape = function(c, x, y, w, h)
841{
842};
843
844mxCellRenderer.registerShape(mxShapeMockupNavigationAnchor.prototype.cst.ANCHOR, mxShapeMockupNavigationAnchor);
845
846