├── Demos ├── StyleExplorer │ ├── BlueMarble.jpg │ ├── StyleExplorer.html │ └── StyleExplorer_min.js └── TetriStack │ ├── Sounds │ ├── 109662__grunz__success.mp3 │ ├── 187024__lloydevans09__jump2.mp3 │ ├── 320777__rhodesmas__action-01.mp3 │ ├── 37732__longhairman__1khz-1ds-peep.mp3 │ ├── 382931__frankum__vintage-techno-house-loop-110bpm.mp3 │ └── SOUNDLICENSE │ ├── TetriStack.html │ └── TetriStack_min.js ├── LICENSE ├── README.md ├── dist ├── FlexCanvasJS.js └── FlexCanvasJS_min.js ├── docs ├── AddedRemovedEvent.html ├── AlertElement.html ├── AnchorContainerElement.html ├── ArrowShape.html ├── ButtonElement.html ├── CanvasElement.html ├── CanvasManager.html ├── CheckboxElement.html ├── CheckboxSkinElement.html ├── CollectionChangedEvent.html ├── CollectionSort.html ├── ColorPickerButtonElement.html ├── ColorPickerElement.html ├── ContainerBaseElement.html ├── CursorDefinition.html ├── DataGridColumnDefinition.html ├── DataGridDataRenderer.html ├── DataGridElement.html ├── DataGridHeaderColumnDividerSkinElement.html ├── DataGridHeaderElement.html ├── DataGridHeaderItemRenderer.html ├── DataGridItemData.html ├── DataGridItemRendererBase.html ├── DataGridLabelItemRenderer.html ├── DataListData.html ├── DataListElement.html ├── DataRendererBaseElement.html ├── DataRendererLabelElement.html ├── DatePickerButtonElement.html ├── DatePickerElement.html ├── DispatcherEvent.html ├── DrawMetrics.html ├── DropdownArrowButtonSkinElement.html ├── DropdownBaseElement.html ├── DropdownElement.html ├── ElementEvent.html ├── ElementGridItemClickEvent.html ├── ElementKeyboardEvent.html ├── ElementListItemClickEvent.html ├── ElementMouseEvent.html ├── ElementMouseWheelEvent.html ├── EllipseShape.html ├── EventDispatcher.html ├── FillBase.html ├── GridContainerElement.html ├── GridContainerRowColumnDefinition.html ├── ImageElement.html ├── IpInputElement.html ├── LabelElement.html ├── LinearGradientFill.html ├── ListCollection.html ├── ListContainerElement.html ├── ProgressElement.html ├── RadioButtonElement.html ├── RadioButtonSkinElement.html ├── RoundedRectangleShape.html ├── ScrollBarElement.html ├── ScrollButtonSkinElement.html ├── ShapeBase.html ├── SkinnableElement.html ├── SolidFill.html ├── StyleChangedEvent.html ├── StyleData.html ├── StyleDefinition.html ├── StyleProxy.html ├── StyleableBase.html ├── TextAreaElement.html ├── TextElement.html ├── TextFieldElement.html ├── TextInputElement.html ├── TimeInputElement.html ├── ToggleButtonElement.html ├── ToggleButtonGroup.html ├── Tween.html └── ViewportElement.html └── src ├── Demos ├── StyleExplorer │ ├── Application │ │ ├── AddStyleDataRenderer.js │ │ ├── CloseButtonSkinElement.js │ │ ├── ControlStyleType.js │ │ ├── StyleExplorerApplication.js │ │ ├── StyleExplorerMain.js │ │ ├── StyleItemRenderer.js │ │ └── StyleListRenderer.js │ ├── BlueMarble.jpg │ └── StyleExplorer.html └── TetriStack │ ├── Application │ ├── CCAttributeLinks.js │ ├── TetriAudioSelectSettings.js │ ├── TetriBlock.js │ ├── TetriPlayField.js │ ├── TetriStackApplication.js │ └── TetriStackMain.js │ ├── Sounds │ ├── 109662__grunz__success.mp3 │ ├── 187024__lloydevans09__jump2.mp3 │ ├── 320777__rhodesmas__action-01.mp3 │ ├── 37732__longhairman__1khz-1ds-peep.mp3 │ ├── 382931__frankum__vintage-techno-house-loop-110bpm.mp3 │ └── SOUNDLICENSE │ └── TetriStack.html ├── FlexCanvasJS ├── AlertElement.js ├── ButtonElement.js ├── CanvasElement.js ├── CanvasManager.js ├── CheckboxElement.js ├── CollectionSort.js ├── ColorPickerButtonElement.js ├── ColorPickerElement.js ├── CursorDefinition.js ├── DatePickerButtonElement.js ├── DatePickerElement.js ├── DrawMetrics.js ├── DropdownBaseElement.js ├── DropdownElement.js ├── EventDispatcher.js ├── ImageElement.js ├── IpInputElement.js ├── LabelElement.js ├── ListCollection.js ├── ProgressElement.js ├── RadioButtonElement.js ├── ScrollBarElement.js ├── SkinnableElement.js ├── StyleDefinition.js ├── StyleProxy.js ├── StyleableBase.js ├── TextAreaElement.js ├── TextElement.js ├── TextFieldElement.js ├── TextInputElement.js ├── TimeInputElement.js ├── ToggleButtonElement.js ├── ToggleButtonGroup.js ├── Tween.js ├── containers │ ├── AnchorContainerElement.js │ ├── ContainerBaseElement.js │ ├── GridContainerElement.js │ ├── GridContainerRowColumnDefinition.js │ ├── ListContainerElement.js │ └── ViewportElement.js ├── dataContainers │ ├── DataGridColumnDefinition.js │ ├── DataGridDataRenderer.js │ ├── DataGridElement.js │ ├── DataGridHeaderElement.js │ ├── DataGridHeaderItemRenderer.js │ ├── DataGridItemData.js │ ├── DataGridItemRendererBase.js │ ├── DataGridLabelItemRenderer.js │ ├── DataListData.js │ ├── DataListElement.js │ ├── DataRendererBaseElement.js │ └── DataRendererLabelElement.js ├── events │ ├── AddedRemovedEvent.js │ ├── CollectionChangedEvent.js │ ├── DispatcherEvent.js │ ├── ElementEvent.js │ ├── ElementGridItemClickEvent.js │ ├── ElementKeyboardEvent.js │ ├── ElementListItemClickEvent.js │ ├── ElementMouseEvent.js │ ├── ElementMouseWheelEvent.js │ └── StyleChangedEvent.js ├── fills │ ├── FillBase.js │ ├── LinearGradientFill.js │ └── SolidFill.js ├── shapes │ ├── ArrowShape.js │ ├── EllipseShape.js │ ├── RoundedRectangleShape.js │ └── ShapeBase.js └── skins │ ├── CheckboxSkinElement.js │ ├── DataGridHeaderColumnDividerSkinElement.js │ ├── DropdownArrowButtonSkinElement.js │ ├── RadioButtonSkinElement.js │ └── ScrollButtonSkinElement.js ├── TestPad.html └── TestPadJS.js /Demos/StyleExplorer/BlueMarble.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensormaticFirmware/FlexCanvasJS/537b9a841f23e1748b18f8a3a60ea0caecfb3c20/Demos/StyleExplorer/BlueMarble.jpg -------------------------------------------------------------------------------- /Demos/StyleExplorer/StyleExplorer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FlexCanvasJS Style Explorer 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Demos/TetriStack/Sounds/109662__grunz__success.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensormaticFirmware/FlexCanvasJS/537b9a841f23e1748b18f8a3a60ea0caecfb3c20/Demos/TetriStack/Sounds/109662__grunz__success.mp3 -------------------------------------------------------------------------------- /Demos/TetriStack/Sounds/187024__lloydevans09__jump2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensormaticFirmware/FlexCanvasJS/537b9a841f23e1748b18f8a3a60ea0caecfb3c20/Demos/TetriStack/Sounds/187024__lloydevans09__jump2.mp3 -------------------------------------------------------------------------------- /Demos/TetriStack/Sounds/320777__rhodesmas__action-01.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensormaticFirmware/FlexCanvasJS/537b9a841f23e1748b18f8a3a60ea0caecfb3c20/Demos/TetriStack/Sounds/320777__rhodesmas__action-01.mp3 -------------------------------------------------------------------------------- /Demos/TetriStack/Sounds/37732__longhairman__1khz-1ds-peep.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensormaticFirmware/FlexCanvasJS/537b9a841f23e1748b18f8a3a60ea0caecfb3c20/Demos/TetriStack/Sounds/37732__longhairman__1khz-1ds-peep.mp3 -------------------------------------------------------------------------------- /Demos/TetriStack/Sounds/382931__frankum__vintage-techno-house-loop-110bpm.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensormaticFirmware/FlexCanvasJS/537b9a841f23e1748b18f8a3a60ea0caecfb3c20/Demos/TetriStack/Sounds/382931__frankum__vintage-techno-house-loop-110bpm.mp3 -------------------------------------------------------------------------------- /Demos/TetriStack/Sounds/SOUNDLICENSE: -------------------------------------------------------------------------------- 1 | 2 | 109662__grunz__success 3 | https://freesound.org/people/grunz/sounds/109662/ 4 | 5 | grunz 6 | https://freesound.org/people/grunz/ 7 | 8 | CC BY 3.0 9 | https://creativecommons.org/licenses/by/3.0/ 10 | 11 | ----------------------------------- 12 | 13 | 187024_lloydevans09_jump2 14 | https://freesound.org/people/LloydEvans09/sounds/187024/ 15 | 16 | LloydEvans09 17 | https://freesound.org/people/LloydEvans09/ 18 | 19 | CC BY 3.0 20 | https://creativecommons.org/licenses/by/3.0/ 21 | 22 | ----------------------------------- 23 | 24 | 37732_longhairman_1khz-1ds-peep 25 | https://freesound.org/people/Longhairman/sounds/37732/ 26 | 27 | Longhairman 28 | https://freesound.org/people/Longhairman/ 29 | 30 | CC0 1.0 31 | https://creativecommons.org/publicdomain/zero/1.0/ 32 | 33 | ------------------------------------ 34 | 35 | 382931__frankum__vintage-techno-house-loop-110bpm 36 | https://freesound.org/people/frankum/sounds/382931/ 37 | 38 | frankum 39 | https://freesound.org/people/frankum/ 40 | 41 | CC BY 3.0 42 | https://creativecommons.org/licenses/by/3.0/ 43 | 44 | ------------------------------------ 45 | 46 | 320777__rhodesmas__action-01 47 | https://freesound.org/people/rhodesmas/sounds/320777/ 48 | 49 | rhodesmas 50 | https://freesound.org/people/rhodesmas/ 51 | 52 | CC BY 3.0 53 | https://creativecommons.org/licenses/by/3.0/ 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Demos/TetriStack/TetriStack.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | TetriStack 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-2019 SENSORMATIC ELECTRONICS LLC, NATHAN E NELSON 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FlexCanvasJS 2 | 3 | #### RIA Web Application Framework for HTML5 Canvas #### 4 | 5 | Easily create rich internet applications using the HTML5 canvas. 6 | 7 | FlexCanvasJS provides highly customizable user interactive canvas display elements, hierarchical parent / child display list, UI events, styling and skinning, relative and dynamic layouts, automatic redraw regions, and includes many UI controls such as buttons, checkboxes, dropdowns, datagrids, color pickers, date pickers, editable and wrapping text controls, and more, while also allowing easy creation of custom components or controls. 8 | 9 | Most typical UI events including capture and bubbling phases are supported including but not limited to mouse, keyboard, focus, rollover, etc... 10 | 11 | Complex scalable layouts are easily achieved by nesting container elements. Data driven containers such as DataList and DataGrid allow displaying very large data sets while only rendering what is visible on screen to maintain excellent performance and will bind too and automatically update as their associated data collection changes. 12 | 13 | A robust styling and skinning system is provided allowing you to easily modify and customize the appearance and behaviour of any UI control. 14 | 15 | FlexCanvasJS does the heavy lifting for you. Render caching, redraw regions, composite layers and effects are all automatic, for good performance even in the most complex, animated, and heavily layered applications and games. 16 | 17 | ### Getting Started ### 18 | 19 | All you need is the minified FlexCanvasJS library and a HTML canvas. 20 | Download the minified library from the latest release. 21 | 22 | Example below is using a full screen canvas, although any canvas will work. 23 | 24 | ```html 25 | 26 | 27 | 28 | 29 | FlexCanvasJS Web Application 30 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | ``` 41 | Now attach the DOM canvas to the FlexCanvasJS CanvasManager and create and style our elements: 42 | 43 | ```javascript 44 | //Create elements 45 | var canvasManager = new CanvasManager(); 46 | var colorPicker = new ColorPickerElement(); 47 | 48 | function init() 49 | { 50 | //Attach the DOM canvas to our CanvasManager 51 | canvasManager.setCanvas(document.getElementById("flexCanvasApplication")); 52 | 53 | //Set up our color picker - add style definitions, event listeners, etc. 54 | colorPicker.setStyle("X", 50); 55 | colorPicker.setStyle("Y", 50); 56 | 57 | //Add colorPicker to CanvasManager 58 | canvasManager.addElement(colorPicker); 59 | } 60 | ``` 61 | -------------------------------------------------------------------------------- /src/Demos/StyleExplorer/Application/AddStyleDataRenderer.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | //DataRenderer used to render the add style drop down list items. 4 | //We're toggling some styles depending on if we're rendering a header 5 | //or a style item. Also adding a horizontal divider line (visible when 6 | //we're a header) and a checkbox (visible when we're a style item). 7 | 8 | //A DataRenderer is any element that implements _setListData(). Any 9 | //element can be a DataRenderer. We're using DataRendererLabelElement 10 | //because it already implements a label, and up, alt, over, selected 11 | //skin states. 12 | 13 | function AddStyleDataRenderer() //extends DataRendererLabelElement 14 | { 15 | AddStyleDataRenderer.base.prototype.constructor.call(this); 16 | 17 | ////Add children 18 | 19 | //Used only for header 20 | this._divider = new CanvasElement(); 21 | this._divider.setStyle("BackgroundFill", "#000000"); 22 | 23 | //Used only for selectable style 24 | this._checkboxSelected = new CheckboxElement(); 25 | 26 | //Add both and we'll just toggle visibility based on state. 27 | this._addChild(this._divider); 28 | this._addChild(this._checkboxSelected); 29 | 30 | 31 | ////Event handling 32 | var _self = this; 33 | 34 | //Private handler, need function for each instance, proxy to prototype. 35 | this._onAddStyleDataRendererClickInstance = 36 | function (event) 37 | { 38 | _self._onAddStyleDataRendererClick(event); 39 | }; 40 | 41 | this.addEventListener("click", this._onAddStyleDataRendererClickInstance); 42 | } 43 | 44 | //Inherit from DataRendererLabelElement 45 | AddStyleDataRenderer.prototype = Object.create(DataRendererLabelElement.prototype); 46 | AddStyleDataRenderer.prototype.constructor = AddStyleDataRenderer; 47 | AddStyleDataRenderer.base = DataRendererLabelElement; 48 | 49 | AddStyleDataRenderer.prototype._onAddStyleDataRendererClick = 50 | function (event) 51 | { 52 | //The popup DataList selection is disabled via styling (Selectable = "false"), 53 | //so we need to close it ourself. 54 | 55 | //Close the dropdown unless we clicked the checkbox itself and exclude headers. 56 | if (event.getTarget() != this._checkboxSelected && this._itemData.styleName != "") 57 | this._listData._parentList._owner.close(true); 58 | }; 59 | 60 | //@override - DataList sets our associated row / collection data. 61 | AddStyleDataRenderer.prototype._setListData = 62 | function (listData, itemData) 63 | { 64 | AddStyleDataRenderer.base.prototype._setListData.call(this, listData, itemData); 65 | 66 | ////Adjust our state based on list supplied data//// 67 | 68 | if (this._itemData.styleName == "") //Header 69 | { 70 | this.setStyle("PaddingTop", 2); 71 | this.setStyle("PaddingBottom", 1); 72 | this.setStyle("PaddingLeft", 4); 73 | this.setStyle("PaddingRight", 10); 74 | this.setStyle("TextStyle", "bold"); 75 | this.setStyle("Selectable", false); 76 | this._divider.setStyle("Visible", true); 77 | this._checkboxSelected.setStyle("Visible", false); 78 | } 79 | else //Selectable style 80 | { 81 | this.setStyle("PaddingTop", 4); 82 | this.setStyle("PaddingBottom", 4); 83 | this.setStyle("PaddingLeft", 14); 84 | this.setStyle("PaddingRight", 10); 85 | this.setStyle("TextStyle", "normal"); 86 | this.setStyle("Selectable", true); 87 | this._divider.setStyle("Visible", false); 88 | this._checkboxSelected.setStyle("Visible", true); 89 | 90 | //Style is defined 91 | if (this._itemData.styleName in this._itemData.styleDefinition._styleMap) 92 | this._checkboxSelected.setSelected(true); 93 | else //Style not defined 94 | this._checkboxSelected.setSelected(false); 95 | } 96 | }; 97 | 98 | //@override 99 | AddStyleDataRenderer.prototype._doLayout = 100 | function (paddingMetrics) 101 | { 102 | AddStyleDataRenderer.base.prototype._doLayout.call(this, paddingMetrics); 103 | 104 | //Convienence 105 | var x = paddingMetrics.getX(); 106 | var y = paddingMetrics.getY(); 107 | var w = paddingMetrics.getWidth(); 108 | var h = paddingMetrics.getHeight(); 109 | 110 | ////Size and position child elements//////////// 111 | 112 | this._divider._setActualPosition(x, this._height - 1); 113 | this._divider._setActualSize(w, 1); 114 | 115 | this._checkboxSelected._setActualSize(this._labelElement._height, this._labelElement._height); 116 | this._checkboxSelected._setActualPosition(x + w - this._checkboxSelected._width, Math.round(y + (h / 2) - (this._checkboxSelected._height / 2))); 117 | }; 118 | 119 | 120 | -------------------------------------------------------------------------------- /src/Demos/StyleExplorer/Application/CloseButtonSkinElement.js: -------------------------------------------------------------------------------- 1 | 2 | //Basic skin class. Used for the remove style button. 3 | //Draws an X across the button. 4 | 5 | function CloseButtonSkinElement() //extends CanvasElement 6 | { 7 | CloseButtonSkinElement.base.prototype.constructor.call(this); 8 | } 9 | 10 | //Inherit from CanvasElement 11 | CloseButtonSkinElement.prototype = Object.create(CanvasElement.prototype); 12 | CloseButtonSkinElement.prototype.constructor = CloseButtonSkinElement; 13 | CloseButtonSkinElement.base = CanvasElement; 14 | 15 | 16 | /////////Internal Functions//////////////////////// 17 | 18 | //@override 19 | CloseButtonSkinElement.prototype._doRender = 20 | function() 21 | { 22 | //Base renders our background & border based on our state. 23 | CloseButtonSkinElement.base.prototype._doRender.call(this); 24 | 25 | //Get the CanvasRenderingContext2D context for this element. 26 | var ctx = this._getGraphicsCtx(); 27 | 28 | //Convienence 29 | var x = this._x; 30 | var y = this._y; 31 | var w = this._width; 32 | var h = this._height; 33 | 34 | //Draw an "X" across the button. 35 | //This is not done in a scalable, or style-able manner, its just for our specific button. 36 | var state = this.getStyle("SkinState"); 37 | var color = null; 38 | 39 | if (state == "up") 40 | color = "#444444"; 41 | else if (state = "over") 42 | color = "#222222"; 43 | else //down 44 | color = "#000000"; 45 | 46 | ctx.beginPath(); 47 | 48 | ctx.moveTo(x + 4.5, y + 4.5); 49 | ctx.lineTo(x + w - 4.5, y + h - 4.5); 50 | ctx.moveTo(x + w - 4.5, y + 4.5); 51 | ctx.lineTo(x + 4.5, y + h - 4.5); 52 | 53 | ctx.strokeStyle = color; 54 | ctx.lineWidth = 2; 55 | ctx.stroke(); 56 | }; 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/Demos/StyleExplorer/Application/StyleExplorerMain.js: -------------------------------------------------------------------------------- 1 | 2 | //////STRINGS///////////////////// 3 | 4 | var localeStrings = Object.create(null); 5 | 6 | //all///////// 7 | localeStrings["all"] = Object.create(null); 8 | localeStrings["all"]["FlexCanvasJS"] = "FlexCanvasJS"; 9 | localeStrings["all"]["Style Explorer"] = "Style Explorer"; 10 | 11 | 12 | //en-us//////// 13 | localeStrings["en-us"] = Object.create(null); 14 | localeStrings["en-us"]["Language"] = "Language"; 15 | localeStrings["en-us"]["Powered By"] = "Powered By"; 16 | localeStrings["en-us"]["Select Control"] = "Select Control"; 17 | localeStrings["en-us"]["Select Styles"] = "Select Styles"; 18 | localeStrings["en-us"]["Sandbox"] = "Sandbox"; 19 | localeStrings["en-us"]["Add"] = "Add"; 20 | localeStrings["en-us"]["Styles"] = "Styles"; 21 | localeStrings["en-us"]["Style Code"] = "Style Code"; 22 | localeStrings["en-us"]["Copy"] = "Copy"; 23 | localeStrings["en-us"]["Text Size"] = "Text Size"; 24 | 25 | 26 | //es-es//////// 27 | localeStrings["es-es"] = Object.create(null); 28 | localeStrings["es-es"]["Language"] = "Idioma"; 29 | localeStrings["es-es"]["Powered By"] = "Desarrollado Por"; 30 | localeStrings["es-es"]["Select Control"] = "Seleccionar Control"; 31 | localeStrings["es-es"]["Select Styles"] = "Seleccionar Estilos"; 32 | localeStrings["es-es"]["Sandbox"] = "Salvadera"; 33 | localeStrings["es-es"]["Add"] = "Añadir"; 34 | localeStrings["es-es"]["Styles"] = "Estilos"; 35 | localeStrings["es-es"]["Style Code"] = "Código De Estilo"; 36 | localeStrings["es-es"]["Copy"] = "Copiar"; 37 | localeStrings["es-es"]["Text Size"] = "Tamano Del Texto"; 38 | 39 | 40 | //////IMAGES/////////////////////// 41 | 42 | //ImageElement loads image from URL when added to display. 43 | var urlImgBlueMarble = "BlueMarble.jpg"; 44 | 45 | //Pre-load images (good for skins) 46 | //var imgBlueMarble = new Image(); 47 | //imgBlueMarble.src = "BlueMarble.jpg"; 48 | 49 | 50 | //////STYLES////////////////////// 51 | 52 | var canvasManagerStyle = new StyleDefinition(); 53 | //canvasManagerStyle.setStyle("BackgroundFill", "#CCDD99"); 54 | canvasManagerStyle.setStyle("BackgroundFill", "#D9C7A6"); 55 | 56 | var applicationContainerStyle = new StyleDefinition(); 57 | applicationContainerStyle.setStyle("PaddingTop", 4); 58 | applicationContainerStyle.setStyle("PaddingLeft", 4); 59 | applicationContainerStyle.setStyle("PaddingRight", 4); 60 | applicationContainerStyle.setStyle("PaddingBottom", 2); 61 | applicationContainerStyle.setStyle("LayoutGap", 6); 62 | applicationContainerStyle.setStyle("MinHeight", 500); 63 | 64 | var textTitleStyle = new StyleDefinition(); 65 | textTitleStyle.setStyle("TextSize", 32); 66 | textTitleStyle.setStyle("TextFont", "Roboto"); 67 | 68 | var panelBackgroundShape = new RoundedRectangleShape(); 69 | panelBackgroundShape.setStyle("CornerRadius", 6); 70 | 71 | var panelBackgroundStyle = new StyleDefinition(); 72 | panelBackgroundStyle.setStyle("BackgroundFill", "#FFFFFF"); 73 | panelBackgroundStyle.setStyle("BackgroundShape", panelBackgroundShape); 74 | panelBackgroundStyle.setStyle("Alpha", .35); 75 | panelBackgroundStyle.setStyle("PercentWidth", 100); 76 | panelBackgroundStyle.setStyle("PercentHeight", 100); 77 | 78 | var panelInnerContainerStyle = new StyleDefinition(); 79 | panelInnerContainerStyle.setStyle("Padding", 6); 80 | panelInnerContainerStyle.setStyle("PercentWidth", 100); 81 | panelInnerContainerStyle.setStyle("PercentHeight", 100); 82 | 83 | var hDividerLineStyle = new StyleDefinition(); 84 | hDividerLineStyle.setStyle("Height", 1); 85 | hDividerLineStyle.setStyle("PercentWidth", 100); 86 | hDividerLineStyle.setStyle("BackgroundFill", "#999999"); 87 | 88 | 89 | //////Clear Style Button 90 | var clearStyleButtonStyle = new StyleDefinition(); 91 | 92 | //Skin styles 93 | var clearStyleButtonUpSkinStyleDef = new StyleDefinition(); 94 | clearStyleButtonUpSkinStyleDef.setStyle("BackgroundFill", "#FF7777"); 95 | 96 | var clearStyleButtonOverSkinStyleDef = new StyleDefinition(); 97 | clearStyleButtonOverSkinStyleDef.setStyle("BackgroundFill", "#EE5555"); 98 | 99 | var clearStyleButtonDownSkinStyleDef = new StyleDefinition(); 100 | clearStyleButtonDownSkinStyleDef.setStyle("BackgroundFill", "#DD3333"); 101 | 102 | clearStyleButtonStyle.setStyle("UpSkinStyle", clearStyleButtonUpSkinStyleDef); 103 | clearStyleButtonStyle.setStyle("OverSkinStyle", clearStyleButtonOverSkinStyleDef); 104 | clearStyleButtonStyle.setStyle("DownSkinStyle", clearStyleButtonDownSkinStyleDef); 105 | clearStyleButtonStyle.setStyle("SkinClass", CloseButtonSkinElement); //Draws an "X" across the button. 106 | clearStyleButtonStyle.setStyle("Width", 15); 107 | clearStyleButtonStyle.setStyle("Height", 15); 108 | clearStyleButtonStyle.setStyle("BackgroundShape", new EllipseShape()); 109 | 110 | 111 | //////Add Style Dropdown 112 | var addStyleDropdownListStyle = new StyleDefinition(); 113 | addStyleDropdownListStyle.setStyle("ListItemClass", AddStyleDataRenderer); //Custom item renderer (renders row in dropdown list) 114 | addStyleDropdownListStyle.setStyle("Selectable", false); //Disable the list's normal selection mechanism 115 | 116 | var addStyleDropdownStyle = new StyleDefinition(); 117 | addStyleDropdownStyle.setStyle("PopupDataListStyle", addStyleDropdownListStyle); 118 | 119 | ////Font size buttons 120 | var fontSizeButtonStyle = new StyleDefinition(); 121 | fontSizeButtonStyle.setStyle("SkinClass", ScrollButtonSkinElement); 122 | fontSizeButtonStyle.setStyle("Width", 14); 123 | fontSizeButtonStyle.setStyle("PercentHeight", 100); 124 | 125 | ////Style editing viewport 126 | var stylesControlViewportVScrollbarStyle = new StyleDefinition(); 127 | stylesControlViewportVScrollbarStyle.setStyle("PaddingLeft", 4); 128 | 129 | var stylesControlViewportStyle = new StyleDefinition(); 130 | stylesControlViewportStyle.setStyle("VerticalScrollBarStyle", stylesControlViewportVScrollbarStyle); 131 | stylesControlViewportStyle.setStyle("MinWidth", 450); 132 | stylesControlViewportStyle.setStyle("MeasureContentWidth", true); //Allow horizontal expansion 133 | 134 | 135 | 136 | //////APPLICATION//////////////// 137 | 138 | //Globals go here...// 139 | 140 | //Root application 141 | var styleExplorer = null; //Best not to initialize here, avoid file ordering dependencies. 142 | 143 | //Run application 144 | function init() 145 | { 146 | //Initialize globals 147 | styleExplorer = new StyleExplorerApplication(); 148 | styleExplorer.setCanvas(document.getElementById("canvasStyleExplorer")); 149 | } 150 | 151 | -------------------------------------------------------------------------------- /src/Demos/StyleExplorer/Application/StyleListRenderer.js: -------------------------------------------------------------------------------- 1 | 2 | //Renders an Add Style dropdown and a list of StyleItemRenderer(s). 3 | 4 | function StyleListRenderer() //extends ListContainer 5 | { 6 | StyleListRenderer.base.prototype.constructor.call(this); 7 | 8 | ////Layout 9 | this.setStyle("LayoutGap", 4); 10 | this.setStyle("PercentWidth", 100); 11 | 12 | this._dropdownAdd = new DropdownElement(); 13 | this._dropdownAdd.setStyle("PercentWidth", 100); 14 | this._dropdownAdd.setStyle("ItemLabelFunction", StyleListRenderer.addStyleDropdownLabelFunction); 15 | this._dropdownAdd.setStyleDefinitions(addStyleDropdownStyle); 16 | 17 | this.addElement(this._dropdownAdd); 18 | 19 | 20 | ////Event handlers 21 | var _self = this; 22 | 23 | //Private event handlers, proxy to prototype. 24 | this._onLocaleChangedInstance = 25 | function (event) 26 | { 27 | _self._onLocaleChanged(event); 28 | }; 29 | this._onDropdownAddListItemClickInstance = 30 | function (event) 31 | { 32 | _self._onDropdownAddListItemClick(event); 33 | }; 34 | this._onItemRendererClearedInstance = 35 | function (event) 36 | { 37 | _self._onItemRendererCleared(event); 38 | }; 39 | 40 | this.addEventListener("localechanged", this._onLocaleChangedInstance); 41 | 42 | //Manually handling the dropdown listitemclick, because we're disabling the list's normal selection mechanism via styling. 43 | this._dropdownAdd.addEventListener("listitemclick", this._onDropdownAddListItemClickInstance); 44 | 45 | 46 | ////Functional 47 | this._styleControlType = null; 48 | } 49 | 50 | //Inherit from ListContainer 51 | StyleListRenderer.prototype = Object.create(ListContainerElement.prototype); 52 | StyleListRenderer.prototype.constructor = StyleListRenderer; 53 | StyleListRenderer.base = ListContainerElement; 54 | 55 | 56 | //////STATIC//////////////////// 57 | 58 | StyleListRenderer.addStyleDropdownLabelFunction = 59 | function (itemData) 60 | { 61 | if (itemData.styleName != "") 62 | return itemData.styleName; 63 | 64 | return itemData.category; 65 | }; 66 | 67 | 68 | //////INTERNAL///////////////// 69 | 70 | StyleListRenderer.prototype._onLocaleChanged = 71 | function (event) 72 | { 73 | //Sometimes we're null depending on if we set data, or add to display first. 74 | if (this.getManager() == null || this._styleControlType == null) 75 | return; 76 | 77 | var currentLocale = this.getManager().getLocale(); 78 | 79 | var dropdownText = localeStrings[currentLocale]["Add"] + " " + this._styleControlType.styleName; 80 | 81 | //Most substyles end with "Style", the ones that dont like "BackgroundShape" we add it to the end for consistency. 82 | if (dropdownText.indexOf("Style") != dropdownText.length - 5) 83 | dropdownText = dropdownText + "Style"; 84 | 85 | this._dropdownAdd.setStyle("Text", dropdownText); 86 | }; 87 | 88 | StyleListRenderer.prototype._onDropdownAddListItemClick = 89 | function (elementListItemClickEvent) 90 | { 91 | var styleControlType = elementListItemClickEvent.getItem(); 92 | 93 | //Header (ignore) 94 | if (styleControlType.styleName == "") 95 | return; 96 | 97 | var itemRenderer; 98 | 99 | //Unchecked 100 | if (styleControlType.styleName in styleControlType.styleDefinition._styleMap) 101 | { 102 | for (var i = 1; i < this.getNumElements(); i++) 103 | { 104 | itemRenderer = this.getElementAt(i); 105 | if (itemRenderer._styleControlType == styleControlType) 106 | { 107 | this._clearItemRenderer(itemRenderer); 108 | break; 109 | } 110 | } 111 | } 112 | else //Checked 113 | { 114 | itemRenderer = new StyleItemRenderer(); 115 | itemRenderer.addEventListener("cleared", this._onItemRendererClearedInstance); 116 | itemRenderer.setStyleControlType(styleControlType); 117 | 118 | this.addElementAt(itemRenderer, 1); 119 | 120 | this._styleControlType.styleList.indexUpdated(this._styleControlType.styleList.getItemIndex(styleControlType)); 121 | 122 | //Dispatch an event from the manager to fire the styling code re-build. 123 | this.getManager().dispatchEvent(new DispatcherEvent("stylingchanged")); 124 | } 125 | }; 126 | 127 | //Clear button clicked on StyleItemRenderer 128 | StyleListRenderer.prototype._onItemRendererCleared = 129 | function (event) 130 | { 131 | this._clearItemRenderer(event.getTarget()); 132 | }; 133 | 134 | StyleListRenderer.prototype._clearItemRenderer = 135 | function (itemRenderer) 136 | { 137 | //This is one of the values in our this._styleControlType.styleList (which is bound to the Add Style dropdown) 138 | var rendererStyleControlType = itemRenderer._styleControlType; 139 | 140 | //Wipe out the style & code string cache 141 | rendererStyleControlType.styleDefinition.clearStyle(rendererStyleControlType.styleName); 142 | rendererStyleControlType.styleListCodeString = ""; 143 | rendererStyleControlType.styleItemCodeString = ""; 144 | 145 | //Fire an indexUpdated event (Update the Add Style dropdown checked state for this style). 146 | this._styleControlType.styleList.indexUpdated(this._styleControlType.styleList.getItemIndex(rendererStyleControlType)); 147 | 148 | //Purge StyleItemRenderer 149 | this.removeElement(itemRenderer); 150 | 151 | //Dispatch an event from the manager to fire the styling code re-build. 152 | this.getManager().dispatchEvent(new DispatcherEvent("stylingchanged")); 153 | }; 154 | 155 | 156 | //////PUBLIC/////////////////// 157 | 158 | StyleListRenderer.prototype.setStyleControlType = 159 | function (styleControlType) 160 | { 161 | this._styleControlType = styleControlType; 162 | this._onLocaleChanged(null); //Update localized labels. 163 | 164 | while (this.getNumElements() > 1) 165 | { 166 | this.getElementAt(1).removeEventListener("cleared", this._onItemRendererClearedInstance); 167 | this.removeElementAt(1); 168 | } 169 | 170 | this._dropdownAdd.setListCollection(styleControlType.styleList); 171 | 172 | var sct; 173 | for (var i = 0; i < styleControlType.styleList.getLength(); i++) 174 | { 175 | sct = styleControlType.styleList.getItemAt(i); 176 | 177 | //Header Item 178 | if (sct.styleName == "") 179 | continue; 180 | 181 | //Defined style item 182 | if (sct.styleName in sct.styleDefinition._styleMap) 183 | { 184 | var itemRenderer = new StyleItemRenderer(); 185 | itemRenderer.addEventListener("cleared", this._onItemRendererClearedInstance); 186 | itemRenderer.setStyleControlType(sct); 187 | 188 | this.addElementAt(itemRenderer, 1); 189 | } 190 | } 191 | }; 192 | 193 | 194 | -------------------------------------------------------------------------------- /src/Demos/StyleExplorer/BlueMarble.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensormaticFirmware/FlexCanvasJS/537b9a841f23e1748b18f8a3a60ea0caecfb3c20/src/Demos/StyleExplorer/BlueMarble.jpg -------------------------------------------------------------------------------- /src/Demos/StyleExplorer/StyleExplorer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FlexCanvasJS Style Explorer 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/Demos/TetriStack/Application/CCAttributeLinks.js: -------------------------------------------------------------------------------- 1 | 2 | function CCAttributeLinks() //extends ListContainerElement 3 | { 4 | //Call base constructor 5 | CCAttributeLinks.base.prototype.constructor.call(this); 6 | 7 | this.setStyle("LayoutDirection", "horizontal"); 8 | this.setStyle("LayoutVerticalAlign", "middle"); 9 | 10 | this._labelCreditSoundName = new LabelElement(); 11 | this._labelCreditSoundName.setStyleDefinitions([textCreditsStyle, textLinkStyle]); 12 | 13 | this._labelCreditSoundBy = new LabelElement(); 14 | this._labelCreditSoundBy.setStyleDefinitions([textCreditsStyle]); 15 | this._labelCreditSoundBy.setStyle("Text", " By "); 16 | 17 | this._labelCreditSoundAuthor = new LabelElement(); 18 | this._labelCreditSoundAuthor.setStyleDefinitions([textCreditsStyle, textLinkStyle]); 19 | 20 | this._labelCreditSoundSpace = new LabelElement(); 21 | this._labelCreditSoundSpace.setStyleDefinitions([textCreditsStyle]); 22 | this._labelCreditSoundSpace.setStyle("Text", " "); 23 | 24 | this._labelCreditSoundLicense = new LabelElement(); 25 | this._labelCreditSoundLicense.setStyleDefinitions([textCreditsStyle, textLinkStyle]); 26 | 27 | this.addElement(this._labelCreditSoundName); 28 | this.addElement(this._labelCreditSoundBy); 29 | this.addElement(this._labelCreditSoundAuthor); 30 | this.addElement(this._labelCreditSoundSpace); 31 | this.addElement(this._labelCreditSoundLicense); 32 | 33 | //////////// 34 | 35 | 36 | var _self = this; 37 | 38 | this._onLabelClickInstance = 39 | function (event) 40 | { 41 | _self._onLabelClick(event); 42 | }; 43 | 44 | this._labelCreditSoundName.addEventListener("click", this._onLabelClickInstance); 45 | this._labelCreditSoundAuthor.addEventListener("click", this._onLabelClickInstance); 46 | this._labelCreditSoundLicense.addEventListener("click", this._onLabelClickInstance); 47 | 48 | 49 | /////////// 50 | 51 | this._licenseData = null; 52 | } 53 | 54 | //Inherit from ListContainerElement 55 | CCAttributeLinks.prototype = Object.create(ListContainerElement.prototype); 56 | CCAttributeLinks.prototype.constructor = CCAttributeLinks; 57 | CCAttributeLinks.base = ListContainerElement; 58 | 59 | CCAttributeLinks.prototype.setLicenseData = 60 | function (data) 61 | { 62 | this._licenseData = data; 63 | 64 | this._labelCreditSoundName.setStyle("Text", data.name); 65 | this._labelCreditSoundAuthor.setStyle("Text", data.author); 66 | this._labelCreditSoundLicense.setStyle("Text", data.license); 67 | }; 68 | 69 | CCAttributeLinks.prototype._onLabelClick = 70 | function (event) 71 | { 72 | var URL = null; 73 | 74 | if (event.getTarget() == this._labelCreditSoundName) 75 | URL = this._licenseData.link; 76 | else if (event.getTarget() == this._labelCreditSoundAuthor) 77 | URL = this._licenseData.authorLink; 78 | else 79 | URL = this._licenseData.licenseLink; 80 | 81 | window.open(URL, "_blank", " "); 82 | }; 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/Demos/TetriStack/Application/TetriAudioSelectSettings.js: -------------------------------------------------------------------------------- 1 | 2 | function TetriAudioSelectSettings() 3 | { 4 | //Call base constructor 5 | TetriAudioSelectSettings.base.prototype.constructor.call(this); 6 | 7 | ////Layout//// 8 | this.setStyle("LayoutDirection", "horizontal"); 9 | 10 | this._checkboxMusic = new CheckboxElement(); 11 | this._checkboxMusic.setStyleDefinitions([labelSelectStyle, labelPlayFieldSmallSizeStyle, buttonBackgroundStyle]); 12 | this._checkboxMusic.setStyle("Text", "Music"); 13 | this._checkboxMusic.setSelected(TetriStackApplication.MusicEnabled); 14 | 15 | this._audioSelectContainerSpacer = new CanvasElement(); 16 | this._audioSelectContainerSpacer.setStyle("Width", 50); 17 | 18 | this._checkboxSFX = new CheckboxElement(); 19 | this._checkboxSFX.setStyleDefinitions([labelSelectStyle, labelPlayFieldSmallSizeStyle, buttonBackgroundStyle]); 20 | this._checkboxSFX.setStyle("Text", "SFX"); 21 | this._checkboxSFX.setSelected(TetriStackApplication.SFXEnabled); 22 | 23 | this.addElement(this._checkboxMusic); 24 | this.addElement(this._audioSelectContainerSpacer); 25 | this.addElement(this._checkboxSFX); 26 | 27 | 28 | ////Event Handling//// 29 | var _self = this; 30 | 31 | //Need a different function instance for each handler, proxy to prototype. 32 | this._onCheckboxMusicChangedInstance = 33 | function (event) 34 | { 35 | _self._onCheckboxMusicChanged(event); 36 | }; 37 | this._onCheckboxSFXChangedInstance = 38 | function (event) 39 | { 40 | _self._onCheckboxSFXChanged(event); 41 | }; 42 | this._onGlobalValueChangedInstance = 43 | function (event) 44 | { 45 | _self._onGlobalValueChanged(event); 46 | }; 47 | this._onTetriAudioSelectSettingsAddedInstance = 48 | function (addedRemovedEvent) 49 | { 50 | _self._onTetriAudioSelectSettingsAdded(addedRemovedEvent); 51 | }; 52 | this._onTetriAudioSelectSettingsRemovedInstance = 53 | function (addedRemovedEvent) 54 | { 55 | _self._onTetriAudioSelectSettingsRemoved(addedRemovedEvent); 56 | }; 57 | 58 | this._checkboxMusic.addEventListener("changed", this._onCheckboxMusicChangedInstance); 59 | this._checkboxSFX.addEventListener("changed", this._onCheckboxSFXChangedInstance); 60 | this.addEventListener("added", this._onTetriAudioSelectSettingsAddedInstance); 61 | this.addEventListener("removed", this._onTetriAudioSelectSettingsRemovedInstance); 62 | } 63 | 64 | //Inherit from ListContainerElement 65 | TetriAudioSelectSettings.prototype = Object.create(ListContainerElement.prototype); 66 | TetriAudioSelectSettings.prototype.constructor = TetriAudioSelectSettings; 67 | TetriAudioSelectSettings.base = ListContainerElement; 68 | 69 | 70 | ////INTERNAL//// 71 | 72 | //Added to display 73 | TetriAudioSelectSettings.prototype._onTetriAudioSelectSettingsAdded = 74 | function (addedRemovedEvent) 75 | { 76 | //Add a listener to global event dispatcher to detect settings changes from other instances. 77 | TetriStackApplication.GlobalEventDispatcher.addEventListener("audiochanged", this._onGlobalValueChangedInstance); 78 | }; 79 | 80 | //Removed from display 81 | TetriAudioSelectSettings.prototype._onTetriAudioSelectSettingsRemoved = 82 | function (addedRemovedEvent) 83 | { 84 | //Remove listener from global event dispatcher. 85 | TetriStackApplication.GlobalEventDispatcher.removeEventListener("audiochanged", this._onGlobalValueChangedInstance); 86 | }; 87 | 88 | //Music toggled 89 | TetriAudioSelectSettings.prototype._onCheckboxMusicChanged = 90 | function (event) 91 | { 92 | //Update static value 93 | TetriStackApplication.MusicEnabled = this._checkboxMusic.getSelected(); 94 | 95 | //Dispatch event from global event dispatcher (update other instances of TetriAudioSelectSettings) 96 | TetriStackApplication.GlobalEventDispatcher.dispatchEvent(new DispatcherEvent("audiochanged")); 97 | }; 98 | 99 | //SFX toggled 100 | TetriAudioSelectSettings.prototype._onCheckboxSFXChanged = 101 | function (event) 102 | { 103 | //Update static value 104 | TetriStackApplication.SFXEnabled = this._checkboxSFX.getSelected(); 105 | 106 | //Dispatch event from global event dispatcher (update other instances of TetriAudioSelectSettings) 107 | TetriStackApplication.GlobalEventDispatcher.dispatchEvent(new DispatcherEvent("audiochanged")); 108 | }; 109 | 110 | //Listener for global event dispatcher (detect settings change from any instance of TetriAudioSelectSettings) 111 | TetriAudioSelectSettings.prototype._onGlobalValueChanged = 112 | function (event) 113 | { 114 | //Update UI 115 | this._checkboxMusic.setSelected(TetriStackApplication.MusicEnabled); 116 | this._checkboxSFX.setSelected(TetriStackApplication.SFXEnabled); 117 | }; 118 | 119 | -------------------------------------------------------------------------------- /src/Demos/TetriStack/Application/TetriBlock.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | function TetriBlock() 4 | { 5 | TetriBlock.base.prototype.constructor.call(this); 6 | 7 | this._isGhost = false; 8 | this._blockColor = TetriStackApplication.BlockColors.BLACK; 9 | } 10 | 11 | //Inherit from CanvasElement 12 | TetriBlock.prototype = Object.create(CanvasElement.prototype); 13 | TetriBlock.prototype.constructor = TetriBlock; 14 | TetriBlock.base = CanvasElement; 15 | 16 | TetriBlock.prototype.setBlockColor = 17 | function (color) 18 | { 19 | if (this._blockColor == color) 20 | return; 21 | 22 | this._blockColor = color; 23 | this._invalidateRender(); 24 | }; 25 | 26 | TetriBlock.prototype.getBlockColor = 27 | function() 28 | { 29 | return this._blockColor; 30 | }; 31 | 32 | TetriBlock.prototype.setIsGhost = 33 | function (isGhost) 34 | { 35 | if (this._isGhost == isGhost) 36 | return; 37 | 38 | this._isGhost = isGhost; 39 | this._invalidateRender(); 40 | }; 41 | 42 | TetriBlock.prototype.getIsGhost = 43 | function () 44 | { 45 | return this._isGhost; 46 | }; 47 | 48 | TetriBlock.prototype._doRender = 49 | function () 50 | { 51 | //Don't call base, we're completely custom rendering. 52 | 53 | var ctx = this._getGraphicsCtx(); 54 | 55 | var x = 0; 56 | var y = 0; 57 | var w = this._width; 58 | var h = this._height; 59 | 60 | var base = null; 61 | var lighter = null; 62 | var darker = null; 63 | var ghost = null; 64 | 65 | if (this._isGhost == true) 66 | { 67 | var black = TetriStackApplication.BlockColors.BLACK; 68 | 69 | base = black.base; 70 | lighter = black.lighter; 71 | darker = black.darker; 72 | 73 | if (this._blockColor != black) 74 | ghost = this._blockColor.base; 75 | } 76 | else 77 | { 78 | base = this._blockColor.base; 79 | lighter = this._blockColor.lighter; 80 | darker = this._blockColor.darker; 81 | } 82 | 83 | ctx.beginPath(); 84 | ctx.moveTo(x, y); 85 | ctx.lineTo(x + w, y); 86 | ctx.lineTo(x + w, y + h); 87 | ctx.lineTo(x, y + h); 88 | ctx.closePath(); 89 | 90 | ctx.fillStyle = base; 91 | ctx.fill(); 92 | 93 | x = .5; 94 | y = .5; 95 | w = this._width - 1; 96 | h = this._height - 1; 97 | 98 | ctx.beginPath(); 99 | ctx.moveTo(x, y); 100 | ctx.lineTo(x + w, y); 101 | ctx.lineTo(x + w, y + h); 102 | ctx.lineTo(x, y + h); 103 | ctx.closePath(); 104 | 105 | ctx.strokeStyle = "#000000"; 106 | ctx.stroke(); 107 | 108 | x = 1; 109 | y = 1; 110 | w = this._width - 2; 111 | h = this._height - 2; 112 | 113 | var bevelWidth = Math.ceil(w / 5); 114 | var bevelHeight = Math.ceil(h / 5); 115 | 116 | ctx.beginPath(); 117 | ctx.moveTo(x, y); 118 | ctx.lineTo(x + w, y); 119 | ctx.lineTo(x + w - bevelWidth, y + bevelHeight); 120 | ctx.lineTo(x + bevelWidth, y + bevelHeight); 121 | ctx.lineTo(x + bevelWidth, y + h - bevelHeight); 122 | ctx.lineTo(x, y + h); 123 | ctx.closePath(); 124 | 125 | ctx.fillStyle = lighter; 126 | ctx.fill(); 127 | 128 | ctx.beginPath(); 129 | ctx.moveTo(x + w, y + h); 130 | ctx.lineTo(x, y + h); 131 | ctx.lineTo(x + bevelWidth, y + h - bevelHeight); 132 | ctx.lineTo(x + w - bevelWidth, y + h - bevelHeight); 133 | ctx.lineTo(x + w - bevelWidth, y + bevelHeight); 134 | ctx.lineTo(x + w, y); 135 | ctx.closePath(); 136 | 137 | ctx.fillStyle = darker; 138 | ctx.fill(); 139 | 140 | if (ghost != null) 141 | { 142 | //Stoke on half pixel (anti-alias / fuzz the outer border) 143 | x = 1; 144 | y = 1; 145 | w = this._width - 2; 146 | h = this._height - 2; 147 | 148 | ctx.beginPath(); 149 | ctx.moveTo(x, y); 150 | ctx.lineTo(x + w, y); 151 | ctx.lineTo(x + w, y + h); 152 | ctx.lineTo(x, y + h); 153 | ctx.closePath(); 154 | 155 | ctx.strokeStyle = ghost; 156 | ctx.stroke(); 157 | 158 | //Stroke inner border (solid) 159 | x = 1.5; 160 | y = 1.5; 161 | w = this._width - 3; 162 | h = this._height - 3; 163 | 164 | ctx.beginPath(); 165 | ctx.moveTo(x, y); 166 | ctx.lineTo(x + w, y); 167 | ctx.lineTo(x + w, y + h); 168 | ctx.lineTo(x, y + h); 169 | ctx.closePath(); 170 | 171 | ctx.strokeStyle = ghost; 172 | ctx.stroke(); 173 | 174 | } 175 | }; 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /src/Demos/TetriStack/Application/TetriStackMain.js: -------------------------------------------------------------------------------- 1 | 2 | //////STYLES////////////////////// 3 | 4 | var applicationStyles = new StyleDefinition(); 5 | applicationStyles.setStyle("BackgroundFill", "#444444"); 6 | 7 | //Increase the line padding to handle characters with low hanging decenders. 8 | applicationStyles.setStyle("TextLinePaddingTop", 2); 9 | applicationStyles.setStyle("TextLinePaddingBottom", 2); 10 | 11 | ///// 12 | var ButtonDownSkinStyle = new StyleDefinition(); 13 | ButtonDownSkinStyle.setStyle("BackgroundFill", "#BEBEBE"); 14 | 15 | var ButtonOverSkinStyle = new StyleDefinition(); 16 | ButtonOverSkinStyle.setStyle("BackgroundFill", "#AFAFAF"); 17 | 18 | var ButtonUpSkinStyle = new StyleDefinition(); 19 | ButtonUpSkinStyle.setStyle("BackgroundFill", "#9F9F9F"); 20 | 21 | var ButtonDisabledSkinStyle = new StyleDefinition(); 22 | ButtonDisabledSkinStyle.setStyle("BackgroundFill", "#777777"); 23 | 24 | var buttonBackgroundShapeStyle = new RoundedRectangleShape(); 25 | buttonBackgroundShapeStyle.setStyle("CornerRadius", 5); 26 | 27 | //Handle button & checkbox 28 | var buttonBackgroundStyle = new StyleDefinition(); 29 | buttonBackgroundStyle.setStyle("DownSkinStyle", ButtonDownSkinStyle); 30 | buttonBackgroundStyle.setStyle("OverSkinStyle", ButtonOverSkinStyle); 31 | buttonBackgroundStyle.setStyle("UpSkinStyle", ButtonUpSkinStyle); 32 | buttonBackgroundStyle.setStyle("SelectedDownSkinStyle", ButtonDownSkinStyle); 33 | buttonBackgroundStyle.setStyle("SelectedOverSkinStyle", ButtonOverSkinStyle); 34 | buttonBackgroundStyle.setStyle("SelectedUpSkinStyle", ButtonUpSkinStyle); 35 | buttonBackgroundStyle.setStyle("DisabledSkinStyle", ButtonDisabledSkinStyle); 36 | buttonBackgroundStyle.setStyle("BorderType", null); 37 | buttonBackgroundStyle.setStyle("BackgroundShape", buttonBackgroundShapeStyle); 38 | ///// 39 | 40 | var textCreditsStyle = new StyleDefinition(); 41 | textCreditsStyle.setStyle("TextFont", "Arial"); 42 | textCreditsStyle.setStyle("TextStyle", "bold"); 43 | textCreditsStyle.setStyle("TextColor", "#DDDDDD"); 44 | textCreditsStyle.setStyle("TextSize", 14); 45 | 46 | var textLinkStyle = new StyleDefinition(); 47 | textLinkStyle.setStyle("TextDecoration", "underline"); 48 | textLinkStyle.setStyle("Cursor", "pointer"); 49 | 50 | ///// 51 | 52 | var buttonPlayStyle = new StyleDefinition(); 53 | buttonPlayStyle.setStyle("Padding", 5); 54 | buttonPlayStyle.setStyle("PaddingLeft", 30); 55 | buttonPlayStyle.setStyle("PaddingRight", 30); 56 | buttonPlayStyle.setStyle("TextFont", "Audiowide"); 57 | buttonPlayStyle.setStyle("TextSize", 22); 58 | buttonPlayStyle.setStyle("TextStyle", "bold"); 59 | buttonPlayStyle.setStyle("Text", "PLAY"); 60 | 61 | var buttonMenuStyle = new StyleDefinition(); 62 | buttonMenuStyle.setStyle("TextFont", "Audiowide"); 63 | buttonMenuStyle.setStyle("TextSize", 22); 64 | buttonMenuStyle.setStyle("TextStyle", "bold"); 65 | buttonMenuStyle.setStyle("Text", "MENU"); 66 | 67 | var labelSelectStyle = new StyleDefinition(); 68 | labelSelectStyle.setStyle("TextSize", 22); 69 | labelSelectStyle.setStyle("TextStyle", "bold"); 70 | labelSelectStyle.setStyle("TextFont", "Audiowide"); 71 | labelSelectStyle.setStyle("TextColor", "#DDDDDD"); 72 | 73 | var labelControlsStyle = new StyleDefinition(); 74 | labelControlsStyle.setStyle("TextSize", 17); 75 | labelControlsStyle.setStyle("TextFont", "Audiowide"); 76 | labelControlsStyle.setStyle("TextColor", "#DDDDDD"); 77 | labelControlsStyle.setStyle("TextStyle", "bold"); 78 | labelControlsStyle.setStyle("TextHorizontalAlign", "center"); 79 | labelControlsStyle.setStyle("PercentWidth", 100); 80 | labelControlsStyle.setStyle("TextHorizontalAlign", "left"); 81 | 82 | var labelControlsValueStyle = new StyleDefinition(); 83 | labelControlsValueStyle.setStyle("TextSize", 17); 84 | labelControlsValueStyle.setStyle("TextFont", "Audiowide"); 85 | labelControlsValueStyle.setStyle("TextColor", "#DDDDDD"); 86 | labelControlsValueStyle.setStyle("TextHorizontalAlign", "center"); 87 | 88 | var labelControlsValueCol1Style = new StyleDefinition(); 89 | labelControlsValueCol1Style.setStyle("Width", 100); 90 | 91 | var labelControlsValueCol2Style = new StyleDefinition(); 92 | labelControlsValueCol2Style.setStyle("Width", 150); 93 | 94 | var labelControlsValueCol3Style = new StyleDefinition(); 95 | labelControlsValueCol3Style.setStyle("Width", 120); 96 | labelControlsValueCol3Style.setStyle("TextHorizontalAlign", "right"); 97 | 98 | var labelControlsDividerStyle = new StyleDefinition(); 99 | labelControlsDividerStyle.setStyle("PercentHeight", 70); 100 | labelControlsDividerStyle.setStyle("Width", 1); 101 | labelControlsDividerStyle.setStyle("BackgroundFill", "#DDDDDD"); 102 | 103 | var labelPlayFieldStyle = new StyleDefinition(); 104 | labelPlayFieldStyle.setStyle("TextStyle", "bold"); 105 | labelPlayFieldStyle.setStyle("TextFont", "Audiowide"); 106 | labelPlayFieldStyle.setStyle("TextColor", "#DDDDDD"); 107 | 108 | var labelPlayFieldStartCountSizeStyle = new StyleDefinition(); 109 | labelPlayFieldStartCountSizeStyle.setStyle("TextSize", 80); 110 | 111 | var labelPlayFieldExLargeSizeStyle = new StyleDefinition(); 112 | labelPlayFieldExLargeSizeStyle.setStyle("TextSize", 36); 113 | 114 | var labelPlayFieldLargeSizeStyle = new StyleDefinition(); 115 | labelPlayFieldLargeSizeStyle.setStyle("TextSize", 24); 116 | 117 | var labelPlayFieldSmallSizeStyle = new StyleDefinition(); 118 | labelPlayFieldSmallSizeStyle.setStyle("TextSize", 20); 119 | 120 | var scoreControlsDividerStyle = new StyleDefinition(); 121 | scoreControlsDividerStyle.setStyle("PercentWidth", 80); 122 | scoreControlsDividerStyle.setStyle("Height", 1); 123 | scoreControlsDividerStyle.setStyle("BackgroundFill", "#DDDDDD"); 124 | 125 | //// 126 | var playFieldOuterContainerBackgroundShapeStyle = new RoundedRectangleShape(); 127 | playFieldOuterContainerBackgroundShapeStyle.setStyle("CornerRadius", 5); 128 | 129 | var playFieldOuterContainerStyle = new StyleDefinition(); 130 | playFieldOuterContainerStyle.setStyle("BackgroundFill", "#DDDDDD"); 131 | playFieldOuterContainerStyle.setStyle("BackgroundShape", playFieldOuterContainerBackgroundShapeStyle); 132 | //// 133 | 134 | var playFieldInnerContainerStyle = new StyleDefinition(); 135 | playFieldInnerContainerStyle.setStyle("BackgroundFill", "#202020"); 136 | playFieldInnerContainerStyle.setStyle("Top", 3); 137 | playFieldInnerContainerStyle.setStyle("Bottom", 3); 138 | playFieldInnerContainerStyle.setStyle("Left", 3); 139 | playFieldInnerContainerStyle.setStyle("Right", 3); 140 | 141 | 142 | /////////SOUNDS////////////////// 143 | 144 | var sound_countdownbeep = new Audio(["Sounds/37732__longhairman__1khz-1ds-peep.mp3"]); 145 | var sound_countdownLicenseData = { 146 | 147 | name:"1khz-1ds-peep", 148 | link:"https://freesound.org/people/Longhairman/sounds/37732/", 149 | 150 | author:"Longhairman", 151 | authorLink:"https://freesound.org/people/Longhairman/", 152 | 153 | license:"CC0 1.0", 154 | licenseLink:"https://creativecommons.org/publicdomain/zero/1.0/" 155 | }; 156 | sound_countdownbeep.volume = 0.35; 157 | 158 | var sound_rotate = new Audio(["Sounds/187024__lloydevans09__jump2.mp3"]); 159 | var sound_rotateLicenseData = { 160 | 161 | name:"jump2", 162 | link:"https://freesound.org/people/LloydEvans09/sounds/187024/", 163 | 164 | author:"LloydEvans09", 165 | authorLink:"https://freesound.org/people/LloydEvans09/", 166 | 167 | license:"CC BY 3.0", 168 | licenseLink:"https://creativecommons.org/licenses/by/3.0/" 169 | }; 170 | 171 | var sound_lineComplete = new Audio(["Sounds/109662__grunz__success.mp3"]); 172 | var sound_lineCompleteLicenseData = { 173 | 174 | name:"success", 175 | link:"https://freesound.org/people/grunz/sounds/109662/", 176 | 177 | author:"grunz", 178 | authorLink:"https://freesound.org/people/grunz/", 179 | 180 | license:"CC BY 3.0", 181 | licenseLink:"https://creativecommons.org/licenses/by/3.0/" 182 | }; 183 | 184 | var sound_levelUp = new Audio(["Sounds/320777__rhodesmas__action-01.mp3"]); 185 | var sound_levelUpLicenseData = { 186 | 187 | name:"action-01", 188 | link:"https://freesound.org/people/rhodesmas/sounds/320777/", 189 | 190 | author:"rhodesmas", 191 | authorLink:"https://freesound.org/people/rhodesmas/", 192 | 193 | license:"CC BY 3.0", 194 | licenseLink:"https://creativecommons.org/licenses/by/3.0/" 195 | }; 196 | 197 | var sound_music = new Audio(["Sounds/382931__frankum__vintage-techno-house-loop-110bpm.mp3"]); 198 | var sound_musicLicenseData = { 199 | 200 | name:"vintage-techno-house-loop-110bpm", 201 | link:"https://freesound.org/people/frankum/sounds/382931/", 202 | 203 | author:"frankum", 204 | authorLink:"https://freesound.org/people/frankum/", 205 | 206 | license:"CC BY 3.0", 207 | licenseLink:"https://creativecommons.org/licenses/by/3.0/" 208 | }; 209 | sound_music.loop = true; 210 | 211 | 212 | //////APPLICATION//////////////// 213 | 214 | //Globals go here...// 215 | 216 | //Root application 217 | var tetriStack = null; //Best not to initialize here, avoid file ordering dependencies. 218 | 219 | //Run application 220 | function init() 221 | { 222 | //Initialize globals 223 | tetriStack = new TetriStackApplication(); 224 | tetriStack.setCanvas(document.getElementById("canvasTetriStack")); 225 | } 226 | 227 | -------------------------------------------------------------------------------- /src/Demos/TetriStack/Sounds/109662__grunz__success.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensormaticFirmware/FlexCanvasJS/537b9a841f23e1748b18f8a3a60ea0caecfb3c20/src/Demos/TetriStack/Sounds/109662__grunz__success.mp3 -------------------------------------------------------------------------------- /src/Demos/TetriStack/Sounds/187024__lloydevans09__jump2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensormaticFirmware/FlexCanvasJS/537b9a841f23e1748b18f8a3a60ea0caecfb3c20/src/Demos/TetriStack/Sounds/187024__lloydevans09__jump2.mp3 -------------------------------------------------------------------------------- /src/Demos/TetriStack/Sounds/320777__rhodesmas__action-01.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensormaticFirmware/FlexCanvasJS/537b9a841f23e1748b18f8a3a60ea0caecfb3c20/src/Demos/TetriStack/Sounds/320777__rhodesmas__action-01.mp3 -------------------------------------------------------------------------------- /src/Demos/TetriStack/Sounds/37732__longhairman__1khz-1ds-peep.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensormaticFirmware/FlexCanvasJS/537b9a841f23e1748b18f8a3a60ea0caecfb3c20/src/Demos/TetriStack/Sounds/37732__longhairman__1khz-1ds-peep.mp3 -------------------------------------------------------------------------------- /src/Demos/TetriStack/Sounds/382931__frankum__vintage-techno-house-loop-110bpm.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SensormaticFirmware/FlexCanvasJS/537b9a841f23e1748b18f8a3a60ea0caecfb3c20/src/Demos/TetriStack/Sounds/382931__frankum__vintage-techno-house-loop-110bpm.mp3 -------------------------------------------------------------------------------- /src/Demos/TetriStack/Sounds/SOUNDLICENSE: -------------------------------------------------------------------------------- 1 | 2 | 109662__grunz__success 3 | https://freesound.org/people/grunz/sounds/109662/ 4 | 5 | grunz 6 | https://freesound.org/people/grunz/ 7 | 8 | CC BY 3.0 9 | https://creativecommons.org/licenses/by/3.0/ 10 | 11 | ----------------------------------- 12 | 13 | 187024_lloydevans09_jump2 14 | https://freesound.org/people/LloydEvans09/sounds/187024/ 15 | 16 | LloydEvans09 17 | https://freesound.org/people/LloydEvans09/ 18 | 19 | CC BY 3.0 20 | https://creativecommons.org/licenses/by/3.0/ 21 | 22 | ----------------------------------- 23 | 24 | 37732_longhairman_1khz-1ds-peep 25 | https://freesound.org/people/Longhairman/sounds/37732/ 26 | 27 | Longhairman 28 | https://freesound.org/people/Longhairman/ 29 | 30 | CC0 1.0 31 | https://creativecommons.org/publicdomain/zero/1.0/ 32 | 33 | ------------------------------------ 34 | 35 | 382931__frankum__vintage-techno-house-loop-110bpm 36 | https://freesound.org/people/frankum/sounds/382931/ 37 | 38 | frankum 39 | https://freesound.org/people/frankum/ 40 | 41 | CC BY 3.0 42 | https://creativecommons.org/licenses/by/3.0/ 43 | 44 | ------------------------------------ 45 | 46 | 320777__rhodesmas__action-01 47 | https://freesound.org/people/rhodesmas/sounds/320777/ 48 | 49 | rhodesmas 50 | https://freesound.org/people/rhodesmas/ 51 | 52 | CC BY 3.0 53 | https://creativecommons.org/licenses/by/3.0/ 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/Demos/TetriStack/TetriStack.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FlexCanvasJS Tetri Stack 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/CollectionSort.js: -------------------------------------------------------------------------------- 1 | 2 | /////////////////////////////////////////////////////////////////// 3 | ///////////////////////CollectionSort////////////////////////////// 4 | 5 | /** 6 | * @class CollectionSort 7 | * 8 | * CollectionSort is a helper class that stores a comparatorFunction 9 | * and a isDecending flag used to invert the sort. 10 | * 11 | * 12 | * @constructor CollectionSort 13 | * Creates new CollectionSort instance. 14 | * 15 | * @param comparatorFunction Function 16 | * The sort comparator function to use when sorting an array. 17 | * 18 | * @param isDecending boolean 19 | * When true invert the sort. 20 | */ 21 | function CollectionSort(comparatorFunction, isDecending) 22 | { 23 | this._comparatorFunction = comparatorFunction; 24 | this._isDecending = isDecending; 25 | 26 | var _self = this; 27 | 28 | //Private function to invert the comparator (decending sort). 29 | //This gets passed to Array as function pointer so there's no point in using prototype. 30 | this._collectionSortDecendingComparator = 31 | function (objA, objB) 32 | { 33 | return _self._comparatorFunction(objB, objA); 34 | }; 35 | } 36 | 37 | //No inheritance (base object) 38 | CollectionSort.prototype.constructor = CollectionSort; 39 | 40 | /** 41 | * @function setComparatorFunction 42 | * Sets the comparator function to be used when sorting. Comparators accept 2 parameters and return -1, 0, or +1 43 | * depending on the sort relation between the 2 parameters. 44 | * 45 | * function (objA, objB) { return objA - objB; }; 46 | * 47 | * @param comparatorFunction Function 48 | * The function to be used as the comparator. 49 | */ 50 | CollectionSort.prototype.setComparatorFunction = 51 | function (comparatorFunction) 52 | { 53 | this._comparatorFunction = comparatorFunction; 54 | }; 55 | 56 | /** 57 | * @function getComparatorFunction 58 | * Gets the comparator function used when sorting. 59 | * 60 | * @returns Function 61 | * The comparator function used when sorting. 62 | */ 63 | CollectionSort.prototype.getComparatorFunction = 64 | function () 65 | { 66 | return this._comparatorFunction; 67 | }; 68 | 69 | /** 70 | * @function sort 71 | * Sorts an array using the comparator function and isDecending flag. 72 | * 73 | * @param array Array 74 | * Array to be sorted. 75 | */ 76 | CollectionSort.prototype.sort = 77 | function (array) 78 | { 79 | if (this._isDecending == true) 80 | array.sort(this._collectionSortDecendingComparator); 81 | else 82 | array.sort(this._comparatorFunction); 83 | }; 84 | 85 | /** 86 | * @function setIsDecending 87 | * Sets the isDecending flag. True to invert the sort. 88 | * 89 | * @param isDecending bool 90 | * When true, invert the sort comparator function. 91 | */ 92 | CollectionSort.prototype.setIsDecending = 93 | function (isDecending) 94 | { 95 | this._isDecending = isDecending; 96 | }; 97 | 98 | /** 99 | * @function getIsDecending 100 | * Gets the state of the isDecending flag. 101 | * 102 | * @returns boolean 103 | * The state of the isDecending flag. 104 | */ 105 | CollectionSort.prototype.getIsDecending = 106 | function () 107 | { 108 | return this._isDecending; 109 | }; 110 | 111 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/CursorDefinition.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends StyleableBase.js 4 | */ 5 | 6 | //////////////////////////////////////////////////////// 7 | //////////////CursorDefinition////////////////////////// 8 | 9 | /** 10 | * @class CursorDefinition 11 | * @inherits StyleableBase 12 | * 13 | * CursorDefintion stores styles necessary to render/animate custom cursors. 14 | * This is used for CanvasElement's Cursor style (roll-over cursor) and can 15 | * also be added directly to CanvasManager. 16 | * 17 | * 18 | * @constructor CursorDefinition 19 | * Creates new CursorDefinition instance. 20 | */ 21 | function CursorDefinition() 22 | { 23 | CursorDefinition.base.prototype.constructor.call(this); 24 | 25 | this._cursorElement = null; 26 | this._addedCount = 0; 27 | } 28 | 29 | //Inherit from StyleableBase 30 | CursorDefinition.prototype = Object.create(StyleableBase.prototype); 31 | CursorDefinition.prototype.constructor = CursorDefinition; 32 | CursorDefinition.base = StyleableBase; 33 | 34 | /////////////Style Types/////////////////////////////// 35 | 36 | CursorDefinition._StyleTypes = Object.create(null); 37 | 38 | /** 39 | * @style CursorClass CanvasElement 40 | * 41 | * The CanvasElement constructor or browser string type to use for the cursor. 42 | */ 43 | CursorDefinition._StyleTypes.CursorClass = StyleableBase.EStyleType.NORMAL; // CanvasElement() constructor 44 | 45 | /** 46 | * @style CursorStyle StyleDefinition 47 | * 48 | * The StyleDefinition to apply to the cursor class. (Including Width and Height, unless you've implemented 49 | * the doMeasure() function into a custom CanvasElement subclass). 50 | */ 51 | CursorDefinition._StyleTypes.CursorStyle = StyleableBase.EStyleType.NORMAL; // StyleDefinition 52 | 53 | /** 54 | * @style CursorOffsetX Number 55 | * 56 | * The X offset from the actual mouse position the cursor should be rendered. 57 | */ 58 | CursorDefinition._StyleTypes.CursorOffsetX = StyleableBase.EStyleType.NORMAL; // number 59 | 60 | /** 61 | * @style CursorOffsetY Number 62 | * 63 | * The Y offset from the actual mouse position the cursor should be rendered. 64 | */ 65 | CursorDefinition._StyleTypes.CursorOffsetY = StyleableBase.EStyleType.NORMAL; // number 66 | 67 | 68 | ///////////Default Styles///////////////////////////// 69 | 70 | CursorDefinition.StyleDefault = new StyleDefinition(); 71 | 72 | CursorDefinition.StyleDefault.setStyle("CursorClass", "default"); // "browsertype" || CanvasElement() constructor 73 | CursorDefinition.StyleDefault.setStyle("CursorStyle", null); // StyleDefinition 74 | CursorDefinition.StyleDefault.setStyle("CursorOffsetX", 0); // number 75 | CursorDefinition.StyleDefault.setStyle("CursorOffsetY", 0); // number 76 | 77 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/DrawMetrics.js: -------------------------------------------------------------------------------- 1 | 2 | ///////////////////////////////////////////////////////////////////// 3 | /////////////////////DrawMetrics///////////////////////////////////// 4 | 5 | /** 6 | * @class DrawMetrics 7 | * 8 | * Simple data structure to represent bounds. (X, Y, Width, Height). 9 | * 10 | * 11 | * @constructor DrawMetrics 12 | * Creates new DrawMetrics instance. 13 | */ 14 | 15 | //Supporting class used to indicate element bounds. 16 | function DrawMetrics() 17 | { 18 | this._x = 0; 19 | this._y = 0; 20 | this._width = 0; 21 | this._height = 0; 22 | } 23 | 24 | //DrawMetrics is base object, no inheritance. 25 | DrawMetrics.prototype.constructor = DrawMetrics; 26 | 27 | /** 28 | * @function equals 29 | * 30 | * Checks if two instances of DrawMetrics contain the same values. 31 | * 32 | * @param drawMetrics DrawMetrics 33 | * DrawMetrics instance to compare. 34 | * 35 | * @returns bool 36 | * True when both instances contain the same values. 37 | */ 38 | DrawMetrics.prototype.equals = 39 | function(drawMetrics) 40 | { 41 | if (this._x == drawMetrics._x && 42 | this._y == drawMetrics._y && 43 | this._width == drawMetrics._width && 44 | this._height == drawMetrics._height) 45 | { 46 | return true; 47 | } 48 | 49 | return false; 50 | }; 51 | 52 | /** 53 | * @function clone 54 | * Duplicates an instance of DrawMetrics. 55 | * 56 | * @returns DrawMetrics 57 | * A new DrawMetrics instance identical to the cloned instance. 58 | */ 59 | DrawMetrics.prototype.clone = 60 | function () 61 | { 62 | var clonedMetrics = new DrawMetrics(); 63 | 64 | clonedMetrics._x = this._x; 65 | clonedMetrics._y = this._y; 66 | clonedMetrics._width = this._width; 67 | clonedMetrics._height = this._height; 68 | 69 | return clonedMetrics; 70 | }; 71 | 72 | //@private (for now) 73 | DrawMetrics.prototype.copyFrom = 74 | function (copyFromMetrics) 75 | { 76 | this._x = copyFromMetrics._x; 77 | this._y = copyFromMetrics._y; 78 | this._width = copyFromMetrics._width; 79 | this._height = copyFromMetrics._height; 80 | }; 81 | 82 | //@private (for now) 83 | DrawMetrics.prototype.mergeExpand = 84 | function (mergeWithDrawMetrics) 85 | { 86 | if (mergeWithDrawMetrics._x < this._x) 87 | { 88 | this._width += (this._x - mergeWithDrawMetrics._x); 89 | this._x = mergeWithDrawMetrics._x; 90 | } 91 | if (mergeWithDrawMetrics._y < this._y) 92 | { 93 | this._height += (this._y - mergeWithDrawMetrics._y); 94 | this._y = mergeWithDrawMetrics._y; 95 | } 96 | if (mergeWithDrawMetrics._x + mergeWithDrawMetrics._width > this._x + this._width) 97 | this._width += ((mergeWithDrawMetrics._x + mergeWithDrawMetrics._width) - (this._x + this._width)); 98 | if (mergeWithDrawMetrics._y + mergeWithDrawMetrics._height > this._y + this._height) 99 | this._height += ((mergeWithDrawMetrics._y + mergeWithDrawMetrics._height) - (this._y + this._height)); 100 | }; 101 | 102 | //@private (for now) 103 | DrawMetrics.prototype.mergeReduce = 104 | function (mergeWithDrawMetrics) 105 | { 106 | if (this._x < mergeWithDrawMetrics._x) 107 | { 108 | this._width -= (mergeWithDrawMetrics._x - this._x); 109 | this._x = mergeWithDrawMetrics._x; 110 | } 111 | if (this._y < mergeWithDrawMetrics._y) 112 | { 113 | this._height -= (mergeWithDrawMetrics._y - this._y); 114 | this._y = mergeWithDrawMetrics._y; 115 | } 116 | if (this._x + this._width > mergeWithDrawMetrics._x + mergeWithDrawMetrics._width) 117 | this._width -= ((this._x + this._width) - (mergeWithDrawMetrics._x + mergeWithDrawMetrics._width)); 118 | if (this._y + this._height > mergeWithDrawMetrics._y + mergeWithDrawMetrics._height) 119 | this._height -= ((this._y + this._height) - (mergeWithDrawMetrics._y + mergeWithDrawMetrics._height)); 120 | }; 121 | 122 | DrawMetrics.prototype.roundToPrecision = 123 | function (precision) 124 | { 125 | this._x = CanvasElement.roundToPrecision(this._x, precision); 126 | this._y = CanvasElement.roundToPrecision(this._y, precision); 127 | this._width = CanvasElement.roundToPrecision(this._width, precision); 128 | this._height = CanvasElement.roundToPrecision(this._height, precision); 129 | }; 130 | 131 | //@private (for now) 132 | DrawMetrics.prototype.roundUp = 133 | function () 134 | { 135 | var x1 = this._x; 136 | var x2 = this._x + this._width; 137 | var y1 = this._y; 138 | var y2 = this._y + this._height; 139 | 140 | x1 = Math.floor(x1); 141 | x2 = Math.ceil(x2); 142 | y1 = Math.floor(y1); 143 | y2 = Math.ceil(y2); 144 | 145 | this._x = x1; 146 | this._y = y1; 147 | this._width = x2 - x1; 148 | this._height = y2 - y1; 149 | }; 150 | 151 | /** 152 | * @function getX 153 | * 154 | * Gets the X value in pixels, this may be fractional. 155 | * 156 | * @returns Number 157 | * The X value. 158 | */ 159 | DrawMetrics.prototype.getX = 160 | function() 161 | { 162 | return this._x; 163 | }; 164 | 165 | /** 166 | * @function getY 167 | * 168 | * Gets the Y value in pixels, this may be fractional. 169 | * 170 | * @returns Number 171 | * The Y value. 172 | */ 173 | DrawMetrics.prototype.getY = 174 | function() 175 | { 176 | return this._y; 177 | }; 178 | 179 | /** 180 | * @function getWidth 181 | * 182 | * Gets the Width value in pixels, this may be fractional. 183 | * 184 | * @returns Number 185 | * The Width value. 186 | */ 187 | DrawMetrics.prototype.getWidth = 188 | function() 189 | { 190 | return this._width; 191 | }; 192 | 193 | /** 194 | * @function getHeight 195 | * 196 | * Gets the Height value in pixels, this may be fractional. 197 | * 198 | * @returns Number 199 | * The Height value. 200 | */ 201 | DrawMetrics.prototype.getHeight = 202 | function() 203 | { 204 | return this._height; 205 | }; 206 | 207 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/EventDispatcher.js: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////// 3 | /////////////////////EventDispatcher////////////////////////////////// 4 | 5 | /** 6 | * @class EventDispatcher 7 | * Base class for all objects that dispatch events. 8 | * 9 | * @constructor EventDispatcher 10 | * Creates new EventDispatcher instance. 11 | */ 12 | function EventDispatcher() 13 | { 14 | this._eventListeners = Object.create(null); //Map of arrays by event name. 15 | } 16 | 17 | //EventDispatcher is base object, no inheritance. 18 | EventDispatcher.prototype.constructor = EventDispatcher; 19 | 20 | ///////////EventDispatcher Public Functions/////////////////////////// 21 | 22 | /** 23 | * @function addEventListener 24 | * Registers an event lister function to be called when an event occurs. 25 | * 26 | * @param type String 27 | * String representing the event type. 28 | * 29 | * @param callback Function 30 | * Function to be called when the event occurs. 31 | */ 32 | EventDispatcher.prototype.addEventListener = 33 | function (type, callback) 34 | { 35 | if (this._eventListeners[type] == null) 36 | this._eventListeners[type] = []; 37 | 38 | this._eventListeners[type].push(callback); 39 | }; 40 | 41 | /** 42 | * @function removeEventListener 43 | * Removes a callback from the EventDispatcher 44 | * 45 | * @param type String 46 | * String representing the event type. 47 | * 48 | * @param callback Function 49 | * Function callback to be removed. 50 | * 51 | * @returns boolean 52 | * Returns true if the callback was successfully removed, otherwise false 53 | * such as if the function callback was not previously registered. 54 | */ 55 | EventDispatcher.prototype.removeEventListener = 56 | function (type, callback) 57 | { 58 | if (!(type in this._eventListeners)) 59 | return false; 60 | 61 | for (var i = 0; i < this._eventListeners[type].length; i++) 62 | { 63 | if (this._eventListeners[type][i] == callback) 64 | { 65 | this._eventListeners[type].splice(i, 1); 66 | return true; 67 | } 68 | } 69 | 70 | return false; 71 | }; 72 | 73 | /** 74 | * @function hasEventListener 75 | * Checks if an event listener has been registered with this EventDispatcher 76 | * 77 | * @param type String 78 | * String representing the event type. 79 | * 80 | * @param callback Function 81 | * Function callback to be called when the event occurs. This may be null to check 82 | * if the EventDispatcher has any events registered for the provided type. 83 | * 84 | * @returns boolean 85 | * Returns true if the EventDispatcher has the provided callback registered for the 86 | * provided type, or any callback for the provided type if the callback parameter is null. 87 | * Otherwise, returns false. 88 | */ 89 | EventDispatcher.prototype.hasEventListener = 90 | function (type, callback) 91 | { 92 | if (!(type in this._eventListeners)) 93 | return false; 94 | 95 | if (callback == null) 96 | { 97 | if (this._eventListeners[type].length > 0) 98 | return true; 99 | 100 | return false; 101 | } 102 | 103 | 104 | for (var i = 0; i < this._eventListeners[type].length; i++) 105 | { 106 | if (this._eventListeners[type][i] == callback) 107 | return true; 108 | } 109 | 110 | return false; 111 | }; 112 | 113 | /** 114 | * @function dispatchEvent 115 | * Dispatches an event to be processed by registered event listeners. The Event's target is the 116 | * EventDispatcher which called dispatchEvent. The Event will be cloned prior to passing to callback functions 117 | * to ensure the callback cannot modify the Event data or properties. You can check if the event was canceled 118 | * by calling the Event's getIsCanceled after dispatching it. Re-dispatching the same event will re-set its canceled state to false. 119 | * 120 | * @param event DispatcherEvent 121 | * The DispatcherEvent class or subclass to be dispatched. 122 | */ 123 | EventDispatcher.prototype.dispatchEvent = 124 | function (event) 125 | { 126 | event._canceled = false; 127 | 128 | if (event._type in this._eventListeners && this._eventListeners[event._type].length > 0) 129 | { 130 | //Copy the list of event handlers, if event handlers add/remove other handlers or themselves, 131 | //we dont want to miss an event, or inconsistently dispatch newly added events. 132 | var listeners = this._eventListeners[event._type].slice(); 133 | 134 | //TODO: Sort by priority (no priority available yet). 135 | 136 | var cloneEvent = null; 137 | for (var i = 0; i < listeners.length; i++) 138 | { 139 | //Clone the event so the handler can't fudge our event data. 140 | cloneEvent = event.clone(); 141 | cloneEvent._target = this; 142 | 143 | listeners[i](cloneEvent); 144 | 145 | if (cloneEvent._canceled == true) 146 | { 147 | event._canceled = true; 148 | return; 149 | } 150 | } 151 | } 152 | }; 153 | 154 | 155 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/LabelElement.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends CanvasElement.js 4 | */ 5 | 6 | ///////////////////////////////////////////////////////// 7 | /////////////////LabelElement//////////////////////////// 8 | 9 | /** 10 | * @class LabelElement 11 | * @inherits CanvasElement 12 | * 13 | * Basic label for rendering single line style-able text. 14 | * Can be styled to automatically truncate text to fit the available 15 | * space with a supplied string like ellipses "...". 16 | * 17 | * 18 | * @constructor LabelElement 19 | * Creates new LabelElement instance. 20 | */ 21 | function LabelElement() 22 | { 23 | LabelElement.base.prototype.constructor.call(this); 24 | 25 | this._textWidth = null; 26 | this._textHeight = null; 27 | this._truncateStringWidth = null; 28 | } 29 | 30 | //Inherit from CanvasElement 31 | LabelElement.prototype = Object.create(CanvasElement.prototype); 32 | LabelElement.prototype.constructor = LabelElement; 33 | LabelElement.base = CanvasElement; 34 | 35 | /////////////Style Types/////////////////////////////// 36 | 37 | LabelElement._StyleTypes = Object.create(null); 38 | 39 | /** 40 | * @style Text String 41 | * Text to be rendered by the Label. 42 | */ 43 | LabelElement._StyleTypes.Text = StyleableBase.EStyleType.NORMAL; // "any string" || null 44 | 45 | /** 46 | * @style TruncateToFit String 47 | * String to use when truncating a label that does not fit the available area. Defaults to "...". 48 | */ 49 | LabelElement._StyleTypes.TruncateToFit = StyleableBase.EStyleType.NORMAL; // null || "string" ("...") 50 | 51 | 52 | ////////////Default Styles//////////////////////////// 53 | 54 | LabelElement.StyleDefault = new StyleDefinition(); 55 | 56 | //Override base class styles 57 | LabelElement.StyleDefault.setStyle("PaddingTop", 2); 58 | LabelElement.StyleDefault.setStyle("PaddingBottom", 2); 59 | LabelElement.StyleDefault.setStyle("PaddingLeft", 2); 60 | LabelElement.StyleDefault.setStyle("PaddingRight", 2); 61 | 62 | //LabelElement specific styles 63 | LabelElement.StyleDefault.setStyle("Text", null); 64 | LabelElement.StyleDefault.setStyle("TruncateToFit", "..."); 65 | 66 | 67 | /////////////LabelElement Internal Functions/////////////////// 68 | 69 | //@Override 70 | LabelElement.prototype._doStylesUpdated = 71 | function (stylesMap) 72 | { 73 | LabelElement.base.prototype._doStylesUpdated.call(this, stylesMap); 74 | 75 | if ("TextStyle" in stylesMap || 76 | "TextFont" in stylesMap || 77 | "TextSize" in stylesMap || 78 | "Text" in stylesMap || 79 | "TextLinePaddingTop" in stylesMap || 80 | "TextLinePaddingBottom" in stylesMap) 81 | { 82 | this._textWidth = null; 83 | this._textHeight = null; 84 | 85 | this._invalidateMeasure(); 86 | this._invalidateRender(); 87 | } 88 | 89 | if ("TruncateToFit" in stylesMap) 90 | { 91 | this._truncateStringWidth = null; 92 | 93 | this._invalidateRender(); 94 | } 95 | 96 | if ("TextHorizontalAlign" in stylesMap || 97 | "TextVerticalAlign" in stylesMap || 98 | "TextColor" in stylesMap || 99 | "TextFillType" in stylesMap || 100 | "TextDecoration" in stylesMap) 101 | { 102 | this._invalidateRender(); 103 | } 104 | }; 105 | 106 | //@Override 107 | LabelElement.prototype._doMeasure = 108 | function(padWidth, padHeight) 109 | { 110 | if (this._textWidth == null || this._textHeight == null) 111 | { 112 | var measureText = this.getStyle("Text"); 113 | if (measureText == null) 114 | measureText = ""; 115 | 116 | this._textHeight = this.getStyle("TextSize") + this.getStyle("TextLinePaddingTop") + this.getStyle("TextLinePaddingBottom"); 117 | this._textWidth = CanvasElement._measureText(measureText, this._getFontString()); 118 | } 119 | 120 | this._setMeasuredSize(this._textWidth + padWidth, this._textHeight + padHeight); 121 | }; 122 | 123 | //@override 124 | LabelElement.prototype._doRender = 125 | function () 126 | { 127 | LabelElement.base.prototype._doRender.call(this); 128 | 129 | var text = this.getStyle("Text"); 130 | if (text == null || text.length == 0) 131 | return; 132 | 133 | var ctx = this._getGraphicsCtx(); 134 | var paddingMetrics = this._getPaddingMetrics(); 135 | 136 | //For convienence 137 | var x = paddingMetrics.getX(); 138 | var y = paddingMetrics.getY(); 139 | var w = paddingMetrics.getWidth(); 140 | var h = paddingMetrics.getHeight(); 141 | 142 | var fontString = this._getFontString(); 143 | var totalWidth = this._textWidth; 144 | 145 | //Truncate if necessary 146 | if (totalWidth > w) 147 | { 148 | var truncateString = this.getStyle("TruncateToFit"); 149 | 150 | //Get number of truncate chars 151 | var numTruncateChars = 0; 152 | if (truncateString != null) 153 | numTruncateChars = truncateString.length; 154 | 155 | //Get truncate chars width 156 | if (this._truncateStringWidth == null) 157 | { 158 | if (truncateString == null) 159 | this._truncateStringWidth = 0; 160 | else 161 | this._truncateStringWidth = CanvasElement._measureText(truncateString, fontString); 162 | } 163 | 164 | var charWidth = 0; 165 | var numTextChars = text.length; 166 | totalWidth = this._textWidth + this._truncateStringWidth; 167 | 168 | //Remove text characters until we fit or run out. 169 | while (numTextChars > 0 && totalWidth > w) 170 | { 171 | charWidth = CanvasElement._measureText(text[numTextChars - 1], fontString); 172 | 173 | numTextChars--; 174 | totalWidth -= charWidth; 175 | } 176 | 177 | //Remove truncate characters until we fit or run out 178 | while (numTruncateChars > 0 && totalWidth > w) 179 | { 180 | charWidth = CanvasElement._measureText(truncateString[numTruncateChars - 1], fontString); 181 | 182 | numTruncateChars--; 183 | totalWidth -= charWidth; 184 | } 185 | 186 | text = text.substring(0, numTextChars) + truncateString.substring(0, numTruncateChars); 187 | } 188 | 189 | var linePaddingTop = this.getStyle("TextLinePaddingTop"); 190 | var linePaddingBottom = this.getStyle("TextLinePaddingBottom"); 191 | 192 | var textBaseline = this.getStyle("TextVerticalAlign"); 193 | var textAlign = this.getStyle("TextHorizontalAlign"); 194 | var textFillType = this.getStyle("TextFillType"); 195 | var textColor = this.getStyle("TextColor"); 196 | var textDecoration = this.getStyle("TextDecoration"); 197 | 198 | //Get x position 199 | var textXPosition; 200 | if (textAlign == "left") 201 | textXPosition = x; 202 | else if (textAlign == "right") 203 | textXPosition = x + w - totalWidth; 204 | else //center 205 | textXPosition = Math.round(x + (w / 2) - (totalWidth / 2)); 206 | 207 | //Get y position 208 | var textYPosition; 209 | if (textBaseline == "top") 210 | textYPosition = y + linePaddingTop; 211 | else if (textBaseline == "bottom") 212 | textYPosition = y + h - linePaddingBottom; 213 | else //middle 214 | textYPosition = Math.round(y + (h / 2) + (linePaddingTop / 2) - (linePaddingBottom / 2)); 215 | 216 | //Render text 217 | if (textFillType == "stroke") 218 | CanvasElement._strokeText(ctx, text, textXPosition, textYPosition, fontString, textColor, textBaseline); 219 | else 220 | CanvasElement._fillText(ctx, text, textXPosition, textYPosition, fontString, textColor, textBaseline); 221 | 222 | if (textDecoration == "underline") 223 | { 224 | y = paddingMetrics.getY() + linePaddingTop + this.getStyle("TextSize") + linePaddingBottom - .5; 225 | 226 | ctx.beginPath(); 227 | ctx.moveTo(x, y); 228 | ctx.lineTo(x + w, y); 229 | ctx.lineWidth = 1; 230 | ctx.strokeStyle = textColor; 231 | 232 | ctx.stroke(); 233 | } 234 | }; 235 | 236 | 237 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/StyleDefinition.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends EventDispatcher.js 4 | */ 5 | 6 | /////////////////////////////////////////////////////////////////// 7 | ///////////////////////StyleDefinition///////////////////////////// 8 | 9 | /** 10 | * @class StyleDefinition 11 | * @inherits EventDispatcher 12 | * 13 | * Stores a key value data set of style values by name. 14 | * 15 | * 16 | * @constructor StyleDefinition 17 | * Creates new StyleDefinition instance. 18 | */ 19 | function StyleDefinition() 20 | { 21 | StyleDefinition.base.prototype.constructor.call(this); 22 | 23 | this._styleMap = Object.create(null); 24 | } 25 | 26 | //Inherit from EventDispatcher 27 | StyleDefinition.prototype = Object.create(EventDispatcher.prototype); 28 | StyleDefinition.prototype.constructor = StyleDefinition; 29 | StyleDefinition.base = EventDispatcher; 30 | 31 | /** 32 | * @event stylechanged StyleChangedEvent 33 | * 34 | * Dispatched when a style is added, cleared, or changed. 35 | */ 36 | 37 | 38 | /** 39 | * @function getStyle 40 | * Gets the stored style value for this object. 41 | * 42 | * @param styleName String 43 | * String representing the style to return. 44 | * 45 | * @returns Any 46 | * Returns the associated style value if found, otherwise undefined. 47 | */ 48 | StyleDefinition.prototype.getStyle = 49 | function (styleName) 50 | { 51 | if (styleName in this._styleMap) 52 | return this._styleMap[styleName]; 53 | 54 | return undefined; 55 | }; 56 | 57 | /** 58 | * @function setStyle 59 | * Sets the stored style value for this object. 60 | * 61 | * @param styleName String 62 | * String representing the style to set. 63 | * 64 | * @param value Any 65 | * The value to store. This may be null or undefined. 66 | * Note that a null style is different from an absent (undefined) style. A null style 67 | * will terminate a style chain lookup and return null value. An undefined style will cause 68 | * the system to look further up the style chain for a value. Passing undefined is the 69 | * same as calling clearStyle(). 70 | */ 71 | StyleDefinition.prototype.setStyle = 72 | function (styleName, value) 73 | { 74 | var oldStyle = undefined; 75 | if (styleName in this._styleMap) 76 | oldStyle = this._styleMap[styleName]; 77 | 78 | //No change 79 | if (oldStyle === value) 80 | return; 81 | 82 | if (this.hasEventListener("stylechanged", null) == true) 83 | { 84 | oldStyle = this.getStyle(styleName); 85 | 86 | if (value === undefined) 87 | delete this._styleMap[styleName]; 88 | else 89 | this._styleMap[styleName] = value; 90 | 91 | var newStyle = this.getStyle(styleName); 92 | 93 | //Strict equality required (undefined !== null) 94 | if (newStyle !== oldStyle) 95 | this.dispatchEvent(new StyleChangedEvent(styleName)); 96 | } 97 | else 98 | { 99 | if (value === undefined) 100 | delete this._styleMap[styleName]; 101 | else 102 | this._styleMap[styleName] = value; 103 | } 104 | }; 105 | 106 | /** 107 | * @function clearStyle 108 | * Clears style data from this object. This is the same 109 | * passing undefined to setStyle(). 110 | * 111 | * @param styleName String 112 | * String representing the style to clear. 113 | */ 114 | StyleDefinition.prototype.clearStyle = 115 | function (styleName) 116 | { 117 | this.setStyle(styleName, undefined); 118 | }; 119 | 120 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/StyleProxy.js: -------------------------------------------------------------------------------- 1 | 2 | /////////////////////////////////////////////////////////////////////////// 3 | ///////////////////////StyleProxy//////////////////////////////////////// 4 | 5 | /** 6 | * @class StyleProxy 7 | * 8 | * Internal class used to wrap CanvasElements to proxy styles to other elements. 9 | * This should only be used by component developers. When a proxy is assigned 10 | * to an element, the proxy is included in its style chain lookup after assigned 11 | * styles (instance, and styleDefinition) but before default styles. 12 | * 13 | * @constructor StyleProxy 14 | * Creates new StyleProxy instance. 15 | * 16 | * @param styleProxyElement CanvasElement 17 | * The element to proxy styles from. 18 | * 19 | * @param styleProxyMap Object 20 | * A map of styleNames to proxy. This Object is walked for members so 21 | * should always be created using a null prototype: Object.create(null) and 22 | * members created for each styleName to proxy (set to true). 23 | * 24 | * MyProxyMap = Object.create(null); 25 | * MyProxyMap.StyleName1 = true; 26 | * MyProxyMap.StyleName2 = true; 27 | * 28 | * MyProxyMap._Arbitrary = true; 29 | * 30 | * _Arbitrary is a special flag that indicates all styles that are not defined / unknown 31 | * by the element will also be proxied. 32 | * 33 | * For example, a Button will proxy several styles to its skins such as "BackgroundFill" by including 34 | * them in the proxy map it passes to its skins. Styles like "Visible" however, are omitted from the proxy 35 | * map. Also, the button sets the _Arbitrary flag so any styles the Button is not aware of and does not define itself, 36 | * are automatically proxied to the skin, without having to be added to the proxy map. 37 | * This is so that skins may have custom styles and still be blanket set by setting the Button style itself. 38 | */ 39 | function StyleProxy(styleProxyElement, styleProxyMap) 40 | { 41 | this._proxyElement = styleProxyElement; 42 | this._proxyMap = styleProxyMap; 43 | } 44 | 45 | //No Inheritance 46 | StyleProxy.prototype.constructor = StyleProxy; 47 | 48 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/TextElement.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends CanvasElement.js 4 | */ 5 | 6 | ///////////////////////////////////////////////////////// 7 | /////////////////TextElement///////////////////////////// 8 | 9 | /** 10 | * @class TextElement 11 | * @inherits CanvasElement 12 | * 13 | * Renders mutli-line style-able select-able text. 14 | * TextElement respects newline characters and will 15 | * wrap text when width is constrained. If only a single 16 | * line of text is needed, LabelElement is more efficient. 17 | * 18 | * @constructor TextElement 19 | * Creates new TextElement instance. 20 | */ 21 | function TextElement() 22 | { 23 | TextElement.base.prototype.constructor.call(this); 24 | 25 | this._textField = new TextFieldElement(); 26 | this._textField.setStyle("Cursor", null); 27 | this._textField.setStyle("TabStop", -1); 28 | this._addChild(this._textField); 29 | } 30 | 31 | //Inherit from CanvasElement 32 | TextElement.prototype = Object.create(CanvasElement.prototype); 33 | TextElement.prototype.constructor = TextElement; 34 | TextElement.base = CanvasElement; 35 | 36 | /////////////Style Types/////////////////////////////// 37 | 38 | TextElement._StyleTypes = Object.create(null); 39 | 40 | /** 41 | * @style Text String 42 | * Text to be rendered by the TextElement. 43 | */ 44 | TextElement._StyleTypes.Text = StyleableBase.EStyleType.NORMAL; // "any string" || null 45 | 46 | /** 47 | * @style Selectable boolean 48 | * When true, text can be highlighted and copied. 49 | */ 50 | TextElement._StyleTypes.Selectable = StyleableBase.EStyleType.NORMAL; // true || false 51 | 52 | /** 53 | * @style Multiline boolean 54 | * When true, newline characters are respected and text will be rendered on multiple lines if necessary. 55 | */ 56 | TextElement._StyleTypes.Multiline = StyleableBase.EStyleType.NORMAL; // true || false 57 | 58 | /** 59 | * @style WordWrap boolean 60 | * When true, text will wrap when width is constrained and will be rendered on multiple lines if necessary. 61 | */ 62 | TextElement._StyleTypes.WordWrap = StyleableBase.EStyleType.NORMAL; // true || false 63 | 64 | 65 | ////////////Default Styles//////////////////////////// 66 | 67 | TextElement.StyleDefault = new StyleDefinition(); 68 | 69 | //Override base class styles 70 | TextElement.StyleDefault.setStyle("PaddingTop", 2); 71 | TextElement.StyleDefault.setStyle("PaddingBottom", 2); 72 | TextElement.StyleDefault.setStyle("PaddingLeft", 2); 73 | TextElement.StyleDefault.setStyle("PaddingRight", 2); 74 | TextElement.StyleDefault.setStyle("TextHorizontalAlign", "left"); 75 | TextElement.StyleDefault.setStyle("TextVerticalAlign", "top"); 76 | TextElement.StyleDefault.setStyle("Cursor", "text"); 77 | 78 | //TextElement specific styles 79 | TextElement.StyleDefault.setStyle("Text", null); 80 | TextElement.StyleDefault.setStyle("Selectable", true); 81 | TextElement.StyleDefault.setStyle("Multiline", true); 82 | TextElement.StyleDefault.setStyle("WordWrap", true); 83 | 84 | 85 | 86 | /////////////Internal Functions/////////////////// 87 | 88 | //@Override 89 | TextElement.prototype._doStylesUpdated = 90 | function (stylesMap) 91 | { 92 | TextElement.base.prototype._doStylesUpdated.call(this, stylesMap); 93 | 94 | if ("Text" in stylesMap) 95 | this._textField.setText(this.getStyle("Text")); 96 | 97 | if ("Selectable" in stylesMap) 98 | this._textField.setStyle("Selectable", this.getStyle("Selectable")); 99 | 100 | if ("Multiline" in stylesMap) 101 | this._textField.setStyle("Multiline", this.getStyle("Multiline")); 102 | 103 | if ("WordWrap" in stylesMap) 104 | this._textField.setStyle("WordWrap", this.getStyle("WordWrap")); 105 | 106 | //Force the textField to use our defaults rather than inherited. 107 | if ("TextHorizontalAlign" in stylesMap) 108 | this._textField.setStyle("TextHorizontalAlign", this.getStyle("TextHorizontalAlign")); 109 | if ("TextVerticalAlign" in stylesMap) 110 | this._textField.setStyle("TextVerticalAlign", this.getStyle("TextVerticalAlign")); 111 | 112 | //Proxy padding to TextField for proper mouse handling 113 | if ("Padding" in stylesMap || 114 | "PaddingTop" in stylesMap || 115 | "PaddingBottom" in stylesMap || 116 | "PaddingLeft" in stylesMap || 117 | "PaddingRight" in stylesMap) 118 | { 119 | var paddingSize = this._getPaddingSize(); 120 | 121 | this._textField.setStyle("PaddingTop", paddingSize.paddingTop); 122 | this._textField.setStyle("PaddingBottom", paddingSize.paddingBottom); 123 | this._textField.setStyle("PaddingLeft", paddingSize.paddingLeft); 124 | this._textField.setStyle("PaddingRight", paddingSize.paddingRight); 125 | } 126 | }; 127 | 128 | //@Override 129 | TextElement.prototype._doMeasure = 130 | function(padWidth, padHeight) 131 | { 132 | //Ignore padding, proxied to TextField 133 | this._setMeasuredSize(this._textField._measuredWidth, this._textField._measuredHeight); 134 | }; 135 | 136 | //@Override 137 | TextElement.prototype._doLayout = 138 | function (paddingMetrics) 139 | { 140 | TextElement.base.prototype._doLayout.call(this, paddingMetrics); 141 | 142 | //Ignore padding, proxied to TextField for mouse handling. 143 | this._textField._setActualPosition(0, 0); 144 | this._textField._setActualSize(this._width, this._height); 145 | }; 146 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/ToggleButtonGroup.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends EventDispatcher.js 4 | */ 5 | 6 | /////////////////////////////////////////////////////////////////// 7 | ///////////////////////ToggleButtonGroup/////////////////////////// 8 | 9 | /** 10 | * @class ToggleButtonGroup 11 | * @inherits EventDispatcher 12 | * 13 | * Convenience helper class for grouping ToggleButtons or subclasses. 14 | * The ToggleButtonGroup can be assigned to set of toggle buttons 15 | * and will only allow a single ToggleButton to be selected at a time. 16 | * When a ToggleButton changes state, the ToggleButtonGroup will dispatch 17 | * a changed event. Use this for functionality like RadioButtons and Tabs. 18 | * 19 | * @constructor ToggleButtonGroup 20 | * Creates new ToggleButtonGroup instance. 21 | */ 22 | function ToggleButtonGroup() 23 | { 24 | ToggleButtonGroup.base.prototype.constructor.call(this); 25 | 26 | this._selectedButton = null; 27 | 28 | this._toggleButtons = []; 29 | 30 | var _self = this; 31 | 32 | this._toggleButtonChangedInstance = 33 | function (event) 34 | { 35 | _self._toggleButtonChanged(event); 36 | }; 37 | } 38 | 39 | //Inherit from EventDispatcher 40 | ToggleButtonGroup.prototype = Object.create(EventDispatcher.prototype); 41 | ToggleButtonGroup.prototype.constructor = ToggleButtonGroup; 42 | ToggleButtonGroup.base = EventDispatcher; 43 | 44 | ////////////Events///////////////////////////////////// 45 | 46 | /** 47 | * @event changed DispatcherEvent 48 | * Dispatched when the selected ToggleButton is changed due to user interaction. 49 | */ 50 | 51 | //////////////Public Functions///////////////////////////////////////// 52 | 53 | /** 54 | * @function addButton 55 | * Adds a ToggleButton or subclass to be managed by ToggleButtonGroup. 56 | * 57 | * @param toggleButton ToggleButtonElement 58 | * ToggleButton or subclass to be managed by ToggleButtonGroup. 59 | * 60 | * @returns boolean 61 | * True when successfully added, false if is not a instance of ToggleButton or already added. 62 | */ 63 | ToggleButtonGroup.prototype.addButton = 64 | function (toggleButton) 65 | { 66 | if (toggleButton == null || 67 | toggleButton instanceof ToggleButtonElement == false || 68 | this._toggleButtons.indexOf(toggleButton) > -1) 69 | return false; 70 | 71 | this._toggleButtons.push(toggleButton); 72 | toggleButton.addEventListener("changed", this._toggleButtonChangedInstance); 73 | 74 | return true; 75 | }; 76 | 77 | /** 78 | * @function removeButton 79 | * Removes a ToggleButton or subclass currently being managed by ToggleButtonGroup 80 | * 81 | * @param toggleButton ToggleButtonElement 82 | * ToggleButton or subclass to be removed from ToggleButtonGroup. 83 | * 84 | * @returns boolean 85 | * True when successfully removed, false if the toggle button is not currently managed by ToggleButtonGroup. 86 | */ 87 | ToggleButtonGroup.prototype.removeButton = 88 | function (toggleButton) 89 | { 90 | var index = this._toggleButtons.indexOf(toggleButton); 91 | 92 | if (index == -1) 93 | return false; 94 | 95 | this._toggleButtons.splice(index, 1); 96 | toggleButton.removeEventListener("changed", this._toggleButtonChangedInstance); 97 | }; 98 | 99 | /** 100 | * @function clearButtons 101 | * Removes all ToggleButtons currently managed by ToggleButtonGroup. 102 | */ 103 | ToggleButtonGroup.prototype.clearButtons = 104 | function () 105 | { 106 | for (var i = 0; i < this._toggleButtons.length; i++) 107 | this._toggleButtons[i].removeEventListener("changed", this._toggleButtonChangedInstance); 108 | 109 | this._toggleButtons = []; 110 | }; 111 | 112 | /** 113 | * @function setSelectedButton 114 | * Sets the ToggleButton to be selected. 115 | * 116 | * @param toggleButton ToggleButtonElement 117 | * ToggleButton or subclass to be selected. May be set to null. 118 | */ 119 | ToggleButtonGroup.prototype.setSelectedButton = 120 | function (toggleButton) 121 | { 122 | if (this._selectedButton == toggleButton) 123 | return; 124 | 125 | if (toggleButton == null || this._toggleButtons.indexOf(toggleButton) > -1) 126 | { 127 | this._selectedButton = toggleButton; 128 | 129 | if (this._selectedButton != null) 130 | this._selectedButton.setSelected(true); 131 | 132 | for (var i = 0; i < this._toggleButtons.length; i++) 133 | { 134 | if (this._toggleButtons[i] != toggleButton) 135 | this._toggleButtons[i].setSelected(false); 136 | } 137 | } 138 | }; 139 | 140 | /** 141 | * @function getSelectedButton 142 | * Gets the selected ToggleButton. 143 | * 144 | * @returns ToggleButtonElement 145 | * ToggleButton or subclass currently selected. May be null. 146 | */ 147 | ToggleButtonGroup.prototype.getSelectedButton = 148 | function () 149 | { 150 | return this._selectedButton; 151 | }; 152 | 153 | ////////////////////Internal///////////////////////// 154 | 155 | 156 | /** 157 | * @function _toggleButtonChanged 158 | * Event handler for managed ToggleButton's "changed" event. 159 | * Updates toggle button selected states and dispatches "changed" event. 160 | * 161 | * @param event ElementEvent 162 | * ElementEvent to be processed. 163 | */ 164 | ToggleButtonGroup.prototype._toggleButtonChanged = 165 | function (elementEvent) 166 | { 167 | var toggleButton = elementEvent.getTarget(); 168 | 169 | if (toggleButton.getSelected() == true) 170 | this._selectedButton = toggleButton; 171 | else 172 | this._selectedButton = null; 173 | 174 | for (var i = 0; i < this._toggleButtons.length; i++) 175 | { 176 | if (this._toggleButtons[i] != toggleButton) 177 | this._toggleButtons[i].setSelected(false); 178 | } 179 | 180 | //Dispatch changed event. 181 | if (this.hasEventListener("changed", null) == true) 182 | this.dispatchEvent(new DispatcherEvent("changed", false)); 183 | }; 184 | 185 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/Tween.js: -------------------------------------------------------------------------------- 1 | 2 | /////////////////////////////////////////////////////// 3 | //////////////////Tween//////////////////////////////// 4 | 5 | /** 6 | * @class Tween 7 | * 8 | * Tween is a helper class that is used to interpolate values 9 | * across a given time span and is essentially just a calculator. 10 | * It can be used for nearly any type of animation and supports 11 | * easing for acceleration and deceleration. 12 | * 13 | * If you're unsure about easing, a hint is that SineInOut is a kind of magic salt 14 | * you can sprinkle on just about any linear animation that usually makes everything 15 | * look smoother and less jarring without being obvious. 16 | * 17 | * @constructor Tween 18 | * Creates new Tween instance. 19 | */ 20 | function Tween() 21 | { 22 | /** 23 | * @member startVal Number 24 | * Beginning value at the start time of the tween. 25 | */ 26 | this.startVal = 0; 27 | 28 | /** 29 | * @member endVal Number 30 | * Ending value at the end time of the tween duration. 31 | */ 32 | this.endVal = 0; 33 | 34 | /** 35 | * @member duration Number 36 | * Duration in milliseconds the tween will run. 37 | */ 38 | this.duration = 0; 39 | 40 | /** 41 | * @member startTime Number 42 | * Time in milliseconds that the tween should start as returned by Date.now(). 43 | */ 44 | this.startTime = null; 45 | 46 | /** 47 | * @member easingFunction Function 48 | * Easing function to use when calculating the tween value. This is used 49 | * to create acceleration/deceleration. Setting this to null will result 50 | * in a linear tween. This is a function that accepts a fraction 51 | * between 0 and 1 and returns a fraction between 0 and 1. The result is used 52 | * to calculate the value based on progress and start/end values. There are several 53 | * standard easing functions built in as static functions of Tween that you can set to this. 54 | */ 55 | this.easingFunction = null; 56 | } 57 | 58 | //Tween is base object, no inheritance. 59 | Tween.prototype.constructor = Tween; 60 | 61 | 62 | /** 63 | * @function getProgress 64 | * Gets the current progress of the tween based on the start time and the current time. 65 | * 66 | * @param time Number 67 | * The current time as returned by Date.now(). 68 | * 69 | * @returns Number 70 | * Fraction between 0 and 1. 71 | */ 72 | Tween.prototype.getProgress = 73 | function (time) 74 | { 75 | if (time >= this.startTime + this.duration) 76 | return 1; 77 | else if (time <= this.startTime) 78 | return 0; 79 | 80 | return (time - this.startTime) / this.duration; 81 | }; 82 | 83 | /** 84 | * @function getValue 85 | * Gets the current value based on the supplied time. 86 | * 87 | * @param time Number 88 | * The current time as returned by Date.now(). 89 | * 90 | * @returns Number 91 | * A number between the start and end values (inclusive). 92 | */ 93 | Tween.prototype.getValue = 94 | function (time) 95 | { 96 | var progress = this.getProgress(time); 97 | 98 | if (progress == 1) 99 | return this.endVal; 100 | else if (progress == 0) 101 | return this.startVal; 102 | 103 | if (this.easingFunction != null) 104 | progress = this.easingFunction(progress); 105 | 106 | var range = Math.abs(this.endVal - this.startVal); 107 | 108 | if (this.startVal < this.endVal) 109 | return this.startVal + (range * progress); 110 | 111 | return this.startVal - (range * progress); 112 | }; 113 | 114 | //////Static////////////////// 115 | 116 | /** 117 | * @function easeInQuad 118 | * @static 119 | * Use for quadratic easing. 120 | * 121 | * @param fraction Number 122 | * A number between 0 and 1. 123 | * 124 | * @returns Number 125 | * A number between 0 and 1. 126 | */ 127 | Tween.easeInQuad = 128 | function (fraction) 129 | { 130 | return fraction * fraction; 131 | }; 132 | 133 | /** 134 | * @function easeOutQuad 135 | * @static 136 | * Use for quadratic easing. 137 | * 138 | * @param fraction Number 139 | * A number between 0 and 1. 140 | * 141 | * @returns Number 142 | * A number between 0 and 1. 143 | */ 144 | Tween.easeOutQuad = 145 | function (fraction) 146 | { 147 | return 1 - Tween.easeInQuad(1 - fraction); 148 | }; 149 | 150 | /** 151 | * @function easeInOutQuad 152 | * @static 153 | * Use for quadratic easing. 154 | * 155 | * @param fraction Number 156 | * A number between 0 and 1. 157 | * 158 | * @returns Number 159 | * A number between 0 and 1. 160 | */ 161 | Tween.easeInOutQuad = 162 | function (fraction) 163 | { 164 | if (fraction < 0.5) 165 | return Tween.easeInQuad(fraction * 2.0) / 2.0; 166 | 167 | return 1 - (Tween.easeInQuad((1 - fraction) * 2.0) / 2.0); 168 | }; 169 | 170 | /** 171 | * @function easeInCubic 172 | * @static 173 | * Use for cubic easing. 174 | * 175 | * @param fraction Number 176 | * A number between 0 and 1. 177 | * 178 | * @returns Number 179 | * A number between 0 and 1. 180 | */ 181 | Tween.easeInCubic = 182 | function (fraction) 183 | { 184 | return Math.pow(fraction, 3); 185 | }; 186 | 187 | /** 188 | * @function easeOutCubic 189 | * @static 190 | * Use for cubic easing. 191 | * 192 | * @param fraction Number 193 | * A number between 0 and 1. 194 | * 195 | * @returns Number 196 | * A number between 0 and 1. 197 | */ 198 | Tween.easeOutCubic = 199 | function (fraction) 200 | { 201 | return 1 - Tween.easeInCubic(1 - fraction); 202 | }; 203 | 204 | /** 205 | * @function easeInOutCubic 206 | * @static 207 | * Use for cubic easing. 208 | * 209 | * @param fraction Number 210 | * A number between 0 and 1. 211 | * 212 | * @returns Number 213 | * A number between 0 and 1. 214 | */ 215 | Tween.easeInOutCubic = 216 | function (fraction) 217 | { 218 | if (fraction < 0.5) 219 | return Tween.easeInCubic(fraction * 2.0) / 2.0; 220 | 221 | return 1 - (Tween.easeInCubic((1 - fraction) * 2.0) / 2.0); 222 | }; 223 | 224 | /** 225 | * @function easeOutSine 226 | * @static 227 | * Use for sine easing. 228 | * 229 | * @param fraction Number 230 | * A number between 0 and 1. 231 | * 232 | * @returns Number 233 | * A number between 0 and 1. 234 | */ 235 | Tween.easeOutSine = 236 | function (fraction) 237 | { 238 | return Math.sin(fraction * (Math.PI / 2.0)); 239 | }; 240 | 241 | /** 242 | * @function easeInSine 243 | * @static 244 | * Use for sine easing. 245 | * 246 | * @param fraction Number 247 | * A number between 0 and 1. 248 | * 249 | * @returns Number 250 | * A number between 0 and 1. 251 | */ 252 | Tween.easeInSine = 253 | function (fraction) 254 | { 255 | return 1 - Tween.easeOutSine(1 - fraction); 256 | }; 257 | 258 | /** 259 | * @function easeInOutSine 260 | * @static 261 | * Use for sine easing. 262 | * 263 | * @param fraction Number 264 | * A number between 0 and 1. 265 | * 266 | * @returns Number 267 | * A number between 0 and 1. 268 | */ 269 | Tween.easeInOutSine = 270 | function (fraction) 271 | { 272 | if (fraction < 0.5) 273 | return Tween.easeInSine(fraction * 2.0) / 2.0; 274 | 275 | return 1 - (Tween.easeInSine((1 - fraction) * 2.0) / 2.0); 276 | }; 277 | 278 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/containers/GridContainerRowColumnDefinition.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @depends StyleableBase.js 3 | */ 4 | 5 | /////////////////////////////////////////////////////////////////////////// 6 | /////////////////GridContainerRowColumnDefinition////////////////////////// 7 | 8 | /** 9 | * @class GridContainerRowColumnDefinition 10 | * @inherits StyleableBase 11 | * 12 | * GridContainerRowColumnDefinition defines and stores styles used by 13 | * the GridContainerElement to layout rows and columns. 14 | * 15 | * @constructor GridContainerRowColumnDefinition 16 | * Creates new GridContainerRowColumnDefinition instance. 17 | */ 18 | 19 | function GridContainerRowColumnDefinition() 20 | { 21 | GridContainerRowColumnDefinition.base.prototype.constructor.call(this); 22 | } 23 | 24 | //Inherit from StyleableBase 25 | GridContainerRowColumnDefinition.prototype = Object.create(StyleableBase.prototype); 26 | GridContainerRowColumnDefinition.prototype.constructor = GridContainerRowColumnDefinition; 27 | GridContainerRowColumnDefinition.base = StyleableBase; 28 | 29 | 30 | /////////////Style Types/////////////////////////////// 31 | 32 | GridContainerRowColumnDefinition._StyleTypes = Object.create(null); 33 | 34 | /** 35 | * @style Size Number 36 | * 37 | * Size in pixels this row or column should consume. This style overrides all other sizing styles. 38 | */ 39 | GridContainerRowColumnDefinition._StyleTypes.Size = StyleableBase.EStyleType.NORMAL; // number 40 | 41 | /** 42 | * @style PercentSize Number 43 | * 44 | * The percentage of available size the row or column should consume relative to its parent GridContainer. 45 | * Note that percentage width is calculated based on the available space left over *after* static sized rows 46 | * and columns are considered. Percentages are allowed to add to more than 100 and will consume all of the 47 | * available space. When percents add to more than 100 the elements will share the available space 48 | * per the ratio of percent vs total percent used. 49 | */ 50 | GridContainerRowColumnDefinition._StyleTypes.PercentSize = StyleableBase.EStyleType.NORMAL; // number || null 51 | 52 | /** 53 | * @style MinSize Number 54 | * 55 | * Minimum number of pixels the row or column should consume. 56 | * This does not affect rows or columns that have the Size style set. 57 | */ 58 | GridContainerRowColumnDefinition._StyleTypes.MinSize = StyleableBase.EStyleType.NORMAL; // number || null 59 | 60 | /** 61 | * @style MaxSize Number 62 | * 63 | * Maximum number of pixels the row or column should consume. 64 | * This does not affect rows or columns that have the Size style set. 65 | */ 66 | GridContainerRowColumnDefinition._StyleTypes.MaxSize = StyleableBase.EStyleType.NORMAL; // number || null 67 | 68 | /** 69 | * @style StretchPriority Number 70 | * 71 | * When rows or columns are forced to stretch due to cells spanning multiple rows or columns, 72 | * rows or columns with the highest StretchPriority will stretch first, equal priorities will stretch evenly. 73 | * This does not affect rows or columns that have Size or PercentSize styles set. 74 | */ 75 | GridContainerRowColumnDefinition._StyleTypes.StretchPriority = StyleableBase.EStyleType.NORMAL; // number || null 76 | 77 | 78 | ////////////Default Styles//////////////////////////// 79 | 80 | GridContainerRowColumnDefinition.StyleDefault = new StyleDefinition(); 81 | 82 | GridContainerRowColumnDefinition.StyleDefault.setStyle("Size", null); 83 | GridContainerRowColumnDefinition.StyleDefault.setStyle("PercentSize", null); 84 | GridContainerRowColumnDefinition.StyleDefault.setStyle("MinSize", null); 85 | GridContainerRowColumnDefinition.StyleDefault.setStyle("MaxSize", null); 86 | GridContainerRowColumnDefinition.StyleDefault.setStyle("StretchPriority", 0); 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/dataContainers/DataGridColumnDefinition.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends StyleableBase.js 4 | * @depends DataGridHeaderItemRenderer.js 5 | * @depends DataGridLabelItemRenderer.js 6 | */ 7 | 8 | /////////////////////////////////////////////////////////////////////// 9 | ///////////////////DataGridColumnDefinition//////////////////////////// 10 | 11 | /** 12 | * @class DataGridColumnDefinition 13 | * @inherits StyleableBase 14 | * 15 | * DataGridColumnDefinition defines and stores styles necessary for the DataGrid to render columns. 16 | * 17 | * The default HeaderItemClass is DataGridHeaderItemRenderer. 18 | * The default RowItemClass is DataGridLabelItemRenderer. 19 | * 20 | * 21 | * @seealso DataGridElement 22 | * @seealso DataGridHeaderItemRenderer 23 | * @seealso DataGridLabelItemRenderer 24 | * 25 | * @constructor DataGridColumnDefinition 26 | * Creates new DataGridColumnDefinition instance. 27 | */ 28 | function DataGridColumnDefinition() 29 | { 30 | DataGridColumnDefinition.base.prototype.constructor.call(this); 31 | 32 | //Set a default alphabetical sort. Need a different sort instance for each column. 33 | this.setStyle("CollectionSort", new CollectionSort(function (objA, objB) { return objA.col2 < objB.col2 ? -1 : objA.col2 > objB.col2 ? 1 : 0; })); 34 | } 35 | 36 | //Inherit from StyleableBase 37 | DataGridColumnDefinition.prototype = Object.create(StyleableBase.prototype); 38 | DataGridColumnDefinition.prototype.constructor = DataGridColumnDefinition; 39 | DataGridColumnDefinition.base = StyleableBase; 40 | 41 | /////////////Style Types/////////////////////////////// 42 | 43 | DataGridColumnDefinition._StyleTypes = Object.create(null); 44 | 45 | /** 46 | * @style PercentSize Number 47 | * 48 | * The percentage of available space the column should consume. Percentages 49 | * are allowed to add to more than 100 and will consume all of the available space. 50 | */ 51 | DataGridColumnDefinition._StyleTypes.PercentSize = StyleableBase.EStyleType.NORMAL; // number || null 52 | 53 | /** 54 | * @style MinSize Number 55 | * 56 | * Minimum number of pixels the column should consume. 57 | */ 58 | DataGridColumnDefinition._StyleTypes.MinSize = StyleableBase.EStyleType.NORMAL; // number || null 59 | 60 | /** 61 | * @style HeaderText String 62 | * Text label to be used for the column header. 63 | */ 64 | DataGridColumnDefinition._StyleTypes.HeaderText = StyleableBase.EStyleType.NORMAL; // "string" 65 | 66 | /** 67 | * @style HeaderItemClass CanvasElement 68 | * 69 | * The DataRenderer CanvasElement constructor to be used for the column header. 70 | */ 71 | DataGridColumnDefinition._StyleTypes.HeaderItemClass = StyleableBase.EStyleType.NORMAL; // Element constructor() 72 | 73 | /** 74 | * @style HeaderItemStyle StyleDefinition 75 | * 76 | * The StyleDefinition or [StyleDefinition] array to apply to the HeaderItem DataRenderer. 77 | */ 78 | DataGridColumnDefinition._StyleTypes.HeaderItemStyle = StyleableBase.EStyleType.SUBSTYLE; // StyleDefinition 79 | 80 | /** 81 | * @style CollectionSort CollectionSort 82 | * 83 | * CollectionSort to be used to sort the column. 84 | * Default column sort uses alphabetic compare. 85 | * You may null this style to prevent the column from sorting, and / or disable the column header button. 86 | */ 87 | DataGridColumnDefinition._StyleTypes.CollectionSort = StyleableBase.EStyleType.NORMAL; // CollectionSort() 88 | 89 | /** 90 | * @style RowItemClass CanvasElement 91 | * 92 | * The DataRenderer CanvasElement constructor to be used for this columns rows. 93 | */ 94 | DataGridColumnDefinition._StyleTypes.RowItemClass = StyleableBase.EStyleType.NORMAL; // Element constructor() 95 | 96 | /** 97 | * @style RowItemStyle StyleDefinition 98 | * 99 | * The StyleDefinition or [StyleDefinition] array to apply to the RowItem DataRenderer. 100 | */ 101 | DataGridColumnDefinition._StyleTypes.RowItemStyle = StyleableBase.EStyleType.SUBSTYLE; // StyleDefinition 102 | 103 | /** 104 | * @style RowItemLabelFunction Function 105 | * 106 | * A function that returns a text string per a supplied collection item and columnIndex. 107 | * function (itemData, columnIndex) { return "" } 108 | */ 109 | DataGridColumnDefinition._StyleTypes.RowItemLabelFunction = StyleableBase.EStyleType.NORMAL; // function (data, columnIndex) { return "" } 110 | 111 | /** 112 | * @style SelectionType string 113 | * 114 | * Determines the selection type that the column will use. Allowable values are "row", "column", or "cell". 115 | * Row selection will only affect other columns also set to "row". 116 | */ 117 | DataGridColumnDefinition._StyleTypes.SelectionType = StyleableBase.EStyleType.NORMAL; 118 | 119 | /** 120 | * @style Selectable boolean 121 | * 122 | * When true, items in this column can be selected and the DataGrid will dispatch "changed" events. 123 | * When SelectionType is set to "row" or "column", related items will also be set to a "selected" state. 124 | */ 125 | DataGridColumnDefinition._StyleTypes.Selectable = StyleableBase.EStyleType.NORMAL; // true || false 126 | 127 | /** 128 | * @style Highlightable boolean 129 | * 130 | * When true, items in this column will be highlighted on mouseover, "over" state. 131 | * When SelectionType is set to "row" or "column", related items will also be set to an "over" state. 132 | */ 133 | DataGridColumnDefinition._StyleTypes.Highlightable = StyleableBase.EStyleType.NORMAL; // true || false 134 | 135 | 136 | 137 | /////////Default Styles/////////////////////////////// 138 | 139 | DataGridColumnDefinition.StyleDefault = new StyleDefinition(); 140 | 141 | DataGridColumnDefinition.StyleDefault.setStyle("PercentSize", 100); // number || null 142 | DataGridColumnDefinition.StyleDefault.setStyle("MinSize", 12); // number || null 143 | DataGridColumnDefinition.StyleDefault.setStyle("SelectionType", "row"); // "row" || "column" || "cell" 144 | DataGridColumnDefinition.StyleDefault.setStyle("Selectable", true); // true || false 145 | DataGridColumnDefinition.StyleDefault.setStyle("Highlightable", true); // true || false 146 | 147 | DataGridColumnDefinition.StyleDefault.setStyle("HeaderText", ""); // "string" 148 | DataGridColumnDefinition.StyleDefault.setStyle("HeaderItemClass", DataGridHeaderItemRenderer); // Element constructor() 149 | DataGridColumnDefinition.StyleDefault.setStyle("HeaderItemStyle", null); // StyleDefinition 150 | DataGridColumnDefinition.StyleDefault.setStyle("CollectionSort", null); 151 | 152 | DataGridColumnDefinition.StyleDefault.setStyle("RowItemClass", DataGridLabelItemRenderer); // Element constructor() 153 | DataGridColumnDefinition.StyleDefault.setStyle("RowItemStyle", null); // StyleDefinition 154 | DataGridColumnDefinition.StyleDefault.setStyle("RowItemLabelFunction", null); // function (data, columnIndex) { return "" } 155 | 156 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/dataContainers/DataGridDataRenderer.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends CanvasElement.js 4 | */ 5 | 6 | /////////////////////////////////////////////////////////////////////// 7 | ///////////////////////DataGridDataRenderer//////////////////////////// 8 | 9 | /** 10 | * @class DataGridDataRenderer 11 | * @inherits CanvasElement 12 | * 13 | * Default DataGrid ListItemClass used to render DataGrid rows. Renders 14 | * column items per the parent DataGrid's column definitions. 15 | * 16 | * @constructor DataGridDataRenderer 17 | * Creates new DataGridDataRenderer instance. 18 | */ 19 | 20 | //Used to render the DataGrid rows. 21 | function DataGridDataRenderer() 22 | { 23 | DataGridDataRenderer.base.prototype.constructor.call(this); 24 | 25 | //Use a containing element for the renderers so we dont interfere with our skins. 26 | this._itemRenderersContainer = new CanvasElement(); 27 | this._addChild(this._itemRenderersContainer); 28 | 29 | var _self = this; 30 | 31 | this._onItemRenderersContainerMeasureCompleteInstance = 32 | function (event) 33 | { 34 | _self.__onItemRenderersContainerMeasureComplete(event); 35 | }; 36 | 37 | this._itemRenderersContainer.addEventListener("measurecomplete", this._onItemRenderersContainerMeasureCompleteInstance); 38 | } 39 | 40 | //Inherit from CanvasElement 41 | DataGridDataRenderer.prototype = Object.create(CanvasElement.prototype); 42 | DataGridDataRenderer.prototype.constructor = DataGridDataRenderer; 43 | DataGridDataRenderer.base = CanvasElement; 44 | 45 | //@private 46 | DataGridDataRenderer.prototype.__onItemRenderersContainerMeasureComplete = 47 | function (event) 48 | { 49 | this._invalidateMeasure(); 50 | this._invalidateLayout(); 51 | }; 52 | 53 | //@Override 54 | DataGridDataRenderer.prototype._setListData = 55 | function (listData, itemData) 56 | { 57 | DataGridDataRenderer.base.prototype._setListData.call(this, listData, itemData); 58 | 59 | var renderer = null; 60 | for (var i = 0; i < listData._parentList._gridColumns.length; i++) 61 | { 62 | renderer = this._itemRenderersContainer._getChildAt(i); 63 | 64 | if (renderer == null) 65 | { 66 | renderer = listData._parentList._createRowItemRenderer(listData._itemIndex, i); 67 | this._itemRenderersContainer._addChildAt(renderer, i); 68 | } 69 | else 70 | { 71 | columnDef = listData._parentList._gridColumns[i]; 72 | 73 | if (renderer.constructor != columnDef.getStyle("RowItemClass")) 74 | { //Renderer Class changed 75 | 76 | this._itemRenderersContainer._removeChildAt(i); 77 | renderer = listData._parentList._createRowItemRenderer(listData._itemIndex, i); 78 | this._itemRenderersContainer._addChildAt(renderer, i); 79 | } 80 | else 81 | { //Update DataGridData 82 | 83 | listData._parentList._updateRowItemRendererData(renderer, listData._itemIndex, i); 84 | } 85 | } 86 | } 87 | 88 | //Purge excess renderers. 89 | while (this._itemRenderersContainer._children.length > this._listData._parentList._gridColumns.length) 90 | this._itemRenderersContainer._removeChildAt(this._itemRenderersContainer._children.length - 1); 91 | }; 92 | 93 | //@override 94 | DataGridDataRenderer.prototype._setListSelected = 95 | function (selectedData) 96 | { 97 | DataGridDataRenderer.base.prototype._setListSelected.call(this, selectedData); 98 | 99 | var columnData; 100 | var columnSelectionType; 101 | var columnSelectable; 102 | var columnHighlightable; 103 | var itemRenderer; 104 | var itemRendererSelectedData; 105 | 106 | var overColumn = null; 107 | if (selectedData.columnOverIndex >= 0 && selectedData.columnOverIndex < this._listData._parentList._gridColumns.length) 108 | overColumn = this._listData._parentList._gridColumns[selectedData.columnOverIndex]; 109 | 110 | var overColumnSelectionType = null; 111 | if (overColumn != null) 112 | overColumnSelectionType = overColumn.getStyle("SelectionType"); 113 | 114 | for (var i = 0; i < this._itemRenderersContainer._children.length; i++) 115 | { 116 | columnData = this._listData._parentList._gridColumns[i]; 117 | columnSelectionType = columnData.getStyle("SelectionType"); 118 | columnSelectable = columnData.getStyle("Selectable"); 119 | columnHighlightable = columnData.getStyle("Highlightable"); 120 | itemRenderer = this._itemRenderersContainer._getChildAt(i); 121 | 122 | //Optimize, use existing data if available 123 | itemRendererSelectedData = itemRenderer._listSelected; 124 | if (itemRendererSelectedData == null) 125 | itemRendererSelectedData = {highlight:false, selected:false}; 126 | else 127 | { 128 | itemRendererSelectedData.highlight = false; 129 | itemRendererSelectedData.selected = false; 130 | } 131 | 132 | if (columnSelectable == true) 133 | { 134 | if ((columnSelectionType == "row" && selectedData.rowIndex == this._listData._itemIndex && selectedData.columnIndex == -1) || 135 | (columnSelectionType == "column" && i == selectedData.columnIndex) || 136 | (columnSelectionType == "cell" && i == selectedData.columnIndex && this._listData._itemIndex == selectedData.rowIndex)) 137 | { 138 | itemRendererSelectedData.selected = true; 139 | } 140 | } 141 | 142 | if (columnHighlightable == true) 143 | { 144 | if ((columnSelectionType == "row" && selectedData.rowOverIndex == this._listData._itemIndex && overColumnSelectionType == "row") || 145 | (columnSelectionType == "column" && i == selectedData.columnOverIndex) || 146 | (columnSelectionType == "cell" && i == selectedData.columnOverIndex && this._listData._itemIndex == selectedData.rowOverIndex)) 147 | { 148 | itemRendererSelectedData.highlight = true; 149 | } 150 | } 151 | 152 | itemRenderer._setListSelected(itemRendererSelectedData); 153 | } 154 | }; 155 | 156 | //@Override 157 | DataGridDataRenderer.prototype._doMeasure = 158 | function(padWidth, padHeight) 159 | { 160 | var measuredWidth = 0; 161 | var measuredHeight = 0; 162 | 163 | var childSize = 0; 164 | 165 | for (var i = 0; i < this._itemRenderersContainer._children.length; i++) 166 | { 167 | childSize = this._itemRenderersContainer._children[i]._getStyledOrMeasuredHeight(); 168 | 169 | if (measuredHeight < childSize) 170 | measuredHeight = childSize; 171 | 172 | measuredWidth += this._itemRenderersContainer._children[i]._getStyledOrMeasuredWidth(); 173 | } 174 | 175 | measuredWidth += padWidth; 176 | measuredHeight += padHeight; 177 | 178 | this._setMeasuredSize(measuredWidth, measuredHeight); 179 | }; 180 | 181 | //@Override 182 | DataGridDataRenderer.prototype._doLayout = 183 | function (paddingMetrics) 184 | { 185 | DataGridDataRenderer.base.prototype._doLayout.call(this, paddingMetrics); 186 | 187 | if (this._listData == null) 188 | return; 189 | 190 | this._itemRenderersContainer._setActualPosition(paddingMetrics.getX(), paddingMetrics.getY()); 191 | this._itemRenderersContainer._setActualSize(paddingMetrics.getWidth(), paddingMetrics.getHeight()); 192 | 193 | var parentGrid = this._listData._parentList; 194 | var rowItemRenderer = null; 195 | var currentPosition = 0; 196 | var columnSize = 0; 197 | 198 | var paddingSize = this._getPaddingSize(); 199 | 200 | for (var i = 0; i < parentGrid._columnSizes.length; i++) 201 | { 202 | rowItemRenderer = this._itemRenderersContainer._children[i]; 203 | columnSize = parentGrid._columnSizes[i]; 204 | 205 | if (i == 0) 206 | columnSize -= paddingSize.paddingLeft; 207 | else if (i == parentGrid._columnSizes.length - 1) //Consume the rest available. 208 | columnSize = this._itemRenderersContainer._width - currentPosition; 209 | 210 | rowItemRenderer._setActualPosition(currentPosition, 0); 211 | rowItemRenderer._setActualSize(columnSize, this._itemRenderersContainer._height); 212 | 213 | currentPosition += columnSize; 214 | } 215 | }; 216 | 217 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/dataContainers/DataGridItemData.js: -------------------------------------------------------------------------------- 1 | 2 | /////////////////////////////////////////////////////////////////////// 3 | ///////////////////////DataGridItemData//////////////////////////////// 4 | 5 | /** 6 | * @class DataGridItemData 7 | * 8 | * Internal data storage class passed to CanvasElements when they are used as 9 | * DataRenderers for a DataGrid. 10 | * 11 | * 12 | * @constructor DataGridItemData 13 | * Creates new DataGridItemData instance. 14 | * 15 | * @param parentGrid DataGridElement 16 | * The parent DataListElement or subclass. 17 | * 18 | * @param itemIndex int 19 | * The Collection item index. 20 | * 21 | * @param columnIndex int 22 | * The column index associated with the DataGrid renderer. 23 | */ 24 | function DataGridItemData(parentGrid, itemIndex, columnIndex) 25 | { 26 | /** 27 | * @member _parentGrid DataGridElement 28 | * Read Only - The parent DataGridElement or subclass. 29 | */ 30 | this._parentGrid = parentGrid; 31 | 32 | /** 33 | * @member _itemIndex int 34 | * Read Only - The Collection item index. 35 | */ 36 | this._itemIndex = itemIndex; 37 | 38 | /** 39 | * @member _columnIndex int 40 | * Read Only - Column index associated with the DataGrid renderer. 41 | */ 42 | this._columnIndex = columnIndex; 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/dataContainers/DataGridItemRendererBase.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends DataRendererBaseElement.js 4 | */ 5 | 6 | /////////////////////////////////////////////////////////////////////// 7 | ////////////////////DataGridItemRendererBase//////////////////////// 8 | 9 | /** 10 | * @class DataGridItemRendererBase 11 | * @inherits DataRendererBaseElement 12 | * 13 | * Abstract base class for DataGrid row item rendering. Any CanvasElement 14 | * can be a data renderer. This class is just here for convenience as it 15 | * implements some commonly used functionality if you wish to subclass it. 16 | * 17 | * Adds skin states and styles for "up", "alt", "over", and "selected" states. 18 | * 19 | * @constructor DataGridItemRendererBase 20 | * Creates new DataGridItemRendererBase instance. 21 | */ 22 | function DataGridItemRendererBase() 23 | { 24 | DataGridItemRendererBase.base.prototype.constructor.call(this); 25 | } 26 | 27 | //Inherit from DataRendererBaseElement 28 | DataGridItemRendererBase.prototype = Object.create(DataRendererBaseElement.prototype); 29 | DataGridItemRendererBase.prototype.constructor = DataGridItemRendererBase; 30 | DataGridItemRendererBase.base = DataRendererBaseElement; 31 | 32 | DataGridItemRendererBase.UpSkinStyleDefault = new StyleDefinition(); 33 | DataGridItemRendererBase.UpSkinStyleDefault.setStyle("BackgroundFill", "#FFFFFF"); 34 | 35 | DataGridItemRendererBase.AltSkinStyleDefault = new StyleDefinition(); 36 | DataGridItemRendererBase.AltSkinStyleDefault.setStyle("BackgroundFill", "#F0F0F0"); 37 | 38 | DataGridItemRendererBase.StyleDefault = new StyleDefinition(); 39 | DataGridItemRendererBase.StyleDefault.setStyle("UpSkinStyle", DataGridItemRendererBase.UpSkinStyleDefault); 40 | DataGridItemRendererBase.StyleDefault.setStyle("AltSkinStyle", DataGridItemRendererBase.AltSkinStyleDefault); 41 | 42 | 43 | /////////////Internal/////////////////////////// 44 | 45 | //@override 46 | DataGridItemRendererBase.prototype._updateState = 47 | function () 48 | { 49 | DataGridItemRendererBase.base.prototype._updateState.call(this); 50 | 51 | if (this._listSelected != null && this._listSelected.selected == true) 52 | newState = "selected"; 53 | else if (this._listSelected != null && this._listSelected.highlight == true) 54 | newState = "over"; 55 | else 56 | { 57 | if (this._listData == null || this._listData._itemIndex % 2 == 0) 58 | newState = "up"; 59 | else 60 | newState = "alt"; 61 | } 62 | 63 | this.setStyle("SkinState", newState); 64 | }; 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/dataContainers/DataGridLabelItemRenderer.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends DataGridItemRendererBase.js 4 | */ 5 | 6 | /////////////////////////////////////////////////////////////////////// 7 | ///////////////////DataGridLabelItemRenderer///////////////////////// 8 | 9 | /** 10 | * @class DataGridLabelItemRenderer 11 | * @inherits DataGridItemRendererBase 12 | * 13 | * DataGrid ItemRenderer for a basic label. Updates label text via 14 | * DataGridColumnDefiniton RowItemLabelFunction. 15 | * 16 | * @constructor DataGridLabelItemRenderer 17 | * Creates new DataGridLabelItemRenderer instance. 18 | */ 19 | function DataGridLabelItemRenderer() 20 | { 21 | DataGridLabelItemRenderer.base.prototype.constructor.call(this); 22 | 23 | this._labelElement = new LabelElement(); 24 | this._labelElement.setStyle("Padding", 0); //Wipe out default padding (no doubly padding, only this elements padding is necessary) 25 | 26 | this._addChild(this._labelElement); 27 | } 28 | 29 | //Inherit from LabelElement 30 | DataGridLabelItemRenderer.prototype = Object.create(DataGridItemRendererBase.prototype); 31 | DataGridLabelItemRenderer.prototype.constructor = DataGridLabelItemRenderer; 32 | DataGridLabelItemRenderer.base = DataGridItemRendererBase; 33 | 34 | 35 | /////////////Style Types///////////////////////// 36 | 37 | DataGridLabelItemRenderer._StyleTypes = Object.create(null); 38 | 39 | /** 40 | * @style UpTextColor String 41 | * 42 | * Hex color value to be used for the label when in the "up" state. Format like "#FF0000" (red). 43 | * This will override the TextColor style of equal priority. 44 | */ 45 | DataGridLabelItemRenderer._StyleTypes.UpTextColor = StyleableBase.EStyleType.NORMAL; //"#000000" 46 | 47 | /** 48 | * @style AltTextColor String 49 | * 50 | * Hex color value to be used for the label when in the "alt" state. Format like "#FF0000" (red). 51 | * This will override the TextColor style of equal priority. 52 | */ 53 | DataGridLabelItemRenderer._StyleTypes.AltTextColor = StyleableBase.EStyleType.NORMAL; //"#000000" 54 | 55 | /** 56 | * @style OverTextColor String 57 | * 58 | * Hex color value to be used for the label when in the "over" state. Format like "#FF0000" (red). 59 | * This will override the TextColor style of equal priority. 60 | */ 61 | DataGridLabelItemRenderer._StyleTypes.OverTextColor = StyleableBase.EStyleType.NORMAL; //"#000000" 62 | 63 | /** 64 | * @style SelectedTextColor String 65 | * 66 | * Hex color value to be used for the label when in the "selected" state. Format like "#FF0000" (red). 67 | * This will override the TextColor style of equal priority. 68 | */ 69 | DataGridLabelItemRenderer._StyleTypes.SelectedTextColor = StyleableBase.EStyleType.NORMAL; //"#000000" 70 | 71 | 72 | ////////////Default Styles/////////////////////// 73 | 74 | DataGridLabelItemRenderer.StyleDefault = new StyleDefinition(); 75 | 76 | DataGridLabelItemRenderer.StyleDefault.setStyle("PaddingTop", 4); 77 | DataGridLabelItemRenderer.StyleDefault.setStyle("PaddingBottom", 4); 78 | DataGridLabelItemRenderer.StyleDefault.setStyle("PaddingLeft", 4); 79 | DataGridLabelItemRenderer.StyleDefault.setStyle("PaddingRight", 4); 80 | 81 | DataGridLabelItemRenderer.StyleDefault.setStyle("UpTextColor", "#000000"); 82 | DataGridLabelItemRenderer.StyleDefault.setStyle("AltTextColor", "#000000"); 83 | DataGridLabelItemRenderer.StyleDefault.setStyle("OverTextColor", "#000000"); 84 | DataGridLabelItemRenderer.StyleDefault.setStyle("SelectedTextColor", "#000000"); 85 | 86 | 87 | ////////////Internal///////////////////////////// 88 | 89 | //@Override 90 | DataGridLabelItemRenderer.prototype._changeState = 91 | function (state) 92 | { 93 | DataGridLabelItemRenderer.base.prototype._changeState.call(this, state); 94 | 95 | this._updateLabelTextColor(); 96 | }; 97 | 98 | /** 99 | * @function _getTextColor 100 | * Gets the text color style for the supplied state. 101 | * 102 | * @param state String 103 | * The current state. 104 | * 105 | * @returns String 106 | * Text color style for the supplied state. 107 | */ 108 | DataGridLabelItemRenderer.prototype._getTextColor = 109 | function (state) 110 | { 111 | var stateTextColor = null; 112 | 113 | if (state == "up") 114 | stateTextColor = this.getStyleData("UpTextColor"); 115 | else if (state == "alt") 116 | stateTextColor = this.getStyleData("AltTextColor"); 117 | else if (state == "over") 118 | stateTextColor = this.getStyleData("OverTextColor"); 119 | else if (state == "selected") 120 | stateTextColor = this.getStyleData("SelectedTextColor"); 121 | 122 | var textColor = this.getStyleData("TextColor"); 123 | 124 | //Shouldnt have null stateTextColor 125 | if (stateTextColor == null || textColor.comparePriority(stateTextColor) > 0) //Use textColor if higher priority 126 | return textColor.value; 127 | 128 | return stateTextColor.value; 129 | }; 130 | 131 | /** 132 | * @function _updateLabelTextColor 133 | * Updates the text color for the current state. 134 | */ 135 | DataGridLabelItemRenderer.prototype._updateLabelTextColor = 136 | function () 137 | { 138 | var color = this._getTextColor(this._currentSkinState); 139 | if (color != null) 140 | this._labelElement.setStyle("TextColor", color); 141 | }; 142 | 143 | /** 144 | * @function _updateLabelTextColor 145 | * Updates the label text base on the DataGrid data and column RowItemLabelFunction. 146 | */ 147 | DataGridLabelItemRenderer.prototype._updateLabelText = 148 | function () 149 | { 150 | if (this._itemData == null || this._listData == null) 151 | this._labelElement.setStyle("Text", ""); 152 | else 153 | { 154 | var parentGrid = this._listData._parentGrid; 155 | var columnDefinition = parentGrid._gridColumns[this._listData._columnIndex]; 156 | var labelFunction = columnDefinition.getStyle("RowItemLabelFunction"); 157 | 158 | this._labelElement.setStyle("Text", labelFunction(this._itemData, this._listData._columnIndex)); 159 | } 160 | }; 161 | 162 | //@override 163 | DataGridLabelItemRenderer.prototype._setListData = 164 | function (listData, itemData) 165 | { 166 | DataGridLabelItemRenderer.base.prototype._setListData.call(this, listData, itemData); 167 | 168 | this._updateLabelText(); 169 | }; 170 | 171 | //@override 172 | DataGridLabelItemRenderer.prototype._doStylesUpdated = 173 | function (stylesMap) 174 | { 175 | DataGridLabelItemRenderer.base.prototype._doStylesUpdated.call(this, stylesMap); 176 | 177 | this._updateLabelTextColor(); 178 | }; 179 | 180 | //@override 181 | DataGridLabelItemRenderer.prototype._doMeasure = 182 | function(padWidth, padHeight) 183 | { 184 | this._setMeasuredSize(this._labelElement._getStyledOrMeasuredWidth() + padWidth, 185 | this._labelElement._getStyledOrMeasuredHeight() + padHeight); 186 | }; 187 | 188 | //@override 189 | DataGridLabelItemRenderer.prototype._doLayout = 190 | function (paddingMetrics) 191 | { 192 | DataGridLabelItemRenderer.base.prototype._doLayout.call(this, paddingMetrics); 193 | 194 | this._labelElement._setActualPosition(paddingMetrics.getX(), paddingMetrics.getY()); 195 | this._labelElement._setActualSize(paddingMetrics.getWidth(), paddingMetrics.getHeight()); 196 | }; 197 | 198 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/dataContainers/DataListData.js: -------------------------------------------------------------------------------- 1 | 2 | /////////////////////////////////////////////////////////////////////// 3 | ///////////////////////DataListData//////////////////////////////////// 4 | 5 | /** 6 | * @class DataListData 7 | * 8 | * Internal data storage class passed to CanvasElements when they are used as 9 | * DataRenderers for a DataListElement or subclass. 10 | * 11 | * 12 | * @constructor DataListData 13 | * Creates new DataListData instance. 14 | * 15 | * @param parentList DataListElement 16 | * The parent DataListElement or subclass. 17 | * 18 | * @param itemIndex int 19 | * The Collection item index. 20 | */ 21 | function DataListData(parentList, itemIndex) 22 | { 23 | /** 24 | * @member _parentList DataListElement 25 | * Read Only - The parent DataListElement or subclass. 26 | */ 27 | this._parentList = parentList; 28 | 29 | /** 30 | * @member _itemIndex int 31 | * Read Only - The Collection item index. 32 | */ 33 | this._itemIndex = itemIndex; 34 | }; -------------------------------------------------------------------------------- /src/FlexCanvasJS/dataContainers/DataRendererLabelElement.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends DataRendererBaseElement.js 4 | */ 5 | 6 | /////////////////////////////////////////////////////////////////////// 7 | ///////////////////////DataRendererLabelElement//////////////////////// 8 | 9 | /** 10 | * @class DataRendererLabelElement 11 | * @inherits DataRendererBaseElement 12 | * 13 | * DataList DataRenderer for a basic label. 14 | * Adds text color styles for DataRenderer states and 15 | * sets label text when the parent DataList sets our list data. 16 | * 17 | * @constructor DataRendererLabelElement 18 | * Creates new DataRendererLabelElement instance. 19 | */ 20 | function DataRendererLabelElement() 21 | { 22 | DataRendererLabelElement.base.prototype.constructor.call(this); 23 | 24 | this._labelElement = new LabelElement(); 25 | this._labelElement.setStyle("Padding", 0); //Wipe out default padding (no doubly padding, only this elements padding is necessary) 26 | 27 | this._addChild(this._labelElement); 28 | } 29 | 30 | //Inherit from DataRendererBaseElement 31 | DataRendererLabelElement.prototype = Object.create(DataRendererBaseElement.prototype); 32 | DataRendererLabelElement.prototype.constructor = DataRendererLabelElement; 33 | DataRendererLabelElement.base = DataRendererBaseElement; 34 | 35 | 36 | /////////////Style Types///////////////////////// 37 | 38 | DataRendererLabelElement._StyleTypes = Object.create(null); 39 | 40 | /** 41 | * @style UpTextColor String 42 | * 43 | * Hex color value to be used for the label when in the "up" state. Format like "#FF0000" (red). 44 | * This will override the TextColor style of equal priority. 45 | */ 46 | DataRendererLabelElement._StyleTypes.UpTextColor = StyleableBase.EStyleType.NORMAL; //"#000000" 47 | 48 | /** 49 | * @style AltTextColor String 50 | * 51 | * Hex color value to be used for the label when in the "alt" state. Format like "#FF0000" (red). 52 | * This will override the TextColor style of equal priority. 53 | */ 54 | DataRendererLabelElement._StyleTypes.AltTextColor = StyleableBase.EStyleType.NORMAL; //"#000000" 55 | 56 | /** 57 | * @style OverTextColor String 58 | * 59 | * Hex color value to be used for the label when in the "over" state. Format like "#FF0000" (red). 60 | * This will override the TextColor style of equal priority. 61 | */ 62 | DataRendererLabelElement._StyleTypes.OverTextColor = StyleableBase.EStyleType.NORMAL; //"#000000" 63 | 64 | /** 65 | * @style SelectedTextColor String 66 | * 67 | * Hex color value to be used for the label when in the "selected" state. Format like "#FF0000" (red). 68 | * This will override the TextColor style of equal priority. 69 | */ 70 | DataRendererLabelElement._StyleTypes.SelectedTextColor = StyleableBase.EStyleType.NORMAL; //"#000000" 71 | 72 | /** 73 | * @style DisabledTextColor String 74 | * 75 | * Hex color value to be used for the label when in the "disabled" state. Format like "#FF0000" (red). 76 | * This will override the TextColor style of equal priority. 77 | */ 78 | DataRendererLabelElement._StyleTypes.DisabledTextColor = StyleableBase.EStyleType.NORMAL; //"#000000" 79 | 80 | 81 | ////////////Default Styles/////////////////////// 82 | 83 | DataRendererLabelElement.StyleDefault = new StyleDefinition(); 84 | 85 | DataRendererLabelElement.StyleDefault.setStyle("PaddingTop", 4); 86 | DataRendererLabelElement.StyleDefault.setStyle("PaddingBottom", 4); 87 | DataRendererLabelElement.StyleDefault.setStyle("PaddingLeft", 4); 88 | DataRendererLabelElement.StyleDefault.setStyle("PaddingRight", 4); 89 | 90 | DataRendererLabelElement.StyleDefault.setStyle("UpTextColor", "#000000"); 91 | DataRendererLabelElement.StyleDefault.setStyle("AltTextColor", "#000000"); 92 | DataRendererLabelElement.StyleDefault.setStyle("OverTextColor", "#000000"); 93 | DataRendererLabelElement.StyleDefault.setStyle("SelectedTextColor", "#000000"); 94 | DataRendererLabelElement.StyleDefault.setStyle("DisabledTextColor", "#888888"); 95 | 96 | 97 | ////////////Internal///////////////////////////// 98 | 99 | //@Override 100 | DataRendererLabelElement.prototype._changeState = 101 | function (state) 102 | { 103 | DataRendererLabelElement.base.prototype._changeState.call(this, state); 104 | 105 | this._updateLabelTextColor(); 106 | }; 107 | 108 | /** 109 | * @function _getTextColor 110 | * Gets the text color style for the supplied state. 111 | * 112 | * @param state String 113 | * The current state. 114 | * 115 | * @returns String 116 | * Text color style for the supplied state. 117 | */ 118 | DataRendererLabelElement.prototype._getTextColor = 119 | function (state) 120 | { 121 | var stateTextColor = null; 122 | 123 | if (state == "up") 124 | stateTextColor = this.getStyleData("UpTextColor"); 125 | else if (state == "alt") 126 | stateTextColor = this.getStyleData("AltTextColor"); 127 | else if (state == "over") 128 | stateTextColor = this.getStyleData("OverTextColor"); 129 | else if (state == "selected") 130 | stateTextColor = this.getStyleData("SelectedTextColor"); 131 | else if (state == "disabled") 132 | stateTextColor = this.getStyleData("DisabledTextColor"); 133 | 134 | var textColor = this.getStyleData("TextColor"); 135 | 136 | //Shouldnt have null stateTextColor 137 | if (stateTextColor == null || textColor.comparePriority(stateTextColor) > 0) //Use textColor if higher priority 138 | return textColor.value; 139 | 140 | return stateTextColor.value; 141 | }; 142 | 143 | /** 144 | * @function _updateLabelTextColor 145 | * Updates the text color for the current state. 146 | */ 147 | DataRendererLabelElement.prototype._updateLabelTextColor = 148 | function () 149 | { 150 | var color = this._getTextColor(this._currentSkinState); 151 | if (color != null) 152 | this._labelElement.setStyle("TextColor", color); 153 | }; 154 | 155 | /** 156 | * @function _updateLabelTextColor 157 | * Updates the label text base on the list data and ItemLabelFunction. 158 | */ 159 | DataRendererLabelElement.prototype._updateLabelText = 160 | function () 161 | { 162 | if (this._itemData == null) 163 | this._labelElement.setStyle("Text", ""); 164 | else 165 | { 166 | var labelFunction = this._listData._parentList.getStyle("ItemLabelFunction"); 167 | this._labelElement.setStyle("Text", labelFunction(this._itemData)); 168 | } 169 | }; 170 | 171 | //@Override 172 | DataRendererLabelElement.prototype._setListData = 173 | function (listData, itemData) 174 | { 175 | DataRendererLabelElement.base.prototype._setListData.call(this, listData, itemData); 176 | 177 | this._updateLabelText(); 178 | }; 179 | 180 | //@Override 181 | DataRendererLabelElement.prototype._doStylesUpdated = 182 | function (stylesMap) 183 | { 184 | DataRendererLabelElement.base.prototype._doStylesUpdated.call(this, stylesMap); 185 | 186 | this._updateLabelTextColor(); 187 | }; 188 | 189 | //@Override 190 | DataRendererLabelElement.prototype._doMeasure = 191 | function(padWidth, padHeight) 192 | { 193 | this._setMeasuredSize(this._labelElement._getStyledOrMeasuredWidth() + padWidth, 194 | this._labelElement._getStyledOrMeasuredHeight() + padHeight); 195 | }; 196 | 197 | //@Override 198 | DataRendererLabelElement.prototype._doLayout = 199 | function (paddingMetrics) 200 | { 201 | DataRendererLabelElement.base.prototype._doLayout.call(this, paddingMetrics); 202 | 203 | this._labelElement._setActualPosition(paddingMetrics.getX(), paddingMetrics.getY()); 204 | this._labelElement._setActualSize(paddingMetrics.getWidth(), paddingMetrics.getHeight()); 205 | }; 206 | 207 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/events/AddedRemovedEvent.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends DispatcherEvent.js 4 | */ 5 | 6 | ////////////////////////////////////////////////////////////////////// 7 | /////////////////////AddedRemovedEvent//////////////////////////////// 8 | 9 | /** 10 | * @class AddedRemovedEvent 11 | * @inherits DispatcherEvent 12 | * 13 | * Event that is dispatched when a CanvasElement is added or removed from 14 | * a CanvasManager and can be of type "added" or "removed". This is used to detect 15 | * when an Element is added or removed from the display and to create / destroy or 16 | * associate / dissociate resources. For example, CanvasElement uses these events 17 | * to add and remove event listeners to its associated StyleDefinitions which are 18 | * external resources and would cause memory leaks if not cleaned up. 19 | * 20 | * 21 | * @constructor AddedRemovedEvent 22 | * Creates new AddedRemovedEvent instance. 23 | * 24 | * @param type String 25 | * String representing the event type ("added" or "removed") 26 | * 27 | * @param manager CanvasManager 28 | * The CanvasManager instance that the element is being added or removed. 29 | */ 30 | function AddedRemovedEvent(type, manager) 31 | { 32 | AddedRemovedEvent.base.prototype.constructor.call(this, type); 33 | 34 | this._manager = manager; 35 | } 36 | 37 | //Inherit from DispatcherEvent 38 | AddedRemovedEvent.prototype = Object.create(DispatcherEvent.prototype); 39 | AddedRemovedEvent.prototype.constructor = AddedRemovedEvent; 40 | AddedRemovedEvent.base = DispatcherEvent; 41 | 42 | /** 43 | * @function getManager 44 | * Gets the CanvasManager instance that the Element has been added or removed. 45 | * Note that when an element is removed, the Element is no longer associated with the CanvasManager 46 | * so you must use this method to get the appropriate CanvasManager reference. 47 | * 48 | * @returns CanvasManager 49 | * The CanvasManager instance the element is now associated with when added, or no longer associated with when removed. 50 | */ 51 | AddedRemovedEvent.prototype.getManager = 52 | function () 53 | { 54 | return this._manager; 55 | }; 56 | 57 | //@Override 58 | AddedRemovedEvent.prototype.clone = 59 | function () 60 | { 61 | var clonedEvent = AddedRemovedEvent.base.prototype.clone.call(this); 62 | 63 | //No additional property copies (handled by constructor) 64 | 65 | return clonedEvent; 66 | }; 67 | 68 | //@Override 69 | AddedRemovedEvent.prototype._cloneInstance = 70 | function () 71 | { 72 | return new AddedRemovedEvent(this._type, this._manager); 73 | }; 74 | 75 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/events/CollectionChangedEvent.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends DispatcherEvent.js 4 | */ 5 | 6 | /////////////////////////////////////////////////////////////////// 7 | //////////////////CollectionChangedEvent/////////////////////////// 8 | 9 | /** 10 | * @class CollectionChangedEvent 11 | * @inherits DispatcherEvent 12 | * 13 | * Event that is dispatched when a data collection is changed of type "collectionchanged". 14 | * This is typically an internal event that the data driven containers use to monitor 15 | * changes to their data collections. 16 | * 17 | * 18 | * @constructor CollectionChangedEvent 19 | * Creates new CollectionChangedEvent instance. 20 | * 21 | * @param kind String 22 | * String representing type of change that occurred to the collection. 23 | * Allowable values are "add", "remove", "update", and "reset". 24 | * 25 | * @param index int 26 | * Index position the change occurred (or -1 if kind is "reset"). 27 | */ 28 | function CollectionChangedEvent(kind, index) 29 | { 30 | CollectionChangedEvent.base.prototype.constructor.call(this, "collectionchanged"); 31 | 32 | this._kind = kind; 33 | this._index = index; 34 | } 35 | 36 | //Inherit from DispatcherEvent 37 | CollectionChangedEvent.prototype = Object.create(DispatcherEvent.prototype); 38 | CollectionChangedEvent.prototype.constructor = CollectionChangedEvent; 39 | CollectionChangedEvent.base = DispatcherEvent; 40 | 41 | /** 42 | * @function getKind 43 | * Gets the kind of the collection event. Possible types are "add", "remove", "update", and "reset". 44 | * 45 | * @returns String 46 | * The kind of the collection event. 47 | */ 48 | CollectionChangedEvent.prototype.getKind = 49 | function () 50 | { 51 | return this._kind; 52 | }; 53 | 54 | /** 55 | * @function getIndex 56 | * Gets the index of the data collection that the change occurred. 57 | * 58 | * @returns int 59 | * The index of the data collection that the change occurred. 60 | */ 61 | CollectionChangedEvent.prototype.getIndex = 62 | function () 63 | { 64 | return this._index; 65 | }; 66 | 67 | //@Override 68 | CollectionChangedEvent.prototype.clone = 69 | function () 70 | { 71 | var clonedEvent = CollectionChangedEvent.base.prototype.clone.call(this); 72 | 73 | //No additional property copies (handled by constructor) 74 | 75 | return clonedEvent; 76 | }; 77 | 78 | //@Override 79 | CollectionChangedEvent.prototype._cloneInstance = 80 | function () 81 | { 82 | return new CollectionChangedEvent(this._kind, this._index); 83 | }; 84 | 85 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/events/DispatcherEvent.js: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////// 3 | /////////////////////DispatcherEvent////////////////////////////////// 4 | 5 | /** 6 | * @class DispatcherEvent 7 | * Base class for all events. 8 | * 9 | * @constructor DispatcherEvent 10 | * Creates new DispatcherEvent instance 11 | * 12 | * @param type String 13 | * String representing the event type 14 | * 15 | */ 16 | function DispatcherEvent(type) 17 | { 18 | this._type = type; 19 | 20 | this._target = null; 21 | this._canceled = false; 22 | } 23 | 24 | //DispatcherEvent is base object, no inheritance. 25 | DispatcherEvent.prototype.constructor = DispatcherEvent; 26 | 27 | 28 | /** 29 | * @function getType 30 | * Gets the event type 31 | * 32 | * @returns String 33 | * String representing the event type 34 | */ 35 | DispatcherEvent.prototype.getType = 36 | function () 37 | { 38 | return this._type; 39 | }; 40 | 41 | 42 | /** 43 | * @function getTarget 44 | * Gets event target 45 | * 46 | * @returns Object 47 | * Object that originally dispatched the event 48 | */ 49 | DispatcherEvent.prototype.getTarget = 50 | function () 51 | { 52 | return this._target; 53 | }; 54 | 55 | /** 56 | * @function cancelEvent 57 | * Prevents processing of any subsequent event handlers 58 | */ 59 | DispatcherEvent.prototype.cancelEvent = 60 | function () 61 | { 62 | this._canceled = true; 63 | }; 64 | 65 | /** 66 | * @function getIsCanceled 67 | * Checks if the event has been canceled 68 | * 69 | * @returns boolean 70 | * Returns true if the event has been canceled, otherwise false 71 | */ 72 | DispatcherEvent.prototype.getIsCanceled = 73 | function () 74 | { 75 | return this._canceled; 76 | }; 77 | 78 | /** 79 | * @function clone 80 | * Duplicates an instance of an Event or Event subclass. 81 | * The event dispatcher calls this when dispatching or re-dispatching events to multiple targets. 82 | * When creating a custom event class, you should override this and call the base class's clone() 83 | * then copy the new event properties to the cloned instance. 84 | * 85 | * @returns DispatcherEvent 86 | * A new event object instance identical to the cloned instance. 87 | */ 88 | DispatcherEvent.prototype.clone = 89 | function () 90 | { 91 | var clonedEvent = this._cloneInstance(); 92 | 93 | clonedEvent._target = this._target; 94 | clonedEvent._canceled = this._canceled; 95 | 96 | return clonedEvent; 97 | }; 98 | 99 | /** 100 | * @function _cloneInstance 101 | * Calls and returns the constructor() of the appropriate event subclass when cloning an event. 102 | * When creating a custom event class, you should override this and return the appropriate event subclass type. 103 | * 104 | * @returns DispatcherEvent 105 | * A new event instance of the same type being cloned. 106 | */ 107 | DispatcherEvent.prototype._cloneInstance = 108 | function () 109 | { 110 | return new DispatcherEvent(this._type); 111 | }; 112 | 113 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/events/ElementEvent.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends DispatcherEvent.js 4 | */ 5 | 6 | ////////////////////////////////////////////////////////////////////// 7 | /////////////////////ElementEvent///////////////////////////////////// 8 | 9 | /** 10 | * @class ElementEvent 11 | * @inherits DispatcherEvent 12 | * 13 | * Base class for CanvasElement UI events. ElementEvents support 14 | * capture and bubbling phase when dispatched from CanvasElement(s). A bubbling event 15 | * invokes capture listeners from the root parent to the target child element and then 16 | * bubbling (normal) listeners from the target element to the root parent. 17 | * Bubbling events are used to detect events dispatched on child elements. 18 | * Capture events are typically not needed but sometimes useful if you wish to 19 | * detect an event before the target has a chance to process it. 20 | * 21 | * For Example, when a Button dispatches a ElementMouseEvent. 22 | * The event propagates from the root parent (CanvasManager) down the display chain 23 | * from child to child dispatching capture events to any parents with registered listeners. 24 | * Once reaching the target element (Button) the event then propagates back up the display chain 25 | * from parent to parent dispatching bubbling events. 26 | * You may cancel the event at any time to stop the event flow. 27 | * 28 | * 29 | * @constructor ElementEvent 30 | * Creates new ElementEvent instance. 31 | * 32 | * @param type String 33 | * String representing the event type 34 | * 35 | * @param bubbles boolean 36 | * True if the ElementEvent should be dispatch capture and bubbling events. 37 | */ 38 | 39 | function ElementEvent(type, bubbles) 40 | { 41 | ElementEvent.base.prototype.constructor.call(this, type); 42 | 43 | this._currentTarget = null; 44 | this._bubbles = bubbles; 45 | this._phase = null; // "capture" || "bubble" 46 | this._defaultPrevented = false; 47 | } 48 | 49 | //Inherit from DispatcherEvent 50 | ElementEvent.prototype = Object.create(DispatcherEvent.prototype); 51 | ElementEvent.prototype.constructor = ElementEvent; 52 | ElementEvent.base = DispatcherEvent; 53 | 54 | /** 55 | * @function getCurrentTarget 56 | * 57 | * Gets the element that is currently dispatching the event. Note that is 58 | * is not always the same as getTarget() which returns the element that 59 | * originally dispatched the event. 60 | * 61 | * For Example, when a click listener is registered to an element, and a child of that 62 | * element dispatches a click (like a Button), the target will be the child (Button) and the 63 | * current target will be the element that registered the click listener. 64 | * 65 | * 66 | * @returns CanvasElement 67 | * The element that is currently dispatching the event. 68 | */ 69 | ElementEvent.prototype.getCurrentTarget = 70 | function () 71 | { 72 | return this._currentTarget; 73 | }; 74 | 75 | /** 76 | * @function getPhase 77 | * 78 | * Gets the current phase of the event. ("bubbling" or "capture") 79 | * 80 | * @returns String 81 | * String representing the event's current phase when dispatched ("bubbling" or "capture") 82 | */ 83 | ElementEvent.prototype.getPhase = 84 | function () 85 | { 86 | return this._phase; 87 | }; 88 | 89 | /** 90 | * @function preventDefault 91 | * 92 | * Prevents the event's typical action from being taken. This is also sometimes used to "consume" 93 | * the event so it is only processed once. Such as preventing a mousewheel event from scrolling multiple 94 | * parent/child views at once. A scroll-able child will call preventDefault() to "consume" the event 95 | * and prevent any parents from also scrolling. 96 | */ 97 | ElementEvent.prototype.preventDefault = 98 | function () 99 | { 100 | this._defaultPrevented = true; 101 | }; 102 | 103 | /** 104 | * @function getDefaultPrevented 105 | * 106 | * Gets the default prevented state of the event. 107 | * 108 | * @returns boolean 109 | * Returns true if preventDefault() has been called, false otherwise. 110 | */ 111 | ElementEvent.prototype.getDefaultPrevented = 112 | function () 113 | { 114 | return this._defaultPrevented; 115 | }; 116 | 117 | //@Override 118 | ElementEvent.prototype.clone = 119 | function () 120 | { 121 | var clonedEvent = ElementEvent.base.prototype.clone.call(this); 122 | 123 | clonedEvent._currentTarget = this._currentTarget; 124 | clonedEvent._phase = this._phase; 125 | clonedEvent._defaultPrevented = this._defaultPrevented; 126 | clonedEvent._bubbles = this._bubbles; //Need to set, some subclasses always pass true in constructor. 127 | 128 | return clonedEvent; 129 | }; 130 | 131 | //@Override 132 | ElementEvent.prototype._cloneInstance = 133 | function () 134 | { 135 | return new ElementEvent(this._type, this._bubbles); 136 | }; -------------------------------------------------------------------------------- /src/FlexCanvasJS/events/ElementGridItemClickEvent.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends ElementListItemClickEvent.js 4 | */ 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | /////////////////////ElementGridItemClickEvent//////////////////////////// 8 | 9 | /** 10 | * @class ElementGridItemClickEvent 11 | * @inherits ElementListItemClickEvent 12 | * 13 | * Event class dispatched when a DataGrid DataRenderer is clicked of type "listitemclick". 14 | * 15 | * 16 | * @constructor ElementGridItemClickEvent 17 | * Creates new ElementGridItemClickEvent instance. 18 | * 19 | * @param item Object 20 | * The collection item associated with the DataRenderer that was clicked. 21 | * 22 | * @param index int 23 | * The collection index associated with the DataRenderer that was clicked. 24 | * 25 | * @param columnIndex int 26 | * The column index associated with the DataRenderer that was clicked. 27 | */ 28 | function ElementGridItemClickEvent(item, index, columnIndex) 29 | { 30 | ElementGridItemClickEvent.base.prototype.constructor.call(this, item, index); 31 | 32 | this._columnIndex = columnIndex; 33 | } 34 | 35 | //Inherit from ElementListItemClickEvent 36 | ElementGridItemClickEvent.prototype = Object.create(ElementListItemClickEvent.prototype); 37 | ElementGridItemClickEvent.prototype.constructor = ElementGridItemClickEvent; 38 | ElementGridItemClickEvent.base = ElementListItemClickEvent; 39 | 40 | /** 41 | * @function getColumnIndex 42 | * Gets the column index that dispatched the event. 43 | * 44 | * @returns int 45 | * Column index. 46 | */ 47 | ElementGridItemClickEvent.prototype.getColumnIndex = 48 | function() 49 | { 50 | return this._columnIndex; 51 | }; 52 | 53 | //@Override 54 | ElementGridItemClickEvent.prototype.clone = 55 | function () 56 | { 57 | var clonedEvent = ElementGridItemClickEvent.base.prototype.clone.call(this); 58 | 59 | //No additional property copies (handled by constructor) 60 | 61 | return clonedEvent; 62 | }; 63 | 64 | //@Override 65 | ElementGridItemClickEvent.prototype._cloneInstance = 66 | function () 67 | { 68 | return new ElementListItemClickEvent(this._item, this._index, this._columnIndex); 69 | }; -------------------------------------------------------------------------------- /src/FlexCanvasJS/events/ElementKeyboardEvent.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends ElementEvent.js 4 | */ 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | /////////////////////ElementKeyboardEvent///////////////////////////////// 8 | 9 | /** 10 | * @class ElementKeyboardEvent 11 | * @inherits ElementEvent 12 | * 13 | * Event class used to represent keyboard events of type "keydown" or "keyup". 14 | * Note that unlike mouse events, every "keydown" is not necessarily paired with a "keyup". 15 | * When a key is held down, "keydown" events will repeatedly be dispatched until the key 16 | * is released which will then dispatch a "keyup" event. 17 | * 18 | * @constructor ElementKeyboardEvent 19 | * Creates new ElementKeyboardEvent instance. 20 | * 21 | * @param type String 22 | * String representing the event type ("keydown" or "keyup") 23 | * 24 | * @param key String 25 | * Printable representation of the key. If the key is not printable such as 26 | * Shift or Return this should be an emtpy string "". 27 | * 28 | * @param keyCode int 29 | * The keycode of the key that caused the event. 30 | * 31 | * @param ctrl boolean 32 | * True if the ctrl key is pressed, false otherwise. 33 | * 34 | * @param alt boolean 35 | * True if the alt key is pressed, false otherwise. 36 | * 37 | * @param shift boolean 38 | * True if the shift key is pressed, false otherwise. 39 | * 40 | * @param meta boolean 41 | * True if the meta key (such as windows key) is pressed, false otherwise. 42 | */ 43 | function ElementKeyboardEvent(type, key, keyCode, ctrl, alt, shift, meta) 44 | { 45 | ElementKeyboardEvent.base.prototype.constructor.call(this, type, true); 46 | 47 | //IE key names are different... normalize 48 | if (key == "Spacebar") 49 | key = " "; 50 | else if (key == "Left") 51 | key = "ArrowLeft"; 52 | else if (key == "Right") 53 | key = "ArrowRight"; 54 | else if (key == "Up") 55 | key = "ArrowUp"; 56 | else if (key == "Down") 57 | key = "ArrowDown"; 58 | else if (key == "Del") 59 | key = "Delete"; 60 | 61 | this._key = key; 62 | this._keyCode = keyCode; 63 | 64 | this._ctrl = ctrl; 65 | this._alt = alt; 66 | this._shift = shift; 67 | this._meta = meta; 68 | } 69 | 70 | //Inherit from ElementEvent 71 | ElementKeyboardEvent.prototype = Object.create(ElementEvent.prototype); 72 | ElementKeyboardEvent.prototype.constructor = ElementKeyboardEvent; 73 | ElementKeyboardEvent.base = ElementEvent; 74 | 75 | /** 76 | * @function getKey 77 | * 78 | * Gets the printable version of the key which caused the event. 79 | * 80 | * @returns String 81 | * The printable version of the key which caused the event. Empty string "" if the 82 | * key is not printable. 83 | */ 84 | ElementKeyboardEvent.prototype.getKey = 85 | function () 86 | { 87 | return this._key; 88 | }; 89 | 90 | /** 91 | * @function getKeyCode 92 | * 93 | * Gets the key code of the key which caused the event. 94 | * 95 | * @returns int 96 | * The keycode of the key which caused the event. 97 | */ 98 | ElementKeyboardEvent.prototype.getKeyCode = 99 | function () 100 | { 101 | return this._keyCode; 102 | }; 103 | 104 | /** 105 | * @function getCtrl 106 | * 107 | * Gets the state of the ctrl key. 108 | * 109 | * @returns boolean 110 | * True if the ctrl key is pressed, otherwise false. 111 | */ 112 | ElementKeyboardEvent.prototype.getCtrl = 113 | function () 114 | { 115 | return this._ctrl; 116 | }; 117 | 118 | /** 119 | * @function getAlt 120 | * 121 | * Gets the state of the alt key. 122 | * 123 | * @returns boolean 124 | * True if the alt key is pressed, otherwise false. 125 | */ 126 | ElementKeyboardEvent.prototype.getAlt = 127 | function () 128 | { 129 | return this._alt; 130 | }; 131 | 132 | /** 133 | * @function getShift 134 | * 135 | * Gets the state of the shift key. 136 | * 137 | * @returns boolean 138 | * True if the shift key is pressed, otherwise false. 139 | */ 140 | ElementKeyboardEvent.prototype.getShift = 141 | function () 142 | { 143 | return this._shift; 144 | }; 145 | 146 | /** 147 | * @function getMeta 148 | * 149 | * Gets the state of the meta key (such as the windows key). 150 | * 151 | * @returns boolean 152 | * True if the meta key is pressed, otherwise false. 153 | */ 154 | ElementKeyboardEvent.prototype.getMeta = 155 | function () 156 | { 157 | return this._meta; 158 | }; 159 | 160 | //@Override 161 | ElementKeyboardEvent.prototype.clone = 162 | function () 163 | { 164 | var clonedEvent = ElementKeyboardEvent.base.prototype.clone.call(this); 165 | 166 | //No additional property copies (handled by constructor) 167 | 168 | return clonedEvent; 169 | }; 170 | 171 | //@Override 172 | ElementKeyboardEvent.prototype._cloneInstance = 173 | function () 174 | { 175 | return new ElementKeyboardEvent(this._type, 176 | this._key, this._keyCode, 177 | this._ctrl, this._alt, this._shift, this._meta); 178 | }; 179 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/events/ElementListItemClickEvent.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends ElementEvent.js 4 | */ 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | /////////////////////ElementListItemClickEvent//////////////////////////// 8 | 9 | /** 10 | * @class ElementListItemClickEvent 11 | * @inherits ElementEvent 12 | * 13 | * Event class dispatched when a DataRenderer is clicked of type "listitemclick". 14 | * 15 | * 16 | * @constructor ElementListItemClickEvent 17 | * Creates new ElementListItemClickEvent instance. 18 | * 19 | * @param item Object 20 | * The collection item associated with the DataRenderer that was clicked. 21 | * 22 | * @param index int 23 | * The collection index associated with the DataRenderer that was clicked. 24 | */ 25 | function ElementListItemClickEvent(item, index) 26 | { 27 | ElementListItemClickEvent.base.prototype.constructor.call(this, "listitemclick", false); 28 | 29 | this._item = item; 30 | this._index = index; 31 | } 32 | 33 | //Inherit from ElementEvent 34 | ElementListItemClickEvent.prototype = Object.create(ElementEvent.prototype); 35 | ElementListItemClickEvent.prototype.constructor = ElementListItemClickEvent; 36 | ElementListItemClickEvent.base = ElementEvent; 37 | 38 | /** 39 | * @function getItem 40 | * Gets the collection item associated with the DataRenderer that was clicked. 41 | * 42 | * @returns Object 43 | * The collection item associated with the DataRenderer that was clicked. 44 | */ 45 | ElementListItemClickEvent.prototype.getItem = 46 | function() 47 | { 48 | return this._item; 49 | }; 50 | 51 | /** 52 | * @function getIndex 53 | * Gets the collection index associated with the DataRenderer that was clicked. 54 | * 55 | * @returns int 56 | * The collection index associated with the DataRenderer that was clicked. 57 | */ 58 | ElementListItemClickEvent.prototype.getIndex = 59 | function() 60 | { 61 | return this._index; 62 | }; 63 | 64 | //@Override 65 | ElementListItemClickEvent.prototype.clone = 66 | function () 67 | { 68 | var clonedEvent = ElementListItemClickEvent.base.prototype.clone.call(this); 69 | 70 | //No additional property copies (handled by constructor) 71 | 72 | return clonedEvent; 73 | }; 74 | 75 | //@Override 76 | ElementListItemClickEvent.prototype._cloneInstance = 77 | function () 78 | { 79 | return new ElementListItemClickEvent(this._item, this._index); 80 | }; -------------------------------------------------------------------------------- /src/FlexCanvasJS/events/ElementMouseEvent.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends ElementEvent.js 4 | */ 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | /////////////////////ElementMouseEvent//////////////////////////////////// 8 | 9 | /** 10 | * @class ElementMouseEvent 11 | * @inherits ElementEvent 12 | * 13 | * Event class used to represent mouse events of type "mousedown", "mouseup" or "click". 14 | * Every "mousedown" event is always paired with a "mouseup" event. Note that the mouse is 15 | * not necessarily still over the same object when "mouseup" is dispatched. The user may have 16 | * pressed and then moved the mouse before releasing. A "click" event however, is only dispatched 17 | * if the mouse is still over the "mousedown" object when the mouse is released. 18 | * 19 | * @constructor ElementMouseEvent 20 | * Creates new ElementMouseEvent instance. 21 | * 22 | * @param type String 23 | * String representing the event type ("mousedown", "mouseup", or "click") 24 | * 25 | * @param x int 26 | * The X coordinate of the mouse relative to the object dispatching the mouse event. 27 | * 28 | * @param y int 29 | * The Y coordinate of the mouse relative to the object dispatching the mouse event. 30 | */ 31 | function ElementMouseEvent(type, x, y) 32 | { 33 | ElementMouseEvent.base.prototype.constructor.call(this, type, true); 34 | 35 | this._x = x; 36 | this._y = y; 37 | } 38 | 39 | //Inherit from ElementEvent 40 | ElementMouseEvent.prototype = Object.create(ElementEvent.prototype); 41 | ElementMouseEvent.prototype.constructor = ElementMouseEvent; 42 | ElementMouseEvent.base = ElementEvent; 43 | 44 | /** 45 | * @function getX 46 | * 47 | * Gets the X coordinate of the mouse relative to the object dispatching the mouse event. 48 | * 49 | * @returns int 50 | * The X coordinate of the mouse relative to the object dispatching the mouse event. 51 | */ 52 | ElementMouseEvent.prototype.getX = 53 | function() 54 | { 55 | return this._x; 56 | }; 57 | 58 | /** 59 | * @function getY 60 | * 61 | * Gets the Y coordinate of the mouse relative to the object dispatching the mouse event. 62 | * 63 | * @returns int 64 | * The Y coordinate of the mouse relative to the object dispatching the mouse event. 65 | */ 66 | ElementMouseEvent.prototype.getY = 67 | function() 68 | { 69 | return this._y; 70 | }; 71 | 72 | //@Override 73 | ElementMouseEvent.prototype.clone = 74 | function () 75 | { 76 | var clonedEvent = ElementMouseEvent.base.prototype.clone.call(this); 77 | 78 | //No additional property copies (handled by constructor) 79 | 80 | return clonedEvent; 81 | }; 82 | 83 | //@Override 84 | ElementMouseEvent.prototype._cloneInstance = 85 | function () 86 | { 87 | return new ElementMouseEvent(this._type, this._x, this._y); 88 | }; 89 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/events/ElementMouseWheelEvent.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends ElementMouseEvent.js 4 | */ 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | /////////////////////ElementMouseWheelEvent/////////////////////////////// 8 | 9 | /** 10 | * @class ElementMouseWheelEvent 11 | * @inherits ElementMouseEvent 12 | * 13 | * Event class used to represent mouse wheel events of type "wheel". 14 | * 15 | * 16 | * @constructor ElementMouseWheelEvent 17 | * Creates new ElementMouseWheelEvent instance. 18 | * 19 | * @param x int 20 | * The X coordinate of the mouse relative to the object dispatching the mouse event. 21 | * 22 | * @param y int 23 | * The Y coordinate of the mouse relative to the object dispatching the mouse event. 24 | * 25 | * @param deltaX int 26 | * The change of the X position of the the mouse wheel. (Currently -1, 0, or +1) 27 | * 28 | * @param deltaY int 29 | * The change of the Y position of the the mouse wheel. (Currently -1, 0, or +1) 30 | */ 31 | function ElementMouseWheelEvent(x, y, deltaX, deltaY) 32 | { 33 | ElementMouseWheelEvent.base.prototype.constructor.call(this, "wheel", x, y); 34 | 35 | this._deltaX = deltaX; 36 | this._deltaY = deltaY; 37 | } 38 | 39 | //Inherit from ElementMouseEvent 40 | ElementMouseWheelEvent.prototype = Object.create(ElementMouseEvent.prototype); 41 | ElementMouseWheelEvent.prototype.constructor = ElementMouseWheelEvent; 42 | ElementMouseWheelEvent.base = ElementMouseEvent; 43 | 44 | /** 45 | * @function getDeltaX 46 | * 47 | * Gets the change of the X position of the mouse wheel. The system normalizes this 48 | * across browsers to values -1, 0, or +1. 49 | * 50 | * @returns int 51 | * The change of the X position of the mouse wheel. 52 | */ 53 | ElementMouseWheelEvent.prototype.getDeltaX = 54 | function() 55 | { 56 | return this._deltaX; 57 | }; 58 | 59 | /** 60 | * @function getDeltaY 61 | * 62 | * Gets the change of the Y position of the mouse wheel. The system normalizes this 63 | * across browsers to values -1, 0, or +1. 64 | * 65 | * @returns int 66 | * The change of the Y position of the mouse wheel. 67 | */ 68 | ElementMouseWheelEvent.prototype.getDeltaY = 69 | function() 70 | { 71 | return this._deltaY; 72 | }; 73 | 74 | //@Override 75 | ElementMouseWheelEvent.prototype.clone = 76 | function () 77 | { 78 | var clonedEvent = ElementMouseWheelEvent.base.prototype.clone.call(this); 79 | 80 | //No additional property copies (handled by constructor) 81 | 82 | return clonedEvent; 83 | }; 84 | 85 | //@Override 86 | ElementMouseWheelEvent.prototype._cloneInstance = 87 | function () 88 | { 89 | return new ElementMouseWheelEvent(this._x, this._y, this._deltaX, this._deltaY); 90 | }; 91 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/events/StyleChangedEvent.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends DispatcherEvent.js 4 | */ 5 | 6 | ////////////////////////////////////////////////////////////////////// 7 | /////////////////////StyleChangedEvent//////////////////////////////// 8 | 9 | /** 10 | * @class StyleChangedEvent 11 | * @inherits DispatcherEvent 12 | * 13 | * Event that is dispatched when a style is changed of type "stylechanged". 14 | * This is typically an internal event that the system uses to monitor 15 | * style changes to Elements, StyleDefnitions, or any style-able objects. 16 | * 17 | * 18 | * @constructor StyleChangedEvent 19 | * Creates new StyleChangedEvent instance. 20 | * 21 | * @param styleName String 22 | * String representing style type that was updated 23 | */ 24 | function StyleChangedEvent(styleName) 25 | { 26 | StyleChangedEvent.base.prototype.constructor.call(this, "stylechanged"); 27 | 28 | this._styleName = styleName; 29 | } 30 | 31 | //Inherit from DispatcherEvent 32 | StyleChangedEvent.prototype = Object.create(DispatcherEvent.prototype); 33 | StyleChangedEvent.prototype.constructor = StyleChangedEvent; 34 | StyleChangedEvent.base = DispatcherEvent; 35 | 36 | /** 37 | * @function getStyleName 38 | * Gets the style name of the style which has changed 39 | * 40 | * @returns String 41 | * String representing the style that has changed 42 | */ 43 | StyleChangedEvent.prototype.getStyleName = 44 | function () 45 | { 46 | return this._styleName; 47 | }; 48 | 49 | //@override 50 | StyleChangedEvent.prototype.clone = 51 | function () 52 | { 53 | var clonedEvent = StyleChangedEvent.base.prototype.clone.call(this); 54 | 55 | //No additional property copies (handled by constructor) 56 | 57 | return clonedEvent; 58 | }; 59 | 60 | //@override 61 | StyleChangedEvent.prototype._cloneInstance = 62 | function () 63 | { 64 | return new StyleChangedEvent(this._styleName, this._oldValue, this._newValue); 65 | }; 66 | 67 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/fills/FillBase.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends StyleableBase.js 4 | */ 5 | 6 | //////////////////////////////////////////////////////// 7 | ////////////////////FillBase/////////////////////////// 8 | 9 | /** 10 | * @class FillBase 11 | * @inherits StyleableBase 12 | * 13 | * Abstract base class for filling element's background shape. 14 | * This can be assigned to CanvasElement's "BackgroundFill" style. 15 | * When sub-classing, add any necessary styles and implement the drawFill() function. 16 | * 17 | * @constructor FillBase 18 | * Creates new FillBase instance. 19 | */ 20 | function FillBase() 21 | { 22 | FillBase.base.prototype.constructor.call(this); 23 | } 24 | 25 | //Inherit from StyleableBase 26 | FillBase.prototype = Object.create(StyleableBase.prototype); 27 | FillBase.prototype.constructor = FillBase; 28 | FillBase.base = StyleableBase; 29 | 30 | ////////////Public////////////////////// 31 | 32 | /** 33 | * @function drawFill 34 | * Abstract stub used to fill an elements background. 35 | * Override this, setup the Canvas2DContext's fill style via ctx.fillStyle and call ctx.fill(). 36 | * The background shape path will have already been drawn by the elements ShapeBase class. 37 | * 38 | * @param ctx Canvas2DContext 39 | * The Canvas2DContext to draw the fill on. 40 | * 41 | * @param metrics DrawMetrics 42 | * DrawMetrics object to use as the bounding box for the fill. 43 | * 44 | */ 45 | FillBase.prototype.drawFill = 46 | function (ctx, metrics) 47 | { 48 | //Stub for override. 49 | }; 50 | 51 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/fills/LinearGradientFill.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends FillBase.js 4 | */ 5 | 6 | //////////////////////////////////////////////////////// 7 | /////////////////LinearGradientFill///////////////////// 8 | 9 | /** 10 | * @class LinearGradientFill 11 | * @inherits FillBase 12 | * 13 | * Fills a linear gradient across the element with supplied angle and color stops. 14 | * 15 | * @constructor LinearGradientFill 16 | * Creates new LinearGradientFill instance. 17 | */ 18 | function LinearGradientFill() 19 | { 20 | LinearGradientFill.base.prototype.constructor.call(this); 21 | } 22 | 23 | //Inherit from ShapeBase 24 | LinearGradientFill.prototype = Object.create(FillBase.prototype); 25 | LinearGradientFill.prototype.constructor = LinearGradientFill; 26 | LinearGradientFill.base = FillBase; 27 | 28 | 29 | /////////////Style Types/////////////////////////////// 30 | 31 | LinearGradientFill._StyleTypes = Object.create(null); 32 | 33 | 34 | /** 35 | * @style GradientDegrees Number 36 | * 37 | * Angle 0-360 which the gradient should be drawn across the element. 38 | */ 39 | LinearGradientFill._StyleTypes.GradientDegrees = StyleableBase.EStyleType.NORMAL; // 45 40 | 41 | /** 42 | * @style GradientColorStops Array 43 | * 44 | * Array of color stops to apply to the gradient. 45 | * Format like [[position, "color"], [position, "color"], ...] 46 | * Position is a number between 0 and 1 representing where on the gradient line 47 | * to place the color stop. 48 | */ 49 | LinearGradientFill._StyleTypes.GradientColorStops = StyleableBase.EStyleType.NORMAL; // [[0, "#FFFFFF"], [1, "#000000]] 50 | 51 | /** 52 | * @style GradientCoverage String 53 | * 54 | * Determines the size of the gradient line based on the GradientDegrees. 55 | * This style has no effect on gradients at 90 degree intervals. 56 | * Available values are "inner" and "outer". 57 | * Inner gradient will draw a line across the center of the element at the specified degrees. 58 | * Outer gradient extends the line beyond the element's bounds so that the gradient is 59 | * perpendicular to the outer most corners of the element. 60 | */ 61 | LinearGradientFill._StyleTypes.GradientCoverage = StyleableBase.EStyleType.NORMAL; // "inner" || "outer" 62 | 63 | 64 | ////////////Default Styles/////////////////////////// 65 | 66 | LinearGradientFill.StyleDefault = new StyleDefinition(); 67 | 68 | LinearGradientFill.StyleDefault.setStyle("GradientDegrees", 0); 69 | LinearGradientFill.StyleDefault.setStyle("GradientColorStops", [[0, "#FF0000"], [1, "#000000"]]); 70 | LinearGradientFill.StyleDefault.setStyle("GradientCoverage", "inner"); 71 | 72 | 73 | ////////////Public////////////////////// 74 | 75 | //@override 76 | LinearGradientFill.prototype.drawFill = 77 | function (ctx, metrics) 78 | { 79 | var degrees = CanvasElement.normalizeDegrees(this.getStyle("GradientDegrees")); 80 | var colorStops = this.getStyle("GradientColorStops"); 81 | var coverage = this.getStyle("GradientCoverage"); 82 | 83 | var pointsStart = this._calculateInnerOuterPoints(CanvasElement.normalizeDegrees(degrees), metrics); 84 | var pointsStop = this._calculateInnerOuterPoints(CanvasElement.normalizeDegrees(degrees + 180), metrics); 85 | 86 | var pointsIndex = 0; 87 | if (coverage == "outer") 88 | pointsIndex = 1; 89 | 90 | var pointStart = pointsStart[pointsIndex]; 91 | var pointStop = pointsStop[pointsIndex]; 92 | 93 | var gradient = ctx.createLinearGradient(pointStart.x, pointStart.y, pointStop.x, pointStop.y); 94 | 95 | if (Array.isArray(colorStops) == true) 96 | { 97 | for (var i = 0; i < colorStops.length; i++) 98 | { 99 | if (colorStops[i].length > 1) 100 | { 101 | try 102 | { 103 | gradient.addColorStop(colorStops[i][0], colorStops[i][1]); 104 | } 105 | catch (ex) 106 | { 107 | //Swallow 108 | } 109 | } 110 | } 111 | } 112 | 113 | ctx.fillStyle = gradient; 114 | ctx.fill(); 115 | }; 116 | 117 | 118 | ///////////Internal//////////////////// 119 | 120 | //@private 121 | LinearGradientFill.prototype._calculateInnerOuterPoints = 122 | function (degrees, metrics) 123 | { 124 | degrees = CanvasElement.normalizeDegrees(degrees); 125 | 126 | var x = metrics.getX(); 127 | var y = metrics.getY(); 128 | var w = metrics.getWidth(); 129 | var h = metrics.getHeight(); 130 | 131 | var radians = CanvasElement.degreesToRadians(degrees); 132 | 133 | var xRadius = (w / 2); 134 | var yRadius = (h / 2); 135 | 136 | var x1 = CanvasElement.cot(radians) * yRadius; 137 | var y1 = Math.tan(radians) * xRadius; 138 | 139 | if (Math.abs(x1) > xRadius) 140 | { 141 | if (x1 < 0) 142 | x1 = xRadius * -1; 143 | else 144 | x1 = xRadius; 145 | } 146 | if (Math.abs(y1) > yRadius) 147 | { 148 | if (y1 < 0) 149 | y1 = yRadius * -1; 150 | else 151 | y1 = yRadius; 152 | } 153 | 154 | if (degrees > 90 && degrees <= 180) 155 | { 156 | y1 = y1 * -1; 157 | } 158 | else if (degrees > 180 && degrees <= 270) 159 | { 160 | x1 = x1 * -1; 161 | y1 = y1 * -1; 162 | } 163 | else if (degrees > 270) 164 | { 165 | x1 = x1 * -1; 166 | } 167 | 168 | var edgeRadius = Math.sqrt((x1 * x1) + (y1 * y1)); 169 | 170 | var finalRadius; 171 | if (Math.abs(y1) < yRadius) 172 | finalRadius = edgeRadius + Math.abs(((yRadius - Math.abs(y1)) * Math.sin(radians))); 173 | else 174 | finalRadius = edgeRadius + Math.abs(((xRadius - Math.abs(x1)) * Math.cos(radians))); 175 | 176 | var x2 = finalRadius * Math.cos(radians); 177 | var y2 = finalRadius * Math.sin(radians); 178 | 179 | return [{x:x1 + xRadius, y:y1 + yRadius}, 180 | {x:x2 + xRadius, y:y2 + yRadius}]; 181 | }; 182 | 183 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/fills/SolidFill.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends FillBase.js 4 | */ 5 | 6 | //////////////////////////////////////////////////////// 7 | /////////////////SolidFill////////////////////////////// 8 | 9 | /** 10 | * @class SolidFill 11 | * @inherits FillBase 12 | * 13 | * Fills an element a solid color. This class is automatically used when 14 | * an element's BackgroundFill style is set to a color string like "#FF0000". 15 | * 16 | * @constructor SolidFill 17 | * Creates new SolidFill instance. 18 | */ 19 | function SolidFill() 20 | { 21 | SolidFill.base.prototype.constructor.call(this); 22 | } 23 | 24 | //Inherit from FillBase 25 | SolidFill.prototype = Object.create(FillBase.prototype); 26 | SolidFill.prototype.constructor = SolidFill; 27 | SolidFill.base = FillBase; 28 | 29 | 30 | /////////////Style Types/////////////////////////////// 31 | 32 | SolidFill._StyleTypes = Object.create(null); 33 | 34 | 35 | /** 36 | * @style FillColor color 37 | * 38 | * Color which the element should be filled. 39 | */ 40 | SolidFill._StyleTypes.FillColor = StyleableBase.EStyleType.NORMAL; // "#FF0000" 41 | 42 | 43 | ////////////Default Styles/////////////////////////// 44 | 45 | SolidFill.StyleDefault = new StyleDefinition(); 46 | 47 | SolidFill.StyleDefault.setStyle("FillColor", "#FF0000"); // "#FF0000" 48 | 49 | 50 | ////////////Public////////////////////// 51 | 52 | //@override 53 | SolidFill.prototype.drawFill = 54 | function (ctx, metrics) 55 | { 56 | ctx.fillStyle = this.getStyle("FillColor"); 57 | ctx.fill(); 58 | }; 59 | 60 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/shapes/EllipseShape.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends ShapeBase.js 4 | */ 5 | 6 | //////////////////////////////////////////////////////// 7 | /////////////////EllipseShape/////////////////////////// 8 | 9 | /** 10 | * @class EllipseShape 11 | * @inherits ShapeBase 12 | * 13 | * Draws an ellipse that fills the supplied metrics rectangle. 14 | * 15 | * @constructor EllipseShape 16 | * Creates new EllipseShape instance. 17 | */ 18 | function EllipseShape() 19 | { 20 | EllipseShape.base.prototype.constructor.call(this); 21 | } 22 | 23 | //Inherit from ShapeBase 24 | EllipseShape.prototype = Object.create(ShapeBase.prototype); 25 | EllipseShape.prototype.constructor = EllipseShape; 26 | EllipseShape.base = ShapeBase; 27 | 28 | ////////////Public////////////////////// 29 | 30 | //@Override 31 | EllipseShape.prototype.drawShape = 32 | function (ctx, metrics) 33 | { 34 | var w = metrics.getWidth(); 35 | var h = metrics.getHeight(); 36 | 37 | var spline4Magic = 0.551784; 38 | var xOffset = (w / 2) * spline4Magic; 39 | var yOffset = (h / 2) * spline4Magic; 40 | 41 | var xStart = metrics.getX(); 42 | var yStart = metrics.getY(); 43 | var xMiddle = xStart + (w / 2); 44 | var yMiddle = yStart + (h / 2); 45 | var xEnd = xStart + w; 46 | var yEnd = yStart + h; 47 | 48 | ctx.moveTo(xStart, yMiddle); 49 | ctx.bezierCurveTo(xStart, yMiddle - yOffset, xMiddle - xOffset, yStart, xMiddle, yStart); 50 | ctx.bezierCurveTo(xMiddle + xOffset, yStart, xEnd, yMiddle - yOffset, xEnd, yMiddle); 51 | ctx.bezierCurveTo(xEnd, yMiddle + yOffset, xMiddle + xOffset, yEnd, xMiddle, yEnd); 52 | ctx.bezierCurveTo(xMiddle - xOffset, yEnd, xStart, yMiddle + yOffset, xStart, yMiddle); 53 | ctx.closePath(); 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/shapes/RoundedRectangleShape.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends ShapeBase.js 4 | */ 5 | 6 | //////////////////////////////////////////////////////// 7 | /////////////RoundedRectangleShape////////////////////// 8 | 9 | /** 10 | * @class RoundedRectangleShape 11 | * @inherits ShapeBase 12 | * 13 | * Draws rectangles and rounded rectangles. 14 | * 15 | * @constructor RoundedRectangleShape 16 | * Creates new RoundedRectangleShape instance. 17 | */ 18 | function RoundedRectangleShape() 19 | { 20 | RoundedRectangleShape.base.prototype.constructor.call(this); 21 | } 22 | 23 | //Inherit from ShapeBase 24 | RoundedRectangleShape.prototype = Object.create(ShapeBase.prototype); 25 | RoundedRectangleShape.prototype.constructor = RoundedRectangleShape; 26 | RoundedRectangleShape.base = ShapeBase; 27 | 28 | /////////////Style Types/////////////////////////////// 29 | 30 | RoundedRectangleShape._StyleTypes = Object.create(null); 31 | 32 | /** 33 | * @style CornerRadius Number 34 | * 35 | * Radius of the rectangles corners in pixels. 36 | * CornerRadius effects all corners of the rectangle. 37 | * This will override CornerRadiusPercent style. 38 | */ 39 | RoundedRectangleShape._StyleTypes.CornerRadius = StyleableBase.EStyleType.NORMAL; // number || null 40 | 41 | /** 42 | * @style CornerRadiusPercent Number 43 | * 44 | * Radius of the rectangles corners as a percent size of the minimum dimension (width/height). 45 | * CornerRadiusPercent effects all corners of the rectangle. 46 | */ 47 | RoundedRectangleShape._StyleTypes.CornerRadiusPercent = StyleableBase.EStyleType.NORMAL; // number || null 48 | 49 | /** 50 | * @style CornerRadiusTopLeft Number 51 | * 52 | * Radius size of the rectangles top left corner in pixels. 53 | * This will override the CornerRadius, CornerRadiusPercent, & CornerRadiusTopLeftPercent styles. 54 | */ 55 | RoundedRectangleShape._StyleTypes.CornerRadiusTopLeft = StyleableBase.EStyleType.NORMAL; // number || null 56 | 57 | /** 58 | * @style CornerRadiusTopLeftPercent Number 59 | * 60 | * Radius of the rectangles top left corner as a percent size of the minimum dimension (width/height). 61 | * This will override the CornerRadius & CornerRadiusPercent styles. 62 | */ 63 | RoundedRectangleShape._StyleTypes.CornerRadiusTopLeft = StyleableBase.EStyleType.NORMAL; // number || null 64 | 65 | /** 66 | * @style CornerRadiusTopRight Number 67 | * 68 | * Radius size of the rectangles top right corner in pixels. 69 | * This will override the CornerRadius, CornerRadiusPercent, & CornerRadiusTopRightPercent styles. 70 | */ 71 | RoundedRectangleShape._StyleTypes.CornerRadiusTopRight = StyleableBase.EStyleType.NORMAL; // number || null 72 | 73 | /** 74 | * @style CornerRadiusTopRightPercent Number 75 | * 76 | * Radius of the rectangles top right corner as a percent size of the minimum dimension (width/height). 77 | * This will override the CornerRadius & CornerRadiusPercent styles. 78 | */ 79 | RoundedRectangleShape._StyleTypes.CornerRadiusTopRightPercent = StyleableBase.EStyleType.NORMAL; // number || null 80 | 81 | /** 82 | * @style CornerRadiusBottomLeft Number 83 | * 84 | * Radius size of the rectangles bottom left corner in pixels. 85 | * This will override the CornerRadius, CornerRadiusPercent, & CornerRadiusBottomLeftPercent styles. 86 | */ 87 | RoundedRectangleShape._StyleTypes.CornerRadiusBottomLeft = StyleableBase.EStyleType.NORMAL; // number || null 88 | 89 | /** 90 | * @style CornerRadiusBottomLeftPercent Number 91 | * 92 | * Radius of the rectangles bottom left corner as a percent size of the minimum dimension (width/height). 93 | * This will override the CornerRadius & CornerRadiusPercent styles. 94 | */ 95 | RoundedRectangleShape._StyleTypes.CornerRadiusBottomLeftPercent = StyleableBase.EStyleType.NORMAL; // number || null 96 | 97 | /** 98 | * @style CornerRadiusBottomRight Number 99 | * 100 | * Radius size of the rectangles bottom right corner in pixels. 101 | * This will override the CornerRadius, CornerRadiusPercent, & CornerRadiusBottomRightPercent styles. 102 | */ 103 | RoundedRectangleShape._StyleTypes.CornerRadiusBottomRight = StyleableBase.EStyleType.NORMAL; // number || null 104 | 105 | /** 106 | * @style CornerRadiusBottomRightPercent Number 107 | * 108 | * Radius of the rectangles bottom right corner as a percent size of the minimum dimension (width/height). 109 | * This will override the CornerRadius & CornerRadiusPercent styles. 110 | */ 111 | RoundedRectangleShape._StyleTypes.CornerRadiusBottomRightPercent = StyleableBase.EStyleType.NORMAL; // number || null 112 | 113 | 114 | ////////////Style Defaults//////////////////////////// 115 | 116 | RoundedRectangleShape.StyleDefault = new StyleDefinition(); 117 | 118 | RoundedRectangleShape.StyleDefault.setStyle("CornerRadius", null); 119 | RoundedRectangleShape.StyleDefault.setStyle("CornerRadiusPercent", null); 120 | 121 | RoundedRectangleShape.StyleDefault.setStyle("CornerRadiusTopLeft", null); 122 | RoundedRectangleShape.StyleDefault.setStyle("CornerRadiusTopLeftPercent", null); 123 | 124 | RoundedRectangleShape.StyleDefault.setStyle("CornerRadiusTopRight", null); 125 | RoundedRectangleShape.StyleDefault.setStyle("CornerRadiusTopRightPercent", null); 126 | 127 | RoundedRectangleShape.StyleDefault.setStyle("CornerRadiusBottomLeft", null); 128 | RoundedRectangleShape.StyleDefault.setStyle("CornerRadiusBottomLeftPercent", null); 129 | 130 | RoundedRectangleShape.StyleDefault.setStyle("CornerRadiusBottomRight", null); 131 | RoundedRectangleShape.StyleDefault.setStyle("CornerRadiusBottomRightPercent", null); 132 | 133 | 134 | ////////////Public////////////////////// 135 | 136 | //@Override 137 | RoundedRectangleShape.prototype.drawShape = 138 | function (ctx, metrics) 139 | { 140 | var x = metrics.getX(); 141 | var y = metrics.getY(); 142 | 143 | var width = metrics.getWidth(); 144 | var height = metrics.getHeight(); 145 | var size = Math.min(width, height); 146 | 147 | var c = this.getStyle("CornerRadius"); 148 | var cTl = this.getStyle("CornerRadiusTopLeft"); 149 | var cTr = this.getStyle("CornerRadiusTopRight"); 150 | var cBl = this.getStyle("CornerRadiusBottomLeft"); 151 | var cBr = this.getStyle("CornerRadiusBottomRight"); 152 | 153 | if (c == null) 154 | { 155 | var cp = this.getStyle("CornerRadiusPercent"); 156 | if (cp == null) 157 | c = 0; 158 | else 159 | c = size * (cp / 100); 160 | } 161 | 162 | if (cTl == null) 163 | { 164 | var cTlp = this.getStyle("CornerRadiusTopLeftPercent"); 165 | if (cTlp == null) 166 | cTl = c; 167 | else 168 | cTl = size * (cTlp / 100); 169 | } 170 | 171 | if (cTr == null) 172 | { 173 | var cTrp = this.getStyle("CornerRadiusTopRightPercent"); 174 | if (cTrp == null) 175 | cTr = c; 176 | else 177 | cTr = size * (cTrp / 100); 178 | } 179 | 180 | if (cBl == null) 181 | { 182 | var cBlp = this.getStyle("CornerRadiusBottomLeftPercent"); 183 | if (cBlp == null) 184 | cBl = c; 185 | else 186 | cBl = size * (cBlp / 100); 187 | } 188 | 189 | if (cBr == null) 190 | { 191 | var cBrp = this.getStyle("CornerRadiusBottomRightPercent"); 192 | if (cBrp == null) 193 | cBr = c; 194 | else 195 | cBr = size * (cBrp / 100); 196 | } 197 | 198 | ctx.moveTo(x, y + cTl); 199 | 200 | if (cTl > 0) 201 | ctx.arcTo(x, y, 202 | x + cTl, y, 203 | cTl); 204 | 205 | ctx.lineTo(x + width - cTr, y); 206 | 207 | if (cTr > 0) 208 | ctx.arcTo(x + width, y, 209 | x + width, y + cTr, 210 | cTr); 211 | 212 | ctx.lineTo(x + width, y + height - cBr); 213 | 214 | if (cBr > 0) 215 | ctx.arcTo(x + width, y + height, 216 | x + width - cBr, y + height, 217 | cBr); 218 | 219 | ctx.lineTo(x + cBl, y + height); 220 | 221 | if (cBl > 0) 222 | ctx.arcTo(x, y + height, 223 | x, y + height - cBl, 224 | cBl); 225 | 226 | ctx.closePath(); 227 | }; 228 | 229 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/shapes/ShapeBase.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends StyleableBase.js 4 | */ 5 | 6 | //////////////////////////////////////////////////////// 7 | ////////////////////ShapeBase/////////////////////////// 8 | 9 | /** 10 | * @class ShapeBase 11 | * @inherits StyleableBase 12 | * 13 | * Abstract base class for drawing vector shape paths. 14 | * This is used by CanvasElements when drawing their background shape 15 | * and can be assigned to CanvasElement's "BackgroundShape" style. 16 | * When sub-classing, add any necessary styles and implement the drawShape() function. 17 | * 18 | * @constructor ShapeBase 19 | * Creates new ShapeBase instance. 20 | */ 21 | function ShapeBase() 22 | { 23 | ShapeBase.base.prototype.constructor.call(this); 24 | } 25 | 26 | //Inherit from StyleableBase 27 | ShapeBase.prototype = Object.create(StyleableBase.prototype); 28 | ShapeBase.prototype.constructor = ShapeBase; 29 | ShapeBase.base = StyleableBase; 30 | 31 | ////////////Public////////////////////// 32 | 33 | /** 34 | * @function drawShape 35 | * Used to draw a sub-path shape path to the supplied Canvas2DContext using the supplied metrics. 36 | * Override this to draw custom shapes. Do *not* call beginPath() as that will destroy previous 37 | * sub-paths and *do not* do any filling or other context calls. Only draw and closePath() the sub-path. 38 | * 39 | * @param ctx Canvas2DContext 40 | * The Canvas2DContext to draw the sub-path on. 41 | * 42 | * @param metrics DrawMetrics 43 | * DrawMetrics object to use as the bounding box for the sub-path. 44 | */ 45 | ShapeBase.prototype.drawShape = 46 | function (ctx, metrics) 47 | { 48 | //Stub for override. 49 | }; 50 | 51 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/skins/CheckboxSkinElement.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends CanvasElement.js 4 | */ 5 | 6 | /////////////////////////////////////////////////////////////////////// 7 | ///////////////////////CheckboxSkinElement///////////////////////////// 8 | 9 | /** 10 | * @class CheckboxSkinElement 11 | * @inherits CanvasElement 12 | * 13 | * Default skin class for the CheckboxElement. 14 | * 15 | * 16 | * @constructor CheckboxSkinElement 17 | * Creates new CheckboxSkinElement instance. 18 | */ 19 | function CheckboxSkinElement() 20 | { 21 | CheckboxSkinElement.base.prototype.constructor.call(this); 22 | } 23 | 24 | //Inherit from CanvasElement 25 | CheckboxSkinElement.prototype = Object.create(CanvasElement.prototype); 26 | CheckboxSkinElement.prototype.constructor = CheckboxSkinElement; 27 | CheckboxSkinElement.base = CanvasElement; 28 | 29 | //////Style Types////////////////////// 30 | CheckboxSkinElement._StyleTypes = Object.create(null); 31 | 32 | /** 33 | * @style CheckColor String 34 | * 35 | * Hex color value to be used for the check icon. Format like "#FF0000" (red). 36 | */ 37 | CheckboxSkinElement._StyleTypes.CheckColor = StyleableBase.EStyleType.NORMAL; //"#000000" 38 | 39 | /** 40 | * @style CheckSize Number 41 | * 42 | * Value between 0 and 1 used to determine the size that the "selected" indicator 43 | * should be rendered relative to this element's size. 44 | */ 45 | CheckboxSkinElement._StyleTypes.CheckSize = StyleableBase.EStyleType.NORMAL; 46 | 47 | 48 | ////////Default Styles//////////////// 49 | 50 | CheckboxSkinElement.StyleDefault = new StyleDefinition(); 51 | 52 | //CheckboxSkinElement specific styles 53 | CheckboxSkinElement.StyleDefault.setStyle("CheckColor", "#000000"); 54 | CheckboxSkinElement.StyleDefault.setStyle("CheckSize", .80); 55 | 56 | 57 | 58 | 59 | /////////Protected Functions//////////////////////// 60 | 61 | //@Override 62 | CheckboxSkinElement.prototype._doStylesUpdated = 63 | function (stylesMap) 64 | { 65 | CheckboxSkinElement.base.prototype._doStylesUpdated.call(this, stylesMap); 66 | 67 | if ("SkinState" in stylesMap || "CheckColor" in stylesMap || "CheckSize" in stylesMap) 68 | this._invalidateRender(); 69 | }; 70 | 71 | //@Override 72 | CheckboxSkinElement.prototype._doMeasure = 73 | function(padWidth, padHeight) 74 | { 75 | this._setMeasuredSize(14, 14); 76 | }; 77 | 78 | //@Override 79 | CheckboxSkinElement.prototype._doRender = 80 | function() 81 | { 82 | CheckboxSkinElement.base.prototype._doRender.call(this); 83 | 84 | var currentState = this.getStyle("SkinState"); 85 | 86 | //Draw check or dash. 87 | if (currentState.indexOf("selected") == 0 || 88 | currentState.indexOf("half") == 0) 89 | { 90 | var ctx = this._getGraphicsCtx(); 91 | 92 | var borderThickness = this._getBorderThickness(); 93 | var checkColor = this.getStyle("CheckColor"); 94 | 95 | var checkSize = this.getStyle("CheckSize"); 96 | var width = this._width * checkSize; 97 | var height = this._height * checkSize; 98 | 99 | var x = 0 + ((this._width - width) / 2); 100 | var y = 0 + ((this._height - height) / 2); 101 | 102 | if (currentState.indexOf("selected") == 0) //Draw check 103 | { 104 | ctx.beginPath(); 105 | 106 | ctx.moveTo(x + (width * .10), 107 | y + (height * .60)); 108 | 109 | ctx.lineTo(x + (width * .40), 110 | y + height * .90); 111 | 112 | ctx.lineTo(x + (width * .90), 113 | y + (height * .26)); 114 | 115 | ctx.lineTo(x + (width * .78), 116 | y + (height * .10)); 117 | 118 | ctx.lineTo(x + (width * .38), 119 | y + height * .65); 120 | 121 | ctx.lineTo(x + (width * .20), 122 | y + height * .45); 123 | 124 | ctx.closePath(); 125 | } 126 | else //Half selected - Draw dash 127 | { 128 | ctx.beginPath(); 129 | 130 | ctx.moveTo(x + (width * .12), 131 | y + (height * .42)); 132 | 133 | ctx.lineTo(x + (width * .12), 134 | y + height * .58); 135 | 136 | ctx.lineTo(x + (width * .88), 137 | y + (height * .58)); 138 | 139 | ctx.lineTo(x + (width * .88), 140 | y + (height * .42)); 141 | 142 | ctx.closePath(); 143 | } 144 | 145 | ctx.fillStyle = checkColor; 146 | ctx.fill(); 147 | } 148 | }; 149 | 150 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/skins/DataGridHeaderColumnDividerSkinElement.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends CanvasElement.js 4 | */ 5 | 6 | ////////////////////////////////////////////////////////////////// 7 | //////DataGridHeaderColumnDividerSkinElement////////////////////// 8 | 9 | /** 10 | * @class DataGridHeaderColumnDividerSkinElement 11 | * @inherits CanvasElement 12 | * 13 | * Default skin class for the draggable DataGrid column dividers. 14 | * Renders a line, and drag arrows when mouse is over. 15 | * 16 | * 17 | * @constructor DataGridHeaderColumnDividerSkinElement 18 | * Creates new DataGridHeaderColumnDividerSkinElement instance. 19 | */ 20 | function DataGridHeaderColumnDividerSkinElement() 21 | { 22 | DataGridHeaderColumnDividerSkinElement.base.prototype.constructor.call(this); 23 | } 24 | 25 | //Inherit from CanvasElement 26 | DataGridHeaderColumnDividerSkinElement.prototype = Object.create(CanvasElement.prototype); 27 | DataGridHeaderColumnDividerSkinElement.prototype.constructor = DataGridHeaderColumnDividerSkinElement; 28 | DataGridHeaderColumnDividerSkinElement.base = CanvasElement; 29 | 30 | //////Style Types////////////////////// 31 | DataGridHeaderColumnDividerSkinElement._StyleTypes = Object.create(null); 32 | 33 | /** 34 | * @style DividerLineColor String 35 | * 36 | * Hex color value to be used for the divider line. Format like "#FF0000" (red). 37 | */ 38 | DataGridHeaderColumnDividerSkinElement._StyleTypes.DividerLineColor = StyleableBase.EStyleType.NORMAL; //"#000000" 39 | 40 | /** 41 | * @style DividerArrowColor String 42 | * 43 | * Hex color value to be used for the arrows. Format like "#FF0000" (red). 44 | */ 45 | DataGridHeaderColumnDividerSkinElement._StyleTypes.DividerArrowColor = StyleableBase.EStyleType.NORMAL; //"up" || "down" || "left" || "right" 46 | 47 | 48 | ////////Default Styles//////////////// 49 | 50 | DataGridHeaderColumnDividerSkinElement.StyleDefault = new StyleDefinition(); 51 | 52 | DataGridHeaderColumnDividerSkinElement.StyleDefault.setStyle("DividerLineColor", "#777777"); 53 | DataGridHeaderColumnDividerSkinElement.StyleDefault.setStyle("DividerArrowColor", "#444444"); 54 | 55 | 56 | 57 | //@Override 58 | DataGridHeaderColumnDividerSkinElement.prototype._doStylesUpdated = 59 | function (stylesMap) 60 | { 61 | DataGridHeaderColumnDividerSkinElement.base.prototype._doStylesUpdated.call(this, stylesMap); 62 | 63 | if ("DividerLineColor" in stylesMap || 64 | "DividerArrowColor" in stylesMap) 65 | { 66 | this._invalidateRender(); 67 | } 68 | }; 69 | 70 | //@Override 71 | DataGridHeaderColumnDividerSkinElement.prototype._doRender = 72 | function() 73 | { 74 | DataGridHeaderColumnDividerSkinElement.base.prototype._doRender.call(this); 75 | 76 | var ctx = this._getGraphicsCtx(); 77 | 78 | var lineColor = this.getStyle("DividerLineColor"); 79 | var arrowColor = this.getStyle("DividerArrowColor"); 80 | var currentState = this.getStyle("SkinState"); 81 | 82 | var x = 0; 83 | var y = 0; 84 | var w = this._width; 85 | var h = this._height; 86 | 87 | ctx.beginPath(); 88 | 89 | ctx.moveTo(x + (w / 2) - .5, y); 90 | ctx.lineTo(x + (w / 2) - .5, y + h); 91 | ctx.lineTo(x + (w / 2) + .5, y + h); 92 | ctx.lineTo(x + (w / 2) + .5, y); 93 | 94 | ctx.closePath(); 95 | 96 | ctx.fillStyle = lineColor; 97 | ctx.fill(); 98 | 99 | //////////////////////////// 100 | 101 | if (currentState == "over" || currentState == "down") 102 | { 103 | var arrowHeight = h / 2; 104 | 105 | ctx.fillStyle = arrowColor; 106 | 107 | ctx.beginPath(); 108 | 109 | ctx.moveTo(x + (w / 2) - .5 - 1, (h / 2) - (arrowHeight / 2)); 110 | ctx.lineTo(x + (w / 2) - .5 - 1, (h / 2) + (arrowHeight / 2)); 111 | ctx.lineTo(x, y + (h / 2)); 112 | 113 | ctx.closePath(); 114 | ctx.fill(); 115 | 116 | ctx.beginPath(); 117 | 118 | ctx.moveTo(x + (w / 2) + .5 + 1, (h / 2) - (arrowHeight / 2)); 119 | ctx.lineTo(x + (w / 2) + .5 + 1, (h / 2) + (arrowHeight / 2)); 120 | ctx.lineTo(x + w, y + (h / 2)); 121 | 122 | ctx.closePath(); 123 | ctx.fill(); 124 | } 125 | }; 126 | 127 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/skins/DropdownArrowButtonSkinElement.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends CanvasElement.js 4 | */ 5 | 6 | /////////////////////////////////////////////////////////////////////// 7 | /////////////////DropdownArrowButtonSkinElement//////////////////////// 8 | 9 | /** 10 | * @class DropdownArrowButtonSkinElement 11 | * @inherits CanvasElement 12 | * 13 | * Default skin class for Arrow button in the DropdownElement. 14 | * Renders the divider line and an arrow. 15 | * 16 | * 17 | * @constructor DropdownArrowButtonSkinElement 18 | * Creates new DropdownArrowButtonSkinElement instance. 19 | */ 20 | function DropdownArrowButtonSkinElement() 21 | { 22 | DropdownArrowButtonSkinElement.base.prototype.constructor.call(this); 23 | } 24 | 25 | //Inherit from CanvasElement 26 | DropdownArrowButtonSkinElement.prototype = Object.create(CanvasElement.prototype); 27 | DropdownArrowButtonSkinElement.prototype.constructor = DropdownArrowButtonSkinElement; 28 | DropdownArrowButtonSkinElement.base = CanvasElement; 29 | 30 | //////Style Types////////////////////// 31 | DropdownArrowButtonSkinElement._StyleTypes = Object.create(null); 32 | 33 | /** 34 | * @style ArrowColor String 35 | * 36 | * Hex color value to be used for the arrow. Format like "#FF0000" (red). 37 | */ 38 | DropdownArrowButtonSkinElement._StyleTypes.ArrowColor = StyleableBase.EStyleType.NORMAL; //"#000000" 39 | 40 | /** 41 | * @style LineColor String 42 | * 43 | * Hex color value to be used for the divider line. Format like "#FF0000" (red). 44 | */ 45 | DropdownArrowButtonSkinElement._StyleTypes.LineColor = StyleableBase.EStyleType.NORMAL; //"#000000" 46 | 47 | 48 | //////Default Styles/////////////////// 49 | 50 | DropdownArrowButtonSkinElement.StyleDefault = new StyleDefinition(); 51 | 52 | DropdownArrowButtonSkinElement.StyleDefault.setStyle("ArrowColor", "#000000"); 53 | DropdownArrowButtonSkinElement.StyleDefault.setStyle("LineColor", "#000000"); 54 | 55 | 56 | /////////Internal Functions//////////////////////// 57 | 58 | //@Override 59 | DropdownArrowButtonSkinElement.prototype._doStylesUpdated = 60 | function (stylesMap) 61 | { 62 | DropdownArrowButtonSkinElement.base.prototype._doStylesUpdated.call(this, stylesMap); 63 | 64 | if ("ArrowColor" in stylesMap || 65 | "LineColor" in stylesMap) 66 | { 67 | this._invalidateRender(); 68 | } 69 | }; 70 | 71 | //@Override 72 | DropdownArrowButtonSkinElement.prototype._doRender = 73 | function() 74 | { 75 | DropdownArrowButtonSkinElement.base.prototype._doRender.call(this); 76 | 77 | var ctx = this._getGraphicsCtx(); 78 | var paddingMetrics = this._getPaddingMetrics(); 79 | 80 | var lineColor = this.getStyle("LineColor"); 81 | var arrowColor = this.getStyle("ArrowColor"); 82 | 83 | var x = paddingMetrics.getX(); 84 | var y = paddingMetrics.getY(); 85 | var width = paddingMetrics.getWidth(); 86 | var height = paddingMetrics.getHeight(); 87 | 88 | if (arrowColor != null) 89 | { 90 | ctx.beginPath(); 91 | 92 | ctx.moveTo(x + (width / 2), y + (height * .60)); 93 | ctx.lineTo(x + (width * .70), y + (height * .40)); 94 | ctx.lineTo(x + (width * .30), y + (height * .40)); 95 | 96 | ctx.closePath(); 97 | 98 | ctx.fillStyle = arrowColor; 99 | ctx.fill(); 100 | } 101 | 102 | if (lineColor != null) 103 | { 104 | var lineHeight = height * .65; 105 | 106 | ctx.beginPath(); 107 | 108 | ctx.moveTo(x, y + (height / 2) - (lineHeight / 2)); 109 | ctx.lineTo(x, y + (height / 2) + (lineHeight / 2)); 110 | ctx.lineTo(x + 1, y + (height / 2) + (lineHeight / 2)); 111 | ctx.lineTo(x + 1, y + (height / 2) - (lineHeight / 2)); 112 | 113 | ctx.closePath(); 114 | 115 | ctx.fillStyle = lineColor; 116 | ctx.fill(); 117 | } 118 | }; 119 | 120 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/skins/RadioButtonSkinElement.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends CanvasElement.js 4 | */ 5 | 6 | /////////////////////////////////////////////////////////////////////// 7 | /////////////////////RadioButtonSkinElement//////////////////////////// 8 | 9 | /** 10 | * @class RadioButtonSkinElement 11 | * @inherits CanvasElement 12 | * 13 | * Default skin class for the RadioButtonElement. 14 | * Renders an inner selected indicator using the BackgroundShape style. 15 | * 16 | * 17 | * @constructor RadioButtonSkinElement 18 | * Creates new RadioButtonSkinElement instance. 19 | */ 20 | function RadioButtonSkinElement() 21 | { 22 | RadioButtonSkinElement.base.prototype.constructor.call(this); 23 | } 24 | 25 | //Inherit from CanvasElement 26 | RadioButtonSkinElement.prototype = Object.create(CanvasElement.prototype); 27 | RadioButtonSkinElement.prototype.constructor = RadioButtonSkinElement; 28 | RadioButtonSkinElement.base = CanvasElement; 29 | 30 | //////Style Types////////////////////// 31 | RadioButtonSkinElement._StyleTypes = Object.create(null); 32 | 33 | /** 34 | * @style CheckColor String 35 | * 36 | * Hex color value to be used for the check icon. Format like "#FF0000" (red). 37 | */ 38 | RadioButtonSkinElement._StyleTypes.CheckColor = StyleableBase.EStyleType.NORMAL; //"#000000" 39 | 40 | /** 41 | * @style CheckSize Number 42 | * 43 | * Value between 0 and 1 used to determine the size that the "selected" indicator 44 | * should be rendered relative to this element's size. 45 | */ 46 | RadioButtonSkinElement._StyleTypes.CheckSize = StyleableBase.EStyleType.NORMAL; 47 | 48 | 49 | ////////Default Styles//////////////// 50 | RadioButtonSkinElement.StyleDefault = new StyleDefinition(); 51 | 52 | //RadioButtonSkinElement specific styles 53 | RadioButtonSkinElement.StyleDefault.setStyle("CheckColor", "#000000"); 54 | RadioButtonSkinElement.StyleDefault.setStyle("CheckSize", .35); 55 | 56 | 57 | /////////Protected Functions//////////////////////// 58 | 59 | //@Override 60 | RadioButtonSkinElement.prototype._doStylesUpdated = 61 | function (stylesMap) 62 | { 63 | RadioButtonSkinElement.base.prototype._doStylesUpdated.call(this, stylesMap); 64 | 65 | if ("SkinState" in stylesMap || "CheckColor" in stylesMap || "CheckSize" in stylesMap) 66 | this._invalidateRender(); 67 | }; 68 | 69 | //@Override 70 | RadioButtonSkinElement.prototype._doMeasure = 71 | function(padWidth, padHeight) 72 | { 73 | this._setMeasuredSize(14, 14); 74 | }; 75 | 76 | //@Override 77 | RadioButtonSkinElement.prototype._doRender = 78 | function() 79 | { 80 | RadioButtonSkinElement.base.prototype._doRender.call(this); 81 | 82 | var currentState = this.getStyle("SkinState"); 83 | 84 | //Draw indicator. 85 | if (currentState.indexOf("selected") == 0) 86 | { 87 | var ctx = this._getGraphicsCtx(); 88 | 89 | var checkSize = this.getStyle("CheckSize"); 90 | 91 | var indicatorMetrics = new DrawMetrics(); 92 | indicatorMetrics._width = this._width * checkSize; 93 | indicatorMetrics._height = this._height * checkSize; 94 | indicatorMetrics._x = (this._width - indicatorMetrics._width) / 2; 95 | indicatorMetrics._y = (this._height - indicatorMetrics._height) / 2; 96 | 97 | if (indicatorMetrics._width <= 0 || indicatorMetrics._height <= 0) 98 | return; 99 | 100 | ctx.beginPath(); 101 | this._drawBackgroundShape(ctx, indicatorMetrics); 102 | 103 | ctx.fillStyle = this.getStyle("CheckColor"); 104 | ctx.fill(); 105 | } 106 | }; 107 | 108 | -------------------------------------------------------------------------------- /src/FlexCanvasJS/skins/ScrollButtonSkinElement.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @depends CanvasElement.js 4 | */ 5 | 6 | /////////////////////////////////////////////////////////////////////// 7 | /////////////////////ScrollButtonSkinElement/////////////////////////// 8 | 9 | /** 10 | * @class ScrollButtonSkinElement 11 | * @inherits CanvasElement 12 | * 13 | * Default skin class for the ScrollButton. 14 | * 15 | * 16 | * @constructor ScrollButtonSkinElement 17 | * Creates new ScrollButtonSkinElement instance. 18 | */ 19 | function ScrollButtonSkinElement() 20 | { 21 | ScrollButtonSkinElement.base.prototype.constructor.call(this); 22 | } 23 | 24 | //Inherit from CanvasElement 25 | ScrollButtonSkinElement.prototype = Object.create(CanvasElement.prototype); 26 | ScrollButtonSkinElement.prototype.constructor = ScrollButtonSkinElement; 27 | ScrollButtonSkinElement.base = CanvasElement; 28 | 29 | //////Style Types////////////////////// 30 | ScrollButtonSkinElement._StyleTypes = Object.create(null); 31 | 32 | /** 33 | * @style ArrowColor String 34 | * 35 | * Hex color value to be used for the arrow icon. Format like "#FF0000" (red). 36 | */ 37 | ScrollButtonSkinElement._StyleTypes.ArrowColor = StyleableBase.EStyleType.NORMAL; //"#000000" 38 | 39 | /** 40 | * @style ArrowDirection String 41 | * 42 | * Determines the arrow direction. Allowable values are "up", "down", "left", "right". 43 | * Note that ScrollBar sets this style directly to the parent button depending on the scroll bar orientation. 44 | */ 45 | ScrollButtonSkinElement._StyleTypes.ArrowDirection = StyleableBase.EStyleType.NORMAL; //"up" || "down" || "left" || "right" 46 | 47 | 48 | ////////Default Styles////////////////// 49 | 50 | ScrollButtonSkinElement.StyleDefault = new StyleDefinition(); 51 | 52 | ScrollButtonSkinElement.StyleDefault.setStyle("ArrowColor", "#000000"); 53 | ScrollButtonSkinElement.StyleDefault.setStyle("ArrowDirection", "up"); 54 | 55 | 56 | /////////Internal Functions//////////////////////// 57 | 58 | //@Override 59 | ScrollButtonSkinElement.prototype._doStylesUpdated = 60 | function (stylesMap) 61 | { 62 | ScrollButtonSkinElement.base.prototype._doStylesUpdated.call(this, stylesMap); 63 | 64 | if ("ArrowColor" in stylesMap || 65 | "ArrowDirection" in stylesMap) 66 | { 67 | this._invalidateRender(); 68 | } 69 | }; 70 | 71 | //@Override 72 | ScrollButtonSkinElement.prototype._doRender = 73 | function() 74 | { 75 | ScrollButtonSkinElement.base.prototype._doRender.call(this); 76 | 77 | var arrowDirection = this.getStyle("ArrowDirection"); 78 | var arrowColor = this.getStyle("ArrowColor"); 79 | 80 | if (arrowColor == null || arrowDirection == null) 81 | return; 82 | 83 | var ctx = this._getGraphicsCtx(); 84 | 85 | var borderThickness = this._getBorderThickness(); 86 | 87 | var x = borderThickness; 88 | var y = borderThickness; 89 | var width = this._width - (borderThickness * 2); 90 | var height = this._height - (borderThickness * 2); 91 | 92 | ctx.beginPath(); 93 | 94 | if (arrowDirection == "up") 95 | { 96 | ctx.moveTo(x + (width / 2), y + (height * .35)); 97 | ctx.lineTo(x + (width * .80), y + (height * .65)); 98 | ctx.lineTo(x + (width * .20), y + (height * .65)); 99 | } 100 | else if (arrowDirection == "down") 101 | { 102 | ctx.moveTo(x + (width / 2), y + (height * .65)); 103 | ctx.lineTo(x + (width * .80), y + (height * .35)); 104 | ctx.lineTo(x + (width * .20), y + (height * .35)); 105 | } 106 | else if (arrowDirection == "left") 107 | { 108 | ctx.moveTo(x + (width * .35), y + (height / 2)); 109 | ctx.lineTo(x + (width * .65), y + (height * .20)); 110 | ctx.lineTo(x + (width * .65), y + (height * .80)); 111 | } 112 | else if (arrowDirection == "right") 113 | { 114 | ctx.moveTo(x + (width * .65), y + (height / 2)); 115 | ctx.lineTo(x + (width * .35), y + (height * .20)); 116 | ctx.lineTo(x + (width * .35), y + (height * .80)); 117 | } 118 | 119 | ctx.closePath(); 120 | 121 | ctx.fillStyle = arrowColor; 122 | ctx.fill(); 123 | 124 | }; 125 | 126 | 127 | -------------------------------------------------------------------------------- /src/TestPad.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FlexCanvasJS Web Application 6 | 7 | 10 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /src/TestPadJS.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | //Create elements 4 | var canvasManager = new CanvasManager(); 5 | var dropdown = new DropdownElement(); 6 | 7 | function init() 8 | { 9 | //Attach the DOM canvas to our CanvasManager 10 | canvasManager.setCanvas(document.getElementById("flexCanvasApplication")); 11 | 12 | var dropdownLocaleCollection = new ListCollection(); 13 | dropdownLocaleCollection.addItem({key:"en-us", label:"English"}); 14 | dropdownLocaleCollection.addItem({key:"es-es", label:"Espanol"}); 15 | 16 | dropdown.setListCollection(dropdownLocaleCollection); 17 | dropdown.setSelectedIndex(0); 18 | 19 | //Add dropdown to CanvasManager 20 | canvasManager.addElement(dropdown); 21 | } 22 | 23 | 24 | 25 | 26 | 27 | --------------------------------------------------------------------------------