├── gm2d ├── ui │ ├── Size.hx │ ├── WidgetState.hx │ ├── DockPosition.hx │ ├── IDialog.hx │ ├── Control.hx │ ├── ChoiceBox.hx │ ├── IListDrag.hx │ ├── TitleBar.hx │ ├── RGBDialog.hx │ ├── Phase.hx │ ├── IDock.hx │ ├── StaticText.hx │ ├── CheckButtons.hx │ ├── FrameWidget.hx │ ├── GroupBox.hx │ ├── DockZones.hx │ ├── RadioGroup.hx │ ├── IDockable.hx │ ├── AdoHandler.hx │ ├── DialogScreen.hx │ ├── WaxeDialog.hx │ ├── SecondaryWindowDialog.hx │ ├── FileSave.hx │ ├── MenuGroup.hx │ ├── Image.hx │ ├── MenuItem.hx │ ├── ChoiceButtons.hx │ ├── TabBar.hx │ ├── MiniWin.hx │ ├── TabWidget.hx │ ├── FileBox.hx │ ├── SecondaryWin.hx │ ├── AsyncThumbnailer.hx │ ├── ProgressBar.hx │ ├── KeyboardAccel.hx │ ├── DockSizeHandler.hx │ ├── ProgressDialog.hx │ ├── MultiTouchButton.hx │ └── Toolbar.hx ├── Version.hx ├── blit │ ├── Grid.hx │ ├── Tile.hx │ ├── NMEViewport.hx │ ├── BMPViewport.hx │ ├── Layer.hx │ ├── NMELayer.hx │ ├── Tilesheets.hx │ ├── GridHandler.hx │ └── BMPLayer.hx ├── CInt.hx ├── InterpolationMethod.hx ├── ScreenScaleMode.hx ├── svg │ ├── FillType.hx │ ├── TextStyle.hx │ ├── FilterSet.hx │ ├── SVG2Gfx.hx │ ├── Marker.hx │ ├── Link.hx │ ├── TSpan.hx │ ├── Path.hx │ ├── Group.hx │ ├── Text.hx │ ├── DisplayElement.hx │ ├── BitmapDataManager.hx │ └── Grad.hx ├── swf │ ├── SWFByteArray.hx │ ├── MorphObject.hx │ ├── Character.hx │ ├── DisplayAttributes.hx │ ├── ScaledFont.hx │ ├── SWFLibrary.hx │ ├── DepthSlot.hx │ ├── Frame.hx │ ├── Bitmap.hx │ ├── StaticText.hx │ └── EditText.hx ├── skin │ ├── LineStyle.hx │ ├── BitmapStyle.hx │ ├── ProgressStyle.hx │ ├── FillStyle.hx │ ├── Shape.hx │ ├── SliderRenderer.hx │ ├── ShadowInstance.hx │ ├── EdgeFlags.hx │ ├── DockRenderer.hx │ └── ShadowCache.hx ├── icons │ ├── EastWest.hx │ ├── NorthSouth.hx │ ├── NSEW.hx │ ├── Icon.hx │ └── Folder.hx ├── gfx │ ├── GfxTextFinder.hx │ ├── LineStyle.hx │ ├── Gradient.hx │ ├── GfxExtent.hx │ ├── Gfx.hx │ └── Gfx2Haxe.hx ├── tween │ ├── Tween.hx │ └── Timeline.hx ├── Lib.hx ├── input │ ├── Input.hx │ └── LRInput.hx ├── math │ └── TimeAverage.hx ├── reso │ └── Resources.hx └── Screen.hx ├── samples ├── 04-Particles │ ├── cpp.hxml │ ├── neko.hxml │ ├── Blobs.png │ ├── swf.hxml │ └── Particles.nmml ├── 03-Dialog │ ├── neko.hxml │ ├── swf.hxml │ ├── Dialog.nmml │ └── Dialog.hx ├── 01-Tilemap │ ├── Tiles.png │ └── Tilemap.nmml ├── 08-Swf │ ├── tests │ │ ├── Text.swf │ │ ├── ShapeMorph.swf │ │ ├── GradientFill.swf │ │ ├── AdvancedLines.swf │ │ └── GradientFillMotion.swf │ ├── SwfTest.nmml │ └── SwfTest.hx ├── 10-Wwx2014 │ ├── Blobs.png │ ├── Bullet.png │ ├── Level1.jpg │ ├── Level2.jpg │ ├── Level3.jpg │ ├── Level4.jpg │ ├── BuildMagic.jpg │ ├── Readme.txt │ ├── game │ │ └── Puck.hx │ ├── build.nmml │ ├── CodeBox.hx │ └── Particles.hx ├── 11-wwx2015 │ ├── Blobs.png │ ├── Bullet.png │ ├── VmVmVm.jpg │ ├── TestScreen.png │ ├── build.nmml │ ├── CodeBox.hx │ └── icon.svg ├── 05-BitmapFont │ ├── Edmunds.png │ ├── edmunds.ttf │ ├── neko.hxml │ ├── swf.hxml │ ├── BitmapFont.nmml │ ├── BitmapFont.hx │ └── READ_ME.TXT ├── 06-App │ ├── neko.hxml │ ├── flash.hxml │ └── SampleApp.nmml ├── 07-RenderToImage │ ├── compile.hxml │ └── RenderToImage.hx ├── 09-BatchConvert │ └── compile.hxml ├── 00-ImportAll │ ├── ApplicationMain.hx │ └── makefile ├── SvgDir │ ├── build.nmml │ └── Svg.hx └── 02-Svg │ ├── Svg.nmml │ └── Svg.hx ├── README.md ├── haxelib.json ├── .gitignore ├── Changes.md ├── LICENSE ├── tools └── version │ └── Write.hx └── .github └── workflows └── main.yml /gm2d/ui/Size.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | typedef Size=nme.geom.Point; 4 | -------------------------------------------------------------------------------- /samples/04-Particles/cpp.hxml: -------------------------------------------------------------------------------- 1 | -main Particles 2 | -cpp cpp 3 | -lib nme 4 | -cp ../.. 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | gm2d 2 | ==== 3 | A library for rapid game developement with Haxe, NME and Waxe. 4 | -------------------------------------------------------------------------------- /samples/03-Dialog/neko.hxml: -------------------------------------------------------------------------------- 1 | -main Dialog 2 | -neko Dialog.n 3 | -lib nme 4 | -cp ../.. 5 | -------------------------------------------------------------------------------- /samples/04-Particles/neko.hxml: -------------------------------------------------------------------------------- 1 | -main Particles 2 | -neko Particles.n 3 | -lib nme 4 | -cp ../.. 5 | -------------------------------------------------------------------------------- /samples/01-Tilemap/Tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/01-Tilemap/Tiles.png -------------------------------------------------------------------------------- /samples/04-Particles/Blobs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/04-Particles/Blobs.png -------------------------------------------------------------------------------- /samples/08-Swf/tests/Text.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/08-Swf/tests/Text.swf -------------------------------------------------------------------------------- /samples/10-Wwx2014/Blobs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/10-Wwx2014/Blobs.png -------------------------------------------------------------------------------- /samples/10-Wwx2014/Bullet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/10-Wwx2014/Bullet.png -------------------------------------------------------------------------------- /samples/10-Wwx2014/Level1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/10-Wwx2014/Level1.jpg -------------------------------------------------------------------------------- /samples/10-Wwx2014/Level2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/10-Wwx2014/Level2.jpg -------------------------------------------------------------------------------- /samples/10-Wwx2014/Level3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/10-Wwx2014/Level3.jpg -------------------------------------------------------------------------------- /samples/10-Wwx2014/Level4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/10-Wwx2014/Level4.jpg -------------------------------------------------------------------------------- /samples/11-wwx2015/Blobs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/11-wwx2015/Blobs.png -------------------------------------------------------------------------------- /samples/11-wwx2015/Bullet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/11-wwx2015/Bullet.png -------------------------------------------------------------------------------- /samples/11-wwx2015/VmVmVm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/11-wwx2015/VmVmVm.jpg -------------------------------------------------------------------------------- /gm2d/Version.hx: -------------------------------------------------------------------------------- 1 | package gm2d; 2 | class Version { 3 | public static inline var name="0.0.0"; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /samples/03-Dialog/swf.hxml: -------------------------------------------------------------------------------- 1 | -main Dialog 2 | -swf9 Dialog.swf 3 | -swf-header 640:480:60:a0a0ff 4 | -cp ../.. 5 | -------------------------------------------------------------------------------- /samples/05-BitmapFont/Edmunds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/05-BitmapFont/Edmunds.png -------------------------------------------------------------------------------- /samples/05-BitmapFont/edmunds.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/05-BitmapFont/edmunds.ttf -------------------------------------------------------------------------------- /samples/06-App/neko.hxml: -------------------------------------------------------------------------------- 1 | -main SampleApp 2 | -neko SampleApp.n 3 | -lib nme 4 | -lib systools 5 | -cp ../.. 6 | -------------------------------------------------------------------------------- /samples/07-RenderToImage/compile.hxml: -------------------------------------------------------------------------------- 1 | -main RenderToImage 2 | -neko RenderToImage.n 3 | -lib nme 4 | -cp ../.. 5 | -------------------------------------------------------------------------------- /samples/08-Swf/tests/ShapeMorph.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/08-Swf/tests/ShapeMorph.swf -------------------------------------------------------------------------------- /samples/10-Wwx2014/BuildMagic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/10-Wwx2014/BuildMagic.jpg -------------------------------------------------------------------------------- /samples/11-wwx2015/TestScreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/11-wwx2015/TestScreen.png -------------------------------------------------------------------------------- /gm2d/blit/Grid.hx: -------------------------------------------------------------------------------- 1 | package gm2d.blit; 2 | 3 | typedef Tiles = Array; 4 | typedef Grid = Array; 5 | 6 | 7 | -------------------------------------------------------------------------------- /samples/06-App/flash.hxml: -------------------------------------------------------------------------------- 1 | -main SampleApp 2 | -swf9 SampleApp.swf 3 | -swf-header 640:480:60:ffffff 4 | -cp ../.. 5 | -------------------------------------------------------------------------------- /samples/08-Swf/tests/GradientFill.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/08-Swf/tests/GradientFill.swf -------------------------------------------------------------------------------- /gm2d/CInt.hx: -------------------------------------------------------------------------------- 1 | package gm2d; 2 | 3 | #if flash 4 | typedef CInt = UInt; 5 | #else 6 | typedef CInt = Int; 7 | #end 8 | -------------------------------------------------------------------------------- /samples/04-Particles/swf.hxml: -------------------------------------------------------------------------------- 1 | -main Particles 2 | -swf9 Particles.swf 3 | -swf-header 480:320:1000:202040 4 | -cp ../.. 5 | -------------------------------------------------------------------------------- /samples/08-Swf/tests/AdvancedLines.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/08-Swf/tests/AdvancedLines.swf -------------------------------------------------------------------------------- /samples/09-BatchConvert/compile.hxml: -------------------------------------------------------------------------------- 1 | -main BatchConvert 2 | -neko BatchConvert.n 3 | -lib nme 4 | --remap flash:nme 5 | -cp ../.. 6 | -------------------------------------------------------------------------------- /samples/05-BitmapFont/neko.hxml: -------------------------------------------------------------------------------- 1 | -main BitmapFont 2 | -neko BitmapFont.n 3 | -lib nme 4 | -resource Edmunds.png@font 5 | -cp ../.. 6 | -------------------------------------------------------------------------------- /samples/08-Swf/tests/GradientFillMotion.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nmehost/gm2d/HEAD/samples/08-Swf/tests/GradientFillMotion.swf -------------------------------------------------------------------------------- /gm2d/InterpolationMethod.hx: -------------------------------------------------------------------------------- 1 | package gm2d; 2 | 3 | 4 | enum InterpolationMethod 5 | { 6 | RGB; 7 | LINEAR_RGB; 8 | STEP; 9 | } 10 | -------------------------------------------------------------------------------- /samples/05-BitmapFont/swf.hxml: -------------------------------------------------------------------------------- 1 | -main BitmapFont 2 | -swf9 BitmapFont.swf 3 | -swf-header 640:480:60:400000 4 | -resource Edmunds.png@font 5 | -cp ../.. 6 | -------------------------------------------------------------------------------- /samples/10-Wwx2014/Readme.txt: -------------------------------------------------------------------------------- 1 | Images used without permission, original authors hold all copyrights. 2 | Please log an issue if you want images removed. 3 | 4 | -------------------------------------------------------------------------------- /samples/00-ImportAll/ApplicationMain.hx: -------------------------------------------------------------------------------- 1 | // Dummy 2 | class ApplicationMain 3 | { 4 | 5 | public static function getAsset(s:String):Dynamic { return null; } 6 | 7 | } 8 | 9 | -------------------------------------------------------------------------------- /gm2d/ScreenScaleMode.hx: -------------------------------------------------------------------------------- 1 | package gm2d; 2 | 3 | enum ScreenScaleMode 4 | { 5 | CENTER_SCALED; 6 | TOPLEFT_SCALED; 7 | PIXEL_PERFECT; 8 | TOPLEFT_UNSCALED; 9 | } 10 | -------------------------------------------------------------------------------- /gm2d/ui/WidgetState.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | enum WidgetState 4 | { 5 | WidgetNormal; 6 | WidgetCurrent; 7 | WidgetDisabled; 8 | WidgetMultiValued; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /gm2d/svg/FillType.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | 3 | enum FillType 4 | { 5 | FillGrad(grad:Grad); 6 | FillSolid(colour:Int); 7 | FillNone; 8 | FillCurrentColor; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /gm2d/swf/SWFByteArray.hx: -------------------------------------------------------------------------------- 1 | package gm2d.swf; 2 | 3 | #if flash 4 | 5 | typedef SWFByteArray = flash.utils.ByteArray; 6 | 7 | #else 8 | 9 | typedef SWFByteArray = String; 10 | 11 | #end 12 | -------------------------------------------------------------------------------- /gm2d/ui/DockPosition.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | enum DockPosition 4 | { 5 | DOCK_OVER; 6 | DOCK_LEFT; 7 | DOCK_RIGHT; 8 | DOCK_TOP; 9 | DOCK_BOTTOM; 10 | DOCK_BAR; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /gm2d/ui/IDialog.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | interface IDialog 4 | { 5 | public function closeFrame():Void; 6 | public function asDialog():Dialog; 7 | public function asScreen():DialogScreen; 8 | } 9 | -------------------------------------------------------------------------------- /gm2d/skin/LineStyle.hx: -------------------------------------------------------------------------------- 1 | package gm2d.skin; 2 | 3 | enum LineStyle 4 | { 5 | LineNone; 6 | LineBorder; 7 | LineTrim; 8 | LineHighlight; 9 | LineSolid( width:Float, rgb:Int, a:Float ); 10 | } 11 | 12 | 13 | -------------------------------------------------------------------------------- /gm2d/svg/TextStyle.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | 3 | class TextStyle 4 | { 5 | public var fill:FillType; 6 | public var size:Float; 7 | public var family:String; 8 | public var weight:String; 9 | 10 | public function new() {} 11 | } 12 | 13 | 14 | -------------------------------------------------------------------------------- /gm2d/svg/FilterSet.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | 3 | import nme.geom.Rectangle; 4 | import nme.filters.*; 5 | 6 | class FilterSet 7 | { 8 | // Rect? 9 | public var filters:Array; 10 | 11 | public function new() 12 | { 13 | filters = []; 14 | } 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /gm2d/skin/BitmapStyle.hx: -------------------------------------------------------------------------------- 1 | package gm2d.skin; 2 | 3 | import nme.display.DisplayObject; 4 | import nme.display.BitmapData; 5 | 6 | enum BitmapStyle 7 | { 8 | BitmapBitmap(bmp:BitmapData); 9 | BitmapFactory(factory:String->Int->BitmapData); 10 | BitmapAndDisable(bmp:BitmapData,bmpDisabled:BitmapData); 11 | } 12 | -------------------------------------------------------------------------------- /gm2d/skin/ProgressStyle.hx: -------------------------------------------------------------------------------- 1 | package gm2d.skin; 2 | 3 | enum ProgressStyle 4 | { 5 | ProgressRoundRect( outlineCol:Int, fillCol:Int, emptyCol:Int, lineWidth:Float, radius:Float ); 6 | ProgressRoundRectBall( outlineCol:Int, fillCol:Int, emptyCol:Int, lineWidth:Float, radius:Float ); 7 | } 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gm2d", 3 | "license": "BSD", 4 | "tags": ["cross","flash","nme","game","svg"], 5 | "description": "GM2D helper classes for rapid game making in 2D.", 6 | "contributors": ["gamehaxe"], 7 | "releasenote": "See Changes.md", 8 | "version": "4.3.0", 9 | "url": "https://github.com/nmehost/gm2d", 10 | "dependencies": { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /gm2d/svg/SVG2Gfx.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | 3 | import Xml; 4 | 5 | // To help old code... 6 | 7 | class SVG2Gfx 8 | { 9 | var renderer : SvgRenderer; 10 | 11 | public function new (inXml:Xml) 12 | { 13 | renderer = new SvgRenderer(new Svg(inXml) ); 14 | } 15 | 16 | public function CreateShape() 17 | { 18 | return renderer.createShape(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /gm2d/svg/Marker.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | 3 | import nme.geom.Matrix; 4 | 5 | class Marker extends Group 6 | { 7 | public var path:Path; 8 | public var refX:Float; 9 | public var refY:Float; 10 | public var orient:String; 11 | 12 | public function new() 13 | { 14 | super(); 15 | refX = refY = 0; 16 | } 17 | 18 | override public function asMarker() : Marker return this; 19 | } 20 | -------------------------------------------------------------------------------- /gm2d/ui/Control.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | 4 | import nme.display.DisplayObjectContainer; 5 | import nme.events.MouseEvent; 6 | import gm2d.ui.Layout; 7 | import gm2d.skin.Skin; 8 | 9 | class Control extends Widget 10 | { 11 | public function new(?inSkin:Skin,?inLineage:Array, ?inAttribs:Dynamic) 12 | { 13 | super(skin,Widget.addLine(inLineage,"Control"),inAttribs); 14 | } 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /gm2d/ui/ChoiceBox.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | class ChoiceBox extends ComboBox 4 | { 5 | public function new(inVal="", ?inOptions:Array, ?inDisplay:Array, 6 | ?inOnSelectIndex:Int->Void, ?inOnSelectString:String->Void, ?inLineage:Array, ?inAttribs:{}) 7 | { 8 | super(inVal, inOptions, inDisplay, inOnSelectIndex, inOnSelectString, Widget.addLine(inLineage,"ChoiceBox"), inAttribs ); 9 | } 10 | } 11 | 12 | 13 | -------------------------------------------------------------------------------- /gm2d/ui/IListDrag.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import nme.events.MouseEvent; 4 | 5 | enum ListDragPos 6 | { 7 | PosAbove; 8 | PosOver; 9 | PosBelow; 10 | } 11 | 12 | interface IListDrag 13 | { 14 | function listShouldDrag(item:Int,ev:MouseEvent) : Bool; 15 | function listCanDrop(src:Int,dest:Int,position:ListDragPos,ev:MouseEvent) : Bool; 16 | function listDoDrop(src:Int,dest:Int,position:ListDragPos,ev:MouseEvent):Void; 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /gm2d/ui/TitleBar.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import nme.text.TextField; 4 | import nme.display.BitmapData; 5 | import nme.events.MouseEvent; 6 | import nme.ui.Keyboard; 7 | import gm2d.ui.Button; 8 | import gm2d.skin.Skin; 9 | import gm2d.ui.Layout; 10 | 11 | class TitleBar extends TextLabel 12 | { 13 | public function new(inVal="",?inLineage:Array, ?inAttribs:{} ) 14 | { 15 | super(inVal,Widget.addLine(inLineage,"TitleBar"),inAttribs); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /gm2d/svg/Link.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | 3 | import nme.geom.Matrix; 4 | 5 | class Link extends DisplayElement 6 | { 7 | public function new() 8 | { 9 | super(); 10 | width = height = 1.0; 11 | } 12 | 13 | public var link:String; 14 | public var width:Float; 15 | public var height:Float; 16 | 17 | override function toString() return 'Link($link)'; 18 | 19 | override public function asLink() : Link return this; 20 | 21 | 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /gm2d/svg/TSpan.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | 3 | 4 | class TSpan 5 | { 6 | public var text:String; 7 | public var x:Null; 8 | public var y:Null; 9 | 10 | public function new(el:Xml) 11 | { 12 | if (el.exists("x")) 13 | x = Std.parseFloat( el.get("x") ); 14 | if (el.exists("y")) 15 | y = Std.parseFloat( el.get("y") ); 16 | var textChild = el.firstChild(); 17 | text = textChild==null ? "" : textChild.nodeValue; 18 | } 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /gm2d/svg/Path.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | 3 | import nme.geom.Matrix; 4 | 5 | typedef PathSegments = Array; 6 | 7 | class Path extends DisplayElement 8 | { 9 | public var segments:PathSegments; 10 | 11 | public function new() 12 | { 13 | super(); 14 | segments = []; 15 | } 16 | 17 | override function toString():String return "Path(" + (segments==null ? "0" : segments.length+"") + ")"; 18 | 19 | 20 | override public function asPath() : Path return this; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /gm2d/skin/FillStyle.hx: -------------------------------------------------------------------------------- 1 | package gm2d.skin; 2 | 3 | import nme.display.BitmapData; 4 | 5 | enum FillStyle 6 | { 7 | FillNone; 8 | FillLight; 9 | FillMedium; 10 | FillButton; 11 | FillDark; 12 | FillHighlight; 13 | FillDisabled; 14 | FillTransparent; 15 | FillRowOdd; 16 | FillRowEven; 17 | FillRowSelect; 18 | FillBitmap( bmp:BitmapData ); 19 | FillSolid( rgb:Int, a:Float ); 20 | FillGradV( rgb0:Int, rgb1:Int, a:Float ); 21 | FillGradH( rgb0:Int, rgb1:Int, a:Float ); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /gm2d/icons/EastWest.hx: -------------------------------------------------------------------------------- 1 | package gm2d.icons; 2 | 3 | import gm2d.gfx.GfxBytes; 4 | import gm2d.gfx.GfxGraphics; 5 | import nme.display.Graphics; 6 | 7 | 8 | class EastWest extends Icon 9 | { 10 | static var data = "eNpjdGJgYABhOYcDDAyOBQwMXP///7dvYGAQARFAAKUYHByQFMk7AnmOBjBGAoixApkBlroBUwwSmQFjNMB0wRkgKZjJPKIMAKURGc4"; 11 | var gfx:GfxBytes; 12 | 13 | public function new() 14 | { 15 | super(); 16 | gfx = GfxBytes.fromString(data); 17 | } 18 | 19 | public override function render(g:Graphics) 20 | { 21 | gfx.iterate(new GfxGraphics(g)); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /gm2d/swf/MorphObject.hx: -------------------------------------------------------------------------------- 1 | package gm2d.swf; 2 | 3 | class MorphObject extends nme.display.Sprite 4 | { 5 | var mData:MorphShape; 6 | 7 | public function new(inData:MorphShape) 8 | { 9 | super(); 10 | mData = inData; 11 | } 12 | 13 | 14 | public function SetRatio(inRatio:Int) 15 | { 16 | // TODO: this could be cached in child objects. 17 | var gfx = graphics; 18 | gfx.clear(); 19 | var f = inRatio/65536.0; 20 | return mData.Render(gfx,f); 21 | } 22 | 23 | 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /gm2d/swf/Character.hx: -------------------------------------------------------------------------------- 1 | package gm2d.swf; 2 | 3 | import gm2d.swf.Shape; 4 | import gm2d.swf.MorphShape; 5 | import gm2d.swf.Sprite; 6 | import gm2d.swf.Bitmap; 7 | import gm2d.swf.Font; 8 | import gm2d.swf.StaticText; 9 | import gm2d.swf.EditText; 10 | 11 | enum Character 12 | { 13 | charShape(inShape:Shape); 14 | charMorphShape(inMorphShape:MorphShape); 15 | charSprite(inSprite:Sprite); 16 | charBitmap(inBitmap:Bitmap); 17 | charFont(inFont:Font); 18 | charStaticText(inText:StaticText); 19 | charEditText(inText:EditText); 20 | } 21 | -------------------------------------------------------------------------------- /gm2d/gfx/GfxTextFinder.hx: -------------------------------------------------------------------------------- 1 | package gm2d.gfx; 2 | 3 | import gm2d.svg.Text; 4 | import gm2d.svg.TextStyle; 5 | 6 | class GfxTextFinder extends Gfx 7 | { 8 | public var text : Text; 9 | public var style : TextStyle; 10 | 11 | public function new() { super(); } 12 | 13 | override public function geometryOnly() { return true; } 14 | override public function renderText(inText:Text, m:nme.geom.Matrix, inStyle:TextStyle) 15 | { 16 | if (text==null) 17 | { 18 | text = inText; 19 | style = inStyle; 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /gm2d/icons/NorthSouth.hx: -------------------------------------------------------------------------------- 1 | package gm2d.icons; 2 | 3 | import gm2d.gfx.GfxBytes; 4 | import gm2d.gfx.GfxGraphics; 5 | import nme.display.Graphics; 6 | 7 | 8 | class NorthSouth extends Icon 9 | { 10 | static var data = "eNpjdGJgYABhOccWBgaHCQwMXP///7dvYGAQARFAAKUYHByQFMk7LmFgcNQAMXqQGXNgUmAGULHjGRDDAyZSgczQgElpQBWDTOYRZQAAtXkZgg"; 11 | var gfx:GfxBytes; 12 | 13 | public function new() 14 | { 15 | super(); 16 | gfx = GfxBytes.fromString(data); 17 | } 18 | 19 | public override function render(g:Graphics) 20 | { 21 | gfx.iterate(new GfxGraphics(g)); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # compiled haxe code 7 | *.swf 8 | *.n 9 | 10 | # vi temp 11 | *.swp 12 | 13 | # Compiled Dynamic libraries 14 | *.so 15 | *.dylib 16 | *.ndll 17 | 18 | # Compiled Static libraries 19 | *.lai 20 | *.la 21 | *.a 22 | 23 | # Untracked directories 24 | obj/ 25 | Export/ 26 | bin/ 27 | cpp/ 28 | lib/*/ 29 | 30 | Thumbs.db 31 | 32 | 33 | 34 | 35 | # Created files 36 | samples/00-ImportAll/All.hx 37 | 38 | # Miscellaneous 39 | all_objs 40 | *.pdb 41 | out.txt 42 | 43 | -------------------------------------------------------------------------------- /samples/00-ImportAll/makefile: -------------------------------------------------------------------------------- 1 | all: create-file build-file 2 | 3 | ifndef FIND_EXE 4 | FIND_EXE := find 5 | endif 6 | 7 | create-file: 8 | echo "" > All.hx 9 | cd ../.. && $(FIND_EXE) gm2d -name "*.hx" | awk -F '.hx$$' '{ x=$$1; gsub("\/",".",x); print "import " x ";" }' >> samples/00-ImportAll/All.hx 10 | echo "class All { public static function main(){} }" >> All.hx 11 | 12 | 13 | build-file: 14 | haxe -cp ../.. -lib nme -main All -dce no -cpp cpp 15 | haxe -cp ../.. -lib nme -main All -dce no -neko t.n 16 | 17 | # haxe -cp ../.. -lib nme -main All -dce no -swf t.swf 18 | 19 | -------------------------------------------------------------------------------- /gm2d/skin/Shape.hx: -------------------------------------------------------------------------------- 1 | package gm2d.skin; 2 | 3 | import gm2d.ui.Widget; 4 | 5 | import nme.display.BitmapData; 6 | import nme.geom.Rectangle; 7 | 8 | enum Shape 9 | { 10 | ShapeNone; 11 | ShapeRect; 12 | ShapeRectFlags(flags:Int); 13 | ShapeUnderlineRect; 14 | ShapeRoundRect; 15 | ShapeRoundRectRad(inRad:Float); 16 | ShapeRoundRectFlags(flags:Int, inRad:Float); 17 | ShapeScale9(bmp:BitmapData, inner:Rectangle, edgeScale:Float); 18 | ShapeShadowRect(depth:Float,flags:Int); 19 | ShapeCustom( renderer:Widget->Void ); 20 | ShapeItemRect; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /gm2d/ui/RGBDialog.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import gm2d.RGBHSV; 4 | 5 | class RGBDialog extends Dialog 6 | { 7 | var control:ColourControl; 8 | 9 | public function new(inRGB:RGBHSV, inOnColour:RGBHSV->Int->Void) 10 | { 11 | control = new ColourControl(inRGB, inOnColour); 12 | 13 | var pane = new Pane(control, "Select Colour", Dock.RESIZABLE); 14 | pane.itemLayout = control.getLayout().setMinSize(300,300); 15 | super(pane); 16 | } 17 | public function setColour(inRGB:RGBHSV) 18 | { 19 | control.setColour(inRGB); 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /gm2d/icons/NSEW.hx: -------------------------------------------------------------------------------- 1 | package gm2d.icons; 2 | 3 | import gm2d.gfx.GfxBytes; 4 | import gm2d.gfx.GfxGraphics; 5 | import nme.display.Graphics; 6 | 7 | 8 | class NSEW extends Icon 9 | { 10 | static var data = "eNpjdGJgYABhOccWBgaHCQwMXP///7dvYGAQARFAAKUYHByQFMk7ejAwOGqAGBXIjAQQwwGZYQBkOBwAMgpgIjNgjAaYLjhjDsxkMANol+MZEGMJTKQHmQHWtQKZATb5BsyuFVDbwYwEmC44QwNmsgbULoi/oAweUQYACQgxMw"; 11 | var gfx:GfxBytes; 12 | 13 | public function new() 14 | { 15 | super(); 16 | gfx = GfxBytes.fromString(data); 17 | } 18 | 19 | public override function render(g:Graphics) 20 | { 21 | gfx.iterate(new GfxGraphics(g)); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /gm2d/svg/Group.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | 3 | 4 | class Group extends DisplayElement 5 | { 6 | public var children:Array; 7 | 8 | public function new() 9 | { 10 | super(); 11 | children = []; 12 | } 13 | 14 | public function hasGroup(inName:String) { return findGroup(inName)!=null; } 15 | public function findGroup(inName:String) : Group 16 | { 17 | for(child in children) 18 | if (child.name==inName) 19 | return child.asGroup(); 20 | return null; 21 | } 22 | 23 | override public function asGroup() : Group return this; 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /samples/SvgDir/build.nmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 15 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /gm2d/tween/Tween.hx: -------------------------------------------------------------------------------- 1 | package gm2d.tween; 2 | 3 | class Tween 4 | { 5 | public var name:String; 6 | public var t0:Float; 7 | public var t1:Float; 8 | public var onComplete:Void->Void; 9 | public var onUpdate:Float->Void; 10 | 11 | public function new(inName:String,inT0:Float,inT1:Float,?inOnUpdate:Float->Void,?inOnComplete:Void->Void) 12 | { 13 | name = inName; 14 | t0 = inT0; 15 | t1 = inT1; 16 | onUpdate = inOnUpdate; 17 | onComplete = inOnComplete; 18 | } 19 | 20 | public static function LINEAR(x:Float) : Float { return x; } 21 | public static function DECELERATE(x:Float) : Float { return 1-(x-1)*(x-1); } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /gm2d/ui/Phase.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import nme.events.MouseEvent; 4 | 5 | class Phase 6 | { 7 | public static inline var BEGIN = 0x1; 8 | public static inline var UPDATE = 0x2; 9 | public static inline var END = 0x4; 10 | public static inline var ALL = 0x7; 11 | 12 | public static function fromMouseEvent(inEvent:MouseEvent) : Int 13 | { 14 | if (inEvent.type == MouseEvent.MOUSE_DOWN) 15 | return BEGIN; 16 | if (inEvent.type == MouseEvent.MOUSE_MOVE) 17 | return UPDATE; 18 | if (inEvent.type == MouseEvent.MOUSE_UP) 19 | return END; 20 | return ALL; 21 | } 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /gm2d/Lib.hx: -------------------------------------------------------------------------------- 1 | package gm2d; 2 | 3 | import nme.display.DisplayObjectContainer; 4 | 5 | class Lib 6 | { 7 | public static var current(get,null) : DisplayObjectContainer; 8 | public static var debug:Bool = false; 9 | public static var isOpenGL(get,null):Bool; 10 | 11 | 12 | static function get_current() : DisplayObjectContainer 13 | { 14 | #if flash 15 | return flash.Lib.current; 16 | #else 17 | return nme.Lib.current; 18 | #end 19 | } 20 | 21 | static function get_isOpenGL() 22 | { 23 | #if flash 24 | return false; 25 | #else 26 | return nme.Lib.stage.isOpenGL; 27 | #end 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /gm2d/svg/Text.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | import Xml; 3 | 4 | 5 | class Text extends DisplayElement 6 | { 7 | /* 8 | public var font_family:String; 9 | public var font_size:Float; 10 | public var kerning:Float; 11 | public var letter_spacing:Float; 12 | */ 13 | 14 | public var text:String; 15 | public var tspans:Array; 16 | 17 | public function new() 18 | { 19 | super(); 20 | tspans = []; 21 | } 22 | 23 | public function addTSpan(el:Xml) 24 | { 25 | tspans.push( new TSpan(el) ); 26 | } 27 | 28 | override public function asText() : Text return this; 29 | override function toString():String return "Text(" + text + ")"; 30 | 31 | } 32 | 33 | -------------------------------------------------------------------------------- /samples/03-Dialog/Dialog.nmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /samples/02-Svg/Svg.nmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 15 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /gm2d/gfx/LineStyle.hx: -------------------------------------------------------------------------------- 1 | package gm2d.gfx; 2 | 3 | import nme.display.LineScaleMode; 4 | import nme.display.CapsStyle; 5 | import nme.display.JointStyle; 6 | 7 | class LineStyle 8 | { 9 | public var thickness:Float; 10 | public var color:Int; 11 | public var gradient:Gradient; 12 | public var alpha:Float; 13 | public var pixelHinting:Bool; 14 | public var scaleMode:LineScaleMode; 15 | public var capsStyle:CapsStyle; 16 | public var jointStyle:JointStyle; 17 | public var miterLimit:Float; 18 | 19 | public function new() 20 | { 21 | thickness = 1.0; 22 | color = 0x000000; 23 | gradient = null; 24 | alpha = 1.0; 25 | pixelHinting = false; 26 | scaleMode = LineScaleMode.NORMAL; 27 | capsStyle = CapsStyle.ROUND; 28 | jointStyle = JointStyle.ROUND; 29 | miterLimit = 3.0; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gm2d/ui/IDock.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import gm2d.ui.IDockable; 4 | import gm2d.ui.Pane; 5 | import nme.display.DisplayObjectContainer; 6 | 7 | 8 | interface IDock 9 | { 10 | public function getDock():IDock; 11 | public function canAddDockable(inPos:DockPosition):Bool; 12 | public function addDockable(child:IDockable,inPos:DockPosition,inSlot:Int):Void; 13 | public function getDockablePosition(child:IDockable):Int; 14 | public function removeDockable(child:IDockable):IDockable; 15 | public function raiseDockable(child:IDockable):Bool; 16 | public function minimizeDockable(child:IDockable):Bool; 17 | public function addSibling(inReference:IDockable,inIncoming:IDockable,inPos:DockPosition):Void; 18 | public function getSlot():Int; 19 | public function setDirty(inLayout:Bool, inChrome:Bool):Void; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /gm2d/icons/Icon.hx: -------------------------------------------------------------------------------- 1 | package gm2d.icons; 2 | 3 | import nme.display.Graphics; 4 | import nme.display.BitmapData; 5 | import nme.geom.Matrix; 6 | 7 | class Icon 8 | { 9 | public var width(get,null) : Int; 10 | public var height(get,null) : Int; 11 | 12 | function get_width() : Int { return 48; } 13 | function get_height() : Int { return 48; } 14 | 15 | function new() { } 16 | 17 | public function render(g:Graphics) { } 18 | 19 | public function toBitmap(scale:Float = 1.0) : BitmapData 20 | { 21 | var bmp = new BitmapData( Std.int(width*scale+0.99), Std.int(height*scale+0.99), 22 | true, gm2d.RGB.CLEAR); 23 | 24 | var shape = new nme.display.Shape(); 25 | render(shape.graphics); 26 | var m = new Matrix(); 27 | m.scale(scale,scale); 28 | bmp.draw(shape,m); 29 | 30 | return bmp; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gm2d/ui/StaticText.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import gm2d.ui.Layout; 4 | import nme.text.TextField; 5 | import nme.display.DisplayObjectContainer; 6 | import gm2d.skin.Skin; 7 | import gm2d.skin.Renderer; 8 | 9 | class StaticText 10 | { 11 | public static function create(inText:String,?inParent:DisplayObjectContainer) 12 | { 13 | var label = new TextField(); 14 | label.text = inText; 15 | var renderer = Skin.renderer(["StaticText","Text"]); 16 | renderer.renderLabel(label); 17 | label.autoSize = nme.text.TextFieldAutoSize.LEFT; 18 | if (inParent!=null) 19 | inParent.addChild(label); 20 | return label; 21 | } 22 | public static function createLayout(inText:String,?inParent:DisplayObjectContainer) 23 | { 24 | return new TextLayout(create(inText,inParent)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /samples/06-App/SampleApp.nmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /samples/04-Particles/Particles.nmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Changes.md: -------------------------------------------------------------------------------- 1 | 2 | * Haxe 4 property fixes 3 | * Propagate activate messages to parents 4 | 5 | 4.0.21 6 | ------------- 7 | * Move some skin classes around, including renaming Style -> Shape 8 | * Widget states are now sub-attributes rather than their own thing. 9 | * Bunch of other stuff 10 | * Added wwx2015 sample 11 | 12 | 3.4 13 | ------------- 14 | * Added scaling and end condition to Tilemap example 15 | * Improved Svg parsing 16 | * More keyboard navigation 17 | * Added ShadowRect fill type 18 | * Added TileControl 19 | * Allow labels inside numeric controls 20 | * Animate the scrollTo position 21 | 22 | ------------- 23 | * Better integration with waxe 24 | * Added Undo class 25 | * Reworked the ui system completely 26 | 27 | ------------- 28 | * Removed the typedefs - let nme do this now 29 | 30 | Version 3.1.0 31 | ------------- 32 | Imported from google code 33 | 34 | -------------------------------------------------------------------------------- /samples/01-Tilemap/Tilemap.nmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /samples/05-BitmapFont/BitmapFont.nmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /samples/10-Wwx2014/game/Puck.hx: -------------------------------------------------------------------------------- 1 | package game; 2 | 3 | import nme.display.Shape; 4 | import nme.display.DisplayObjectContainer; 5 | 6 | class Puck 7 | { 8 | var display:Shape; 9 | public var x:Float; 10 | public var y:Float; 11 | public var vx:Float; 12 | public var vy:Float; 13 | 14 | public function new(parent:DisplayObjectContainer) 15 | { 16 | display = new Shape(); 17 | var gfx = display.graphics; 18 | gfx.beginFill(0x000000); 19 | gfx.drawCircle( 0, 0, Game.PUCK_RAD ); 20 | parent.addChild(display); 21 | 22 | } 23 | 24 | public function init(inX,inY,inVx,inVy) 25 | { 26 | x = inX; 27 | y = inY; 28 | vx = inVx; 29 | vy = inVy; 30 | updateDisplay(); 31 | } 32 | 33 | public function updateDisplay() 34 | { 35 | display.x = x; 36 | display.y = y; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /samples/11-wwx2015/build.nmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /samples/10-Wwx2014/build.nmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 15 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /gm2d/gfx/Gradient.hx: -------------------------------------------------------------------------------- 1 | package gm2d.gfx; 2 | 3 | import nme.geom.Matrix; 4 | import nme.display.GradientType; 5 | import nme.display.SpreadMethod; 6 | import nme.display.InterpolationMethod; 7 | import nme.display.CapsStyle; 8 | import nme.display.JointStyle; 9 | import nme.display.LineScaleMode; 10 | import gm2d.CInt; 11 | 12 | class Gradient 13 | { 14 | public function new() 15 | { 16 | type = GradientType.LINEAR; 17 | colors = []; 18 | alphas = []; 19 | ratios = []; 20 | matrix = new Matrix(); 21 | spread = SpreadMethod.PAD; 22 | interp = InterpolationMethod.RGB; 23 | focus = 0.0; 24 | } 25 | 26 | public var type:GradientType; 27 | public var colors:Array; 28 | public var alphas:Array; 29 | public var ratios:Array; 30 | public var matrix: Matrix; 31 | public var spread: SpreadMethod; 32 | public var interp:InterpolationMethod; 33 | public var focus:Float; 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 0-Clause License 2 | 3 | Copyright (c) 2024, Hugh Sanderson and contributors 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any purpose 6 | with or without fee is hereby granted. 7 | 8 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 9 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 10 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 11 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 12 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 13 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 14 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 15 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 16 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 17 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 18 | -------------------------------------------------------------------------------- /samples/02-Svg/Svg.hx: -------------------------------------------------------------------------------- 1 | import nme.display.Sprite; 2 | import gm2d.Game; 3 | import gm2d.Screen; 4 | import gm2d.reso.Resources; 5 | import gm2d.svg.SvgRenderer; 6 | 7 | import nme.ui.Keyboard; 8 | 9 | 10 | class Svg extends Screen 11 | { 12 | var mResources:Hash; 13 | 14 | function new() 15 | { 16 | super(); 17 | 18 | var svg = new SvgRenderer(Resources.loadSvg("test.svg")); 19 | //var shape = svg.createShape(); 20 | var shape = svg.createDisplayTree(); 21 | shape.scaleX = shape.scaleY = 0.25; 22 | //shape.cacheAsBitmap = true; 23 | addChild(shape); 24 | makeCurrent(); 25 | } 26 | 27 | override public function getScaleMode() { return gm2d.ScreenScaleMode.TOPLEFT_SCALED; } 28 | 29 | override public function updateDelta(inDT:Float) 30 | { 31 | } 32 | 33 | 34 | static public function main() 35 | { 36 | Game.showFPS = true; 37 | Game.fpsColor = 0xffffff; 38 | new Svg(); 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /samples/10-Wwx2014/CodeBox.hx: -------------------------------------------------------------------------------- 1 | import nme.text.TextField; 2 | import nme.text.TextFormat; 3 | import nme.text.TextFieldAutoSize; 4 | import nme.ui.Keyboard; 5 | import gm2d.ui.Layout; 6 | 7 | 8 | class CodeBox extends TextField 9 | { 10 | public var layout:Layout; 11 | 12 | public function new(inText:String) 13 | { 14 | super(); 15 | var fmt = new TextFormat(); 16 | fmt.font = "courier"; 17 | fmt.size = Std.int(12*Talk.instance.guiScale); 18 | //fmt.color = 0xff00ff; 19 | fmt.color = 0xffffff; 20 | fmt.bold = true; 21 | defaultTextFormat = fmt; 22 | border = true; 23 | borderColor = 0x0000ff; 24 | background = true; 25 | backgroundColor = 0x000000; 26 | selectable = false; 27 | multiline = true; 28 | 29 | setText(inText); 30 | var pad = 10*Talk.instance.guiScale; 31 | layout = new TextLayout(this).setPadding(pad,pad).stretch(); 32 | } 33 | 34 | public function setText(inText:String) 35 | { 36 | htmlText = inText; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /samples/11-wwx2015/CodeBox.hx: -------------------------------------------------------------------------------- 1 | import nme.text.TextField; 2 | import nme.text.TextFormat; 3 | import nme.text.TextFieldAutoSize; 4 | import nme.ui.Keyboard; 5 | import gm2d.ui.Layout; 6 | 7 | 8 | class CodeBox extends TextField 9 | { 10 | public var layout:Layout; 11 | 12 | public function new(inText:String) 13 | { 14 | super(); 15 | var fmt = new TextFormat(); 16 | fmt.font = "courier"; 17 | fmt.size = Std.int(12*Talk.instance.guiScale); 18 | //fmt.color = 0xff00ff; 19 | fmt.color = 0xffffff; 20 | fmt.bold = true; 21 | defaultTextFormat = fmt; 22 | border = true; 23 | borderColor = 0x0000ff; 24 | background = true; 25 | backgroundColor = 0x000000; 26 | selectable = false; 27 | multiline = true; 28 | 29 | setText(inText); 30 | var pad = 10*Talk.instance.guiScale; 31 | layout = new TextLayout(this).setPadding(pad,pad).stretch(); 32 | } 33 | 34 | public function setText(inText:String) 35 | { 36 | htmlText = inText; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /samples/08-Swf/SwfTest.nmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /gm2d/blit/Tile.hx: -------------------------------------------------------------------------------- 1 | package gm2d.blit; 2 | import nme.geom.Rectangle; 3 | 4 | class Tile 5 | { 6 | public var rect(default,null):Rectangle; 7 | public var id(default,null):Int; 8 | public var sheet:Tilesheet; 9 | public var hotX:Float; 10 | public var hotY:Float; 11 | 12 | public function new(inSheet:Tilesheet, inRect:Rectangle) 13 | { 14 | sheet = inSheet; 15 | rect = inRect==null ? new Rectangle(0,0,inSheet.width, inSheet.height) : inRect.clone(); 16 | id = sheet.gm2dAllocTile(this); 17 | hotX = hotY = 0; 18 | } 19 | 20 | public function alignLeft() { hotX = 0; return this; } 21 | public function alignCenterX() { hotX = rect.width/2; return this; } 22 | public function alignRight() { hotX = rect.width; return this; } 23 | 24 | public function alignTop() { hotY = 0; return this; } 25 | public function alignCenterY() { hotY = rect.height/2; return this; } 26 | public function alignBottom() { hotY = rect.height; return this; } 27 | 28 | public function alignCenter() { alignCenterX(); alignCenterY(); return this; } 29 | } 30 | -------------------------------------------------------------------------------- /gm2d/ui/CheckButtons.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import nme.display.BitmapData; 4 | import nme.display.Bitmap; 5 | import nme.display.Shape; 6 | import nme.display.Sprite; 7 | import gm2d.ui.Button; 8 | import gm2d.skin.Skin; 9 | import gm2d.ui.WidgetState; 10 | 11 | 12 | class CheckButtons extends Button 13 | { 14 | public function new(inValue:Bool, ?inCheck:Bool->Void,?inLineage:Array,?inAttribs:Dynamic) 15 | { 16 | super(null,inCheck==null ? null : () -> inCheck(down),Widget.addLines(inLineage,["CheckButton"]),inAttribs); 17 | setChecked(inValue); 18 | //build(); 19 | } 20 | 21 | public function setChecked(inCheck:Bool) 22 | down = inCheck; 23 | 24 | 25 | 26 | override public function set(inValue:Dynamic) : Void 27 | { 28 | if ( (inValue!=null && inValue!="") ) 29 | setChecked(inValue); 30 | } 31 | 32 | override public function get(inValue:Dynamic) : Void 33 | { 34 | if (Reflect.hasField(inValue,name)) 35 | Reflect.setField(inValue, name, down ); 36 | } 37 | 38 | 39 | } 40 | 41 | -------------------------------------------------------------------------------- /gm2d/svg/DisplayElement.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | 3 | import nme.geom.Matrix; 4 | import nme.display.GradientType; 5 | import nme.display.SpreadMethod; 6 | import nme.display.InterpolationMethod; 7 | import nme.display.CapsStyle; 8 | import nme.display.JointStyle; 9 | import nme.display.LineScaleMode; 10 | 11 | typedef Style = Map; 12 | 13 | 14 | class DisplayElement 15 | { 16 | 17 | 18 | public var name:String; 19 | public var id:String; 20 | public var x:Float; 21 | public var y:Float; 22 | public var matrix:Matrix; 23 | 24 | public var style:Style; 25 | 26 | public function new() 27 | { 28 | name = ""; 29 | id = ""; 30 | x = 0; 31 | y = 0; 32 | } 33 | 34 | 35 | function toString():String return "DisplayElement"; 36 | 37 | 38 | public function asGroup() : Group return null; 39 | public function asPath() : Path return null; 40 | public function asLink() : Link return null; 41 | public function asText() : Text return null; 42 | public function asMarker() : Marker return null; 43 | 44 | } 45 | 46 | -------------------------------------------------------------------------------- /gm2d/gfx/GfxExtent.hx: -------------------------------------------------------------------------------- 1 | package gm2d.gfx; 2 | 3 | import nme.geom.Matrix; 4 | import nme.geom.Rectangle; 5 | 6 | class GfxExtent extends Gfx 7 | { 8 | public var extent : Rectangle; 9 | 10 | public function new() 11 | { 12 | super(); 13 | extent = null; 14 | } 15 | 16 | function addExtent(inX:Float, inY:Float) 17 | { 18 | if (extent==null) 19 | { 20 | extent = new Rectangle(inX,inY,0,0); 21 | return; 22 | } 23 | if (inXextent.right) extent.right = inX; 25 | if (inYextent.bottom) extent.bottom = inY; 27 | } 28 | 29 | 30 | override public function geometryOnly() { return true; } 31 | override public function moveTo(inX:Float, inY:Float) 32 | { 33 | addExtent(inX,inY); 34 | } 35 | override public function lineTo(inX:Float, inY:Float) 36 | { 37 | addExtent(inX,inY); 38 | } 39 | override public function curveTo(inCX:Float, inCY:Float,inX:Float,inY:Float) 40 | { 41 | addExtent(inCX,inCY); 42 | addExtent(inX,inY); 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /gm2d/ui/FrameWidget.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import nme.text.TextFormat; 4 | import gm2d.ui.Layout; 5 | import nme.filters.BitmapFilter; 6 | import nme.filters.DropShadowFilter; 7 | import gm2d.ui.HitBoxes; 8 | import nme.geom.Rectangle; 9 | import gm2d.skin.Skin; 10 | import gm2d.skin.Renderer; 11 | 12 | 13 | class FrameWidget extends Widget 14 | { 15 | var child:Widget; 16 | 17 | public function new(inChild:Widget, ?inLineage:Array, ?inAttribs:{}) 18 | { 19 | child = inChild; 20 | super(Widget.addLines(inLineage,["Frame"]), inAttribs); 21 | 22 | var titleLineage:Array = attrib("titleLineage"); 23 | if (titleLineage!=null) 24 | { 25 | var vlayout = new VerticalLayout(); 26 | var title = new TextLabel(child.name, titleLineage); 27 | addChild(title); 28 | vlayout.add( title.getLayout() ); 29 | addChild(child); 30 | vlayout.add( child.getLayout() ); 31 | setItemLayout(vlayout); 32 | } 33 | else 34 | { 35 | addWidget(child); 36 | } 37 | build(); 38 | } 39 | } 40 | 41 | 42 | -------------------------------------------------------------------------------- /gm2d/ui/GroupBox.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import gm2d.ui.Layout; 4 | import gm2d.skin.Skin; 5 | import nme.display.BitmapData; 6 | import nme.text.TextField; 7 | 8 | 9 | class GroupBox extends Widget 10 | { 11 | var icon:BitmapData; 12 | var title:TextLabel; 13 | 14 | public function new(inTitle:String, inIcon:BitmapData, inLayout:Layout, 15 | ?inLineage:Array, ?inAttribs:Dynamic) 16 | { 17 | super(Widget.addLine(inLineage,"GroupBox"), inAttribs); 18 | icon = inIcon; 19 | name = inTitle; 20 | 21 | wantFocus = false; 22 | 23 | cacheAsBitmap = true; 24 | 25 | if (inTitle!="") 26 | { 27 | title = new TextLabel(inTitle,["GroupBoxTitle"]); 28 | title.x = 2; 29 | title.y = 0; 30 | addChild(title); 31 | } 32 | 33 | setItemLayout(inLayout); 34 | build(); 35 | } 36 | override public function onLayout(x,y,w,h) 37 | { 38 | super.onLayout(x,y,w,h); 39 | if (title!=null && mRenderer.margin!=null) 40 | { 41 | title.y = -mRenderer.margin.y; 42 | title.x = mRenderer.margin.x; 43 | } 44 | } 45 | 46 | } 47 | 48 | -------------------------------------------------------------------------------- /samples/11-wwx2015/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /samples/03-Dialog/Dialog.hx: -------------------------------------------------------------------------------- 1 | import gm2d.reso.Resources; 2 | import nme.display.Sprite; 3 | import gm2d.blit.Tilesheet; 4 | import gm2d.blit.Tile; 5 | import gm2d.blit.Layer; 6 | import gm2d.blit.Grid; 7 | import gm2d.Game; 8 | import gm2d.Screen; 9 | import gm2d.ui.Button; 10 | import nme.ui.Keyboard; 11 | import nme.events.MouseEvent; 12 | import gm2d.ui.BitmapFont; 13 | import gm2d.ui.BitmapText; 14 | import gm2d.ui.Slider; 15 | import gm2d.skin.Skin; 16 | import gm2d.svg.Svg; 17 | 18 | 19 | class Dialog extends Screen 20 | { 21 | function new() 22 | { 23 | super(); 24 | 25 | Game.setCurrentScreen(this); 26 | 27 | skin.fromSvg(Resources.loadSvg("skin.svg")); 28 | 29 | var panel = new gm2d.ui.Panel("Settings"); 30 | panel.addLabelUI("Music Volume", new Slider(0,100,50,OnMusic) ); 31 | panel.addTextButton("Ok", function() { Game.closeDialog(); } ); 32 | panel.addTextButton("Cancel"); 33 | panel.showDialog(); 34 | 35 | stage.addEventListener( MouseEvent.MOUSE_UP, function (e:MouseEvent) { 36 | if (e.target == stage) 37 | panel.showDialog(); 38 | } ); 39 | } 40 | 41 | function OnMusic(inVal) trace(inVal); 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /gm2d/gfx/Gfx.hx: -------------------------------------------------------------------------------- 1 | package gm2d.gfx; 2 | 3 | import nme.display.GradientType; 4 | import nme.display.SpreadMethod; 5 | import nme.display.InterpolationMethod; 6 | import nme.display.CapsStyle; 7 | import nme.display.JointStyle; 8 | import nme.display.LineScaleMode; 9 | import gm2d.svg.Text; 10 | import gm2d.svg.TextStyle; 11 | 12 | import nme.geom.Matrix; 13 | 14 | class Gfx 15 | { 16 | public function new() { } 17 | public function geometryOnly() { return false; } 18 | public function size(inWidth:Float,inHeight:Float) { } 19 | public function beginGradientFill(grad:Gradient) { } 20 | 21 | public function beginFill(color:Int, alpha:Float) { } 22 | public function endFill() { } 23 | 24 | public function lineStyle(style:LineStyle) { } 25 | public function endLineStyle() { } 26 | 27 | public function moveTo(inX:Float, inY:Float) { } 28 | public function lineTo(inX:Float, inY:Float) { } 29 | public function curveTo(inCX:Float, inCY:Float,inX:Float,inY:Float) { } 30 | public function cubicTo(inCx0:Float, inCy0:Float,inCx1:Float, inCy1:Float, inX:Float,inY:Float) { 31 | return false; 32 | } 33 | 34 | public function renderText(text:Text,matrix:Matrix,style:TextStyle) { } 35 | 36 | public function eof() {} 37 | } 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /gm2d/ui/DockZones.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | import nme.geom.Rectangle; 3 | import nme.display.Sprite; 4 | 5 | class DockZone 6 | { 7 | public var rect(default,null):Rectangle; 8 | public var onDock(default,null):IDockable->Void; 9 | public function new(inRect:Rectangle, inOnDock:IDockable->Void) 10 | { 11 | rect = inRect; 12 | onDock = inOnDock; 13 | } 14 | } 15 | 16 | class DockZones 17 | { 18 | public var x(default,null):Float; 19 | public var y(default,null):Float; 20 | public var container(default,null):Sprite; 21 | 22 | var zones:Array; 23 | 24 | public function new(inX:Float, inY:Float, inContainer:Sprite) 25 | { 26 | x = inX; 27 | y = inY; 28 | container = inContainer; 29 | zones = []; 30 | } 31 | 32 | public function addRect(inRect:Rectangle, inOnDock:IDockable->Void) 33 | { 34 | if (inRect!=null) 35 | zones.push( new DockZone(inRect, inOnDock) ); 36 | } 37 | 38 | public function test(inX:Float, inY:Float,inDockable:IDockable) : Bool 39 | { 40 | for(zone in zones) 41 | { 42 | if (zone.rect.contains(inX,inY)) 43 | { 44 | zone.onDock(inDockable); 45 | return true; 46 | } 47 | } 48 | return false; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /gm2d/blit/NMEViewport.hx: -------------------------------------------------------------------------------- 1 | package gm2d.blit; 2 | 3 | #if !flash 4 | 5 | import nme.display.Sprite; 6 | import nme.display.Stage; 7 | import nme.events.Event; 8 | import nme.geom.Rectangle; 9 | 10 | class NMEViewport extends Viewport 11 | { 12 | public function new(inWidth:Int, inHeight:Int,inTransparent:Bool,inBackground) 13 | { 14 | super(inWidth,inHeight,inTransparent,inBackground); 15 | scrollRect = new Rectangle(0,0,inWidth,inHeight); 16 | } 17 | 18 | override function onAdded() 19 | { 20 | super.onAdded(); 21 | if (!mTransparent) 22 | opaqueBackground = #if ((neko_v1 || !haxe3) && neko) getBG().rgb; #else getBG(); #end 23 | } 24 | 25 | 26 | public override function createLayer() : Layer 27 | { 28 | var layer = NMELayer.gm2dCreate(this); 29 | addLayer(layer); 30 | addChild(layer.gm2dShape); 31 | return layer; 32 | } 33 | 34 | override function resize(inWidth:Int, inHeight:Int) 35 | { 36 | scrollRect = new Rectangle(0,0,inWidth,inHeight); 37 | super.resize(inWidth,inHeight); 38 | } 39 | 40 | override function renderViewport() 41 | { 42 | for(layer in mLayers) 43 | if (layer.visible) 44 | layer.gm2dRender(originX,originY); 45 | } 46 | 47 | } 48 | 49 | #end 50 | -------------------------------------------------------------------------------- /gm2d/skin/SliderRenderer.hx: -------------------------------------------------------------------------------- 1 | package gm2d.skin; 2 | 3 | import gm2d.ui.HitBoxes; 4 | import nme.filters.BitmapFilter; 5 | import nme.filters.BitmapFilterType; 6 | import nme.filters.DropShadowFilter; 7 | import nme.filters.GlowFilter; 8 | import nme.display.Sprite; 9 | import nme.display.BitmapData; 10 | import nme.display.Bitmap; 11 | import nme.display.Shape; 12 | import nme.display.Graphics; 13 | import nme.text.TextField; 14 | import nme.text.TextFieldAutoSize; 15 | import nme.events.MouseEvent; 16 | import nme.geom.Point; 17 | import nme.geom.Rectangle; 18 | import nme.geom.Matrix; 19 | 20 | import nme.display.SimpleButton; 21 | import gm2d.ui.IDockable; 22 | import gm2d.ui.Layout; 23 | import gm2d.ui.Slider; 24 | import gm2d.svg.SvgRenderer; 25 | import gm2d.svg.Svg; 26 | 27 | 28 | class SliderRenderer 29 | { 30 | public function new() { } 31 | 32 | public dynamic function onCreate(inSlider:Slider):Void { } 33 | public dynamic function onRender(inSlider:Slider, inRect:Rectangle):Void { } 34 | public dynamic function onPosition(inSlider:Slider):Void 35 | { 36 | if (inSlider.mThumb!=null) 37 | inSlider.mThumb.x = inSlider.mX0 + (inSlider.mX1-inSlider.mX0) * 38 | (inSlider.mValue - inSlider.mMin) / 39 | (inSlider.mMax-inSlider.mMin); 40 | } 41 | } 42 | 43 | 44 | -------------------------------------------------------------------------------- /tools/version/Write.hx: -------------------------------------------------------------------------------- 1 | import sys.io.File; 2 | 3 | class Write 4 | { 5 | public static function main() 6 | { 7 | var args = Sys.args(); 8 | var buildNumber = Std.parseInt(args[0]); 9 | if (buildNumber<1 || buildNumber==null) 10 | throw "Usage: Write buildNumber"; 11 | 12 | 13 | var jsonFile = "haxelib.json"; 14 | var lines = File.getContent(jsonFile).split("\n"); 15 | var idx = 0; 16 | var versionMatch = ~/(.*"version"\s*:\s*")(.*)(".*)/; 17 | var found = false; 18 | var newVersion = ""; 19 | while(idxVoid):Void 55 | { 56 | if (swf == null) 57 | { 58 | swf = new SWF(Assets.getBytes(id)); 59 | handler(this); 60 | } 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /gm2d/ui/AdoHandler.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import gm2d.Ado; 4 | 5 | 6 | class AdoHandler 7 | { 8 | public var ado:Ado; 9 | public var text:String; 10 | public var getValue:Void->T; 11 | public var setValue:Dynamic->T->Void; 12 | public var getContext:Void->Dynamic; 13 | public var guiLockout:Int; 14 | 15 | public var updateGui:T->Void; 16 | 17 | public function new(inAdo:Ado, inText:String, 18 | inGetValue:Void->T, 19 | inSetValue:Dynamic->T->Void, 20 | ?inGetContext:Void->Dynamic) 21 | { 22 | guiLockout = 0; 23 | ado = inAdo; 24 | text= inText; 25 | getValue = inGetValue; 26 | setValue = inSetValue; 27 | getContext = inGetContext; 28 | 29 | } 30 | 31 | function updateValue(context:Dynamic, value:T) 32 | { 33 | setValue(context,value); 34 | 35 | if (updateGui!=null && guiLockout==0) 36 | { 37 | var ctx = getContext==null ? null : getContext(); 38 | if (ctx==context) 39 | updateGui(value); 40 | } 41 | } 42 | 43 | public function finishEdit() 44 | { 45 | ado.finishEdit(); 46 | } 47 | 48 | public function onValue(value:T, phase:Int) : Void 49 | { 50 | var oldValue = getValue(); 51 | if (oldValue!=value) 52 | { 53 | guiLockout++; 54 | var context = getContext==null ? null : getContext(); 55 | ado.editPhase(text, 56 | function() updateValue(context,value), 57 | function() updateValue(context,oldValue), 58 | phase ); 59 | guiLockout--; 60 | } 61 | } 62 | 63 | 64 | 65 | 66 | 67 | } 68 | -------------------------------------------------------------------------------- /samples/05-BitmapFont/BitmapFont.hx: -------------------------------------------------------------------------------- 1 | import nme.display.Sprite; 2 | import gm2d.blit.Tilesheet; 3 | import gm2d.blit.Tile; 4 | import gm2d.blit.Layer; 5 | import gm2d.blit.Grid; 6 | import gm2d.Game; 7 | import gm2d.Screen; 8 | import gm2d.ui.Button; 9 | import nme.ui.Keyboard; 10 | import nme.events.MouseEvent; 11 | import gm2d.ui.BitmapFont; 12 | import gm2d.ui.BitmapText; 13 | import nme.display.Bitmap; 14 | import nme.display.BitmapData; 15 | import nme.geom.Rectangle; 16 | import nme.text.TextFieldType; 17 | 18 | 19 | class BitmapFont extends Screen 20 | { 21 | function new() 22 | { 23 | super(); 24 | 25 | makeCurrent(); 26 | 27 | var bmp:BitmapData = nme.Assets.getBitmapData("Edmunds.png"); 28 | var font = gm2d.ui.BitmapFont.createFromActiveRects(bmp,0x20); 29 | font.packing = -3; 30 | 31 | var text = new BitmapText(font,"Hello from the bitmap font"); 32 | text.layout(200,font.height); 33 | text.x = 100; 34 | text.y = 100; 35 | text.type = TextFieldType.INPUT; 36 | addChild(text); 37 | 38 | var font = gm2d.ui.BitmapFont.create("edmunds", 48, 0xffffff); 39 | 40 | var text = new BitmapText(font,"Hello2"); 41 | text.layout(400,font.height); 42 | text.x = 10; 43 | text.y = 200; 44 | text.type = TextFieldType.INPUT; 45 | addChild(text); 46 | } 47 | 48 | override public function updateDelta(inDT:Float) 49 | { 50 | } 51 | 52 | 53 | static public function main() 54 | { 55 | //Game.showFPS = true; 56 | Game.fpsColor = 0x000000; 57 | Game.backgroundColor = 0x400000; 58 | new BitmapFont(); 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /gm2d/ui/DialogScreen.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import nme.events.MouseEvent; 4 | import nme.display.DisplayObject; 5 | import nme.display.Sprite; 6 | import nme.text.TextField; 7 | import nme.text.TextFormat; 8 | import gm2d.ui.Layout; 9 | import nme.filters.BitmapFilter; 10 | import nme.filters.DropShadowFilter; 11 | import gm2d.ui.HitBoxes; 12 | import nme.geom.Rectangle; 13 | import gm2d.skin.Skin; 14 | import gm2d.skin.Renderer; 15 | import gm2d.Game; 16 | import gm2d.Screen; 17 | 18 | 19 | class DialogScreen extends Screen implements IDialog 20 | { 21 | var mPane:Pane; 22 | public var shouldConsumeEvent : MouseEvent -> Bool; 23 | 24 | public function new(inPane:Pane, ?inLineage:Array, ?inAttribs:{} ) 25 | { 26 | super(Widget.addLines(inLineage,["DialogScreen","Dialog"]), inAttribs); 27 | 28 | mPane = inPane; 29 | 30 | var obj = mPane.displayObject; 31 | if (obj!=null) 32 | addChild(obj); 33 | //mPane.setDock(this); 34 | 35 | setItemLayout(inPane.itemLayout); 36 | 37 | /* 38 | var vlayout = new VerticalLayout([0,1]); 39 | inPane.setDock(null,this); 40 | vlayout.add(inPane.itemLayout.stretch()); 41 | setItemLayout(vlayout.stretch()); 42 | */ 43 | } 44 | 45 | override public function relayout() 46 | { 47 | trace("relayout!"); 48 | super.relayout(); 49 | } 50 | 51 | override public function closeIfDialog() 52 | { 53 | Game.popScreen(); 54 | } 55 | 56 | public function closeFrame():Void Game.popScreen(); 57 | 58 | public function asDialog():Dialog return null; 59 | public function asScreen():DialogScreen return this; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /gm2d/math/TimeAverage.hx: -------------------------------------------------------------------------------- 1 | package gm2d.math; 2 | 3 | class TimedValue 4 | { 5 | public var time:Float; 6 | public var value:Float; 7 | public var weight:Float; 8 | 9 | public function new(inTime:Float,inVal:Float,inWeight:Float) 10 | { 11 | time = inTime; 12 | value = inVal; 13 | weight = inWeight; 14 | } 15 | } 16 | 17 | class TimeAverage 18 | { 19 | public var window:Float; 20 | public var samples:Array; 21 | public var mean(get,null):Float; 22 | public var isValid(get,null):Bool; 23 | 24 | public function new(inWindow:Float) 25 | { 26 | samples = []; 27 | window = inWindow; 28 | } 29 | public function add(inValue:Float,inWeight:Float=1.0) 30 | { 31 | var now = haxe.Timer.stamp(); 32 | samples.push(new TimedValue(now,inValue,inWeight)); 33 | removeOld(now-window); 34 | } 35 | public function clear() 36 | { 37 | samples = []; 38 | } 39 | public function get_isValid() : Bool { return samples.length>0; } 40 | function removeOld(inTime:Float) 41 | { 42 | var keepFirst = 0; 43 | while(keepFirstinTime) 46 | break; 47 | keepFirst++; 48 | } 49 | if (keepFirst>0) 50 | samples.splice(0,keepFirst); 51 | } 52 | public function get_mean() : Float 53 | { 54 | if (samples.length<1) 55 | return 0.0; 56 | var now = haxe.Timer.stamp(); 57 | var total = 0.0; 58 | var total_w = 0.0; 59 | for(s in samples) 60 | { 61 | total += s.value * s.weight; 62 | total_w += s.weight; 63 | } 64 | return total/total_w; 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /gm2d/svg/BitmapDataManager.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | 3 | import gm2d.reso.Resources; 4 | import gm2d.svg.SvgRenderer; 5 | import nme.geom.Matrix; 6 | 7 | import nme.display.Shape; 8 | import nme.display.Bitmap; 9 | import nme.display.BitmapData; 10 | 11 | typedef BitmapDataHash = haxe.ds.StringMap; 12 | 13 | class BitmapDataManager 14 | { 15 | static var bitmaps = new BitmapDataHash(); 16 | static var mScale = 0.0; 17 | 18 | public static function create(inSVG:String, inGroup:String, inScale:Float, inCache=false) 19 | { 20 | var key = inSVG + " : " + inGroup + " : " +inScale; 21 | if (bitmaps.exists(key)) 22 | return bitmaps.get(key); 23 | 24 | var svg:SvgRenderer = new SvgRenderer( Resources.loadSvg(inSVG) ); 25 | var shape = new Shape(); 26 | if (inGroup=="") 27 | svg.renderObject(shape,shape.graphics); 28 | else 29 | svg.renderObject(shape,shape.graphics,null, function(_,groups) { return groups[0]==inGroup; }); 30 | 31 | var matrix = new Matrix(); 32 | matrix.scale(inScale,inScale); 33 | 34 | var w = Std.int(svg.width*inScale + 0.99); 35 | var h = Std.int(svg.height*inScale + 0.99); 36 | var bmp = new BitmapData(w,h,true,RGB.CLEAR); 37 | var q = gm2d.Lib.current.stage.quality; 38 | gm2d.Lib.current.stage.quality = nme.display.StageQuality.BEST; 39 | bmp.draw(shape,matrix); 40 | gm2d.Lib.current.stage.quality = q; 41 | 42 | if (inCache) 43 | bitmaps.set(key,bmp); 44 | return bmp; 45 | } 46 | 47 | static public function setCacheScale(inScale:Float) 48 | { 49 | if (inScale!=mScale) 50 | { 51 | bitmaps = new BitmapDataHash(); 52 | mScale = inScale; 53 | } 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /gm2d/svg/Grad.hx: -------------------------------------------------------------------------------- 1 | package gm2d.svg; 2 | 3 | import nme.geom.Matrix; 4 | import nme.geom.Rectangle; 5 | 6 | import nme.display.GradientType; 7 | import nme.display.SpreadMethod; 8 | import nme.display.InterpolationMethod; 9 | import nme.display.CapsStyle; 10 | import nme.display.JointStyle; 11 | import nme.display.LineScaleMode; 12 | 13 | class Grad extends gm2d.gfx.Gradient 14 | { 15 | public var gradMatrix:Matrix; 16 | public var radius:Float; 17 | public var x1:Float; 18 | public var y1:Float; 19 | public var x2:Float; 20 | public var y2:Float; 21 | 22 | public function new(inType:GradientType) 23 | { 24 | super(); 25 | type = inType; 26 | radius = 0.0; 27 | gradMatrix = new Matrix(); 28 | x1 = 0.0; 29 | y1 = 0.0; 30 | x2 = 0.0; 31 | y2 = 0.0; 32 | } 33 | 34 | public function updateMatrix(inMatrix:Matrix) 35 | { 36 | var dx = x2 - x1; 37 | var dy = y2 - y1; 38 | var theta = Math.atan2(dy,dx); 39 | var len = Math.sqrt(dx*dx+dy*dy); 40 | 41 | var mtx = new Matrix(); 42 | 43 | if (type==GradientType.LINEAR) 44 | { 45 | mtx.createGradientBox(1.0,1.0); 46 | mtx.scale(len,len); 47 | } 48 | else 49 | { 50 | if (radius!=0.0) 51 | focus = len/radius; 52 | 53 | mtx.createGradientBox(1.0,1.0); 54 | mtx.translate(-0.5,-0.5); 55 | mtx.scale(radius*2,radius*2); 56 | } 57 | 58 | mtx.rotate(theta); 59 | mtx.translate(x1,y1); 60 | mtx.concat(gradMatrix); 61 | if (inMatrix!=null) 62 | mtx.concat(inMatrix); 63 | matrix = mtx; 64 | } 65 | 66 | 67 | } 68 | 69 | #if haxe3 70 | typedef GradHash = haxe.ds.StringMap; 71 | #else 72 | typedef GradHash = Hash; 73 | #end 74 | 75 | -------------------------------------------------------------------------------- /gm2d/ui/WaxeDialog.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | import gm2d.skin.Skin; 3 | import wx.NMEStage; 4 | import nme.display.Stage; 5 | 6 | class WaxeDialog implements IDialog 7 | { 8 | var frame:wx.Dialog; 9 | var nmeStage:NMEStage; 10 | var stage:Stage; 11 | 12 | public function new(inPane:Pane, ?inAttribs:Dynamic, ?inLineage:Array) 13 | { 14 | var w = Std.int(inPane.sizeX); 15 | var h = Std.int(inPane.sizeY); 16 | var size = { width:w, height:h }; 17 | frame = wx.Dialog.create(wx.NMEStage.mainWindow,null, inPane.title, null, size); 18 | nmeStage = NMEStage.create(frame); 19 | stage = nmeStage.stage; 20 | stage.color = Skin.dialogColor; 21 | stage.addChild(inPane.displayObject); 22 | inPane.getLayout().setRect(0,0,w,h); 23 | } 24 | public function show(autoClose:Bool) 25 | { 26 | frame.showFrame(wx.TopLevelWindow.MODAL); 27 | } 28 | 29 | public function closeFrame():Void 30 | { 31 | trace("closeFrame"); 32 | frame.destroy(); 33 | trace("dispose"); 34 | //stage.dispose(); 35 | } 36 | public function asDialog():Dialog return null; 37 | 38 | 39 | /* 40 | public function getDock():IDock { return this; } 41 | public function canAddDockable(inPos:DockPosition):Bool; 42 | public function addDockable(child:IDockable,inPos:DockPosition,inSlot:Int):Void; 43 | public function getDockablePosition(child:IDockable):Int; 44 | public function removeDockable(child:IDockable):IDockable; 45 | public function raiseDockable(child:IDockable):Bool; 46 | public function minimizeDockable(child:IDockable):Bool; 47 | public function addSibling(inReference:IDockable,inIncoming:IDockable,inPos:DockPosition):Void; 48 | public function getSlot():Int; 49 | public function setDirty(inLayout:Bool, inChrome:Bool):Void; 50 | */ 51 | } 52 | 53 | -------------------------------------------------------------------------------- /gm2d/ui/SecondaryWindowDialog.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import gm2d.skin.Skin; 4 | import gm2d.skin.FillStyle; 5 | import nme.display.*; 6 | import nme.events.*; 7 | 8 | class SecondaryWindowDialog implements IDialog 9 | { 10 | var window:nme.app.Window; 11 | 12 | public function new(pane:Pane, ?inAttribs:{}, ?inLineage:Array ) 13 | { 14 | var fps = 0.0; 15 | var layout = pane.getLayout(); 16 | var size = layout.getBestSize(); 17 | //var skin = pane.skin; 18 | var skin = Skin.getSkin(); 19 | 20 | var bgCol = 0xffffff; 21 | var combined = skin.combineAttribs(["Dialog"], 0, inAttribs); 22 | var bg:FillStyle = combined.get("fill"); 23 | if (bg!=null) 24 | switch(bg) 25 | { 26 | case FillSolid(c,a) : bgCol = c; 27 | case FillLight: bgCol = skin.guiLight; 28 | case FillMedium: bgCol = skin.guiMedium; 29 | case FillButton: bgCol = skin.guiButton; 30 | case FillDark: bgCol = skin.guiDark; 31 | case FillHighlight: bgCol = skin.guiHighlight; 32 | default: 33 | } 34 | 35 | window = nme.Lib.createSecondaryWindow( 36 | Std.int(size.x), Std.int(size.y), pane.getTitle(), 37 | nme.app.Application.HARDWARE | nme.app.Application.RESIZABLE | 38 | nme.app.Application.ALWAYS_ON_TOP, 39 | bgCol, fps, pane.getIcon() ); 40 | var stage = window.stage; 41 | stage.scaleMode = StageScaleMode.NO_SCALE; 42 | stage.addEventListener( Event.RESIZE, (_) -> 43 | layout.setRect(0,0, stage.stageWidth, stage.stageHeight) 44 | ); 45 | stage.onCloseRequest = Game.closeDialog; 46 | 47 | pane.setDock(null,stage.current); 48 | } 49 | 50 | public function closeFrame():Void 51 | { 52 | window.close(); 53 | } 54 | public function asDialog():Dialog return null; 55 | public function asScreen():DialogScreen return null; 56 | } 57 | -------------------------------------------------------------------------------- /samples/08-Swf/SwfTest.hx: -------------------------------------------------------------------------------- 1 | import nme.display.Sprite; 2 | import gm2d.Game; 3 | import gm2d.Screen; 4 | import gm2d.reso.Resources; 5 | 6 | #if swf 7 | import format.SWF; 8 | #else 9 | import gm2d.swf.SWF; 10 | #end 11 | 12 | 13 | 14 | class SwfTest extends Screen 15 | { 16 | function new() 17 | { 18 | super(); 19 | 20 | var obj = new Sprite(); 21 | addChild(obj); 22 | //obj.cacheAsBitmap = true; 23 | var gfx=obj.graphics; 24 | gfx.beginFill(0x00ff00); 25 | gfx.moveTo(100,100); 26 | gfx.lineTo(200,100); 27 | gfx.lineTo(200,200); 28 | gfx.lineTo(100,200); 29 | gfx.lineTo(100,100); 30 | gfx.moveTo(120,120); 31 | gfx.lineTo(180,120); 32 | gfx.lineTo(180,180); 33 | gfx.lineTo(120,180); 34 | gfx.lineTo(120,120); 35 | 36 | 37 | var test=[ "AdvancedLines", "Text", "GradientFillMotion", "ShapeMorph" ]; 38 | var idx = 0; 39 | var gfx = graphics; 40 | gfx.lineStyle(1,0x000000); 41 | for(y in 0...2) 42 | for(x in 0...2) 43 | { 44 | gfx.drawRect(x*320+1, y*240+1, 318, 238 ); 45 | var data = Resources.loadBytes("tests/" + test[idx++] + ".swf"); 46 | //trace(data.length); 47 | var swf = new SWF(data); 48 | var obj = swf.createMovieClip(); 49 | //obj.cacheAsBitmap = true; 50 | obj.x = x*320; 51 | obj.y = y*240; 52 | obj.scaleX = 0.5; 53 | obj.scaleY = 0.5; 54 | addChild(obj); 55 | } 56 | makeCurrent(); 57 | } 58 | 59 | override public function getScaleMode() { return gm2d.ScreenScaleMode.TOPLEFT_SCALED; } 60 | 61 | override public function updateDelta(inDT:Float) 62 | { 63 | } 64 | 65 | 66 | static public function main() 67 | { 68 | Game.showFPS = true; 69 | Game.fpsColor = 0xffffff; 70 | new SwfTest(); 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push] 3 | 4 | jobs: 5 | release: 6 | runs-on: ubuntu-latest 7 | name: Release 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@v3 11 | 12 | - uses: krdlab/setup-haxe@v1 13 | with: 14 | haxe-version: 4.3.0 15 | 16 | - name: Set Haxelib 17 | run: | 18 | haxe -version 19 | haxelib dev gm2d . 20 | 21 | - name: Set Version 22 | run: haxe -cp tools/version --run Write ${{github.run_number}} >> $GITHUB_ENV 23 | 24 | - name: Zip release 25 | run: | 26 | mkdir gm2d-${{ env.gm2d_release }} 27 | cp -r Changes.md README.md gm2d haxelib.json samples gm2d-${{ env.gm2d_release }} 28 | zip -r gm2d-${{ env.gm2d_release }}.zip gm2d-${{ env.gm2d_release }} 29 | 30 | - name: Create Release 31 | id: create_release 32 | uses: actions/create-release@v1 33 | env: 34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 35 | with: 36 | tag_name: v${{ env.gm2d_release }} 37 | release_name: Release ${{ env.gm2d_release }} 38 | draft: false 39 | prerelease: false 40 | 41 | - name: Upload Release Asset 42 | id: upload-release-asset 43 | uses: actions/upload-release-asset@v1 44 | env: 45 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 46 | with: 47 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps 48 | asset_path: ./gm2d-${{ env.gm2d_release }}.zip 49 | asset_name: gm2d-${{ env.gm2d_release }}.zip 50 | asset_content_type: application/zip 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /gm2d/ui/FileSave.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | import nme.utils.ByteArray; 3 | import gm2d.ui.ProgressDialog; 4 | 5 | #if flash 6 | 7 | import flash.net.FileReference; 8 | import flash.net.FileFilter; 9 | import flash.events.Event; 10 | import flash.events.IOErrorEvent; 11 | import flash.events.ProgressEvent; 12 | import flash.events.SecurityErrorEvent; 13 | 14 | #elseif waxe 15 | 16 | import wx.FileDialog; 17 | 18 | #end 19 | 20 | 21 | class FileSave 22 | { 23 | public static function saveAs(inMessage:String, 24 | onResult:String->Void, 25 | onError:String->Void, 26 | ?inExtension:String, 27 | ?inDefaultPath:String, 28 | ?saveName:String, 29 | inFlags:Int = 0) 30 | { 31 | if (saveName!=null) 32 | { 33 | var parts = saveName.split("\\").join("/").split("/"); 34 | if (parts.length>1) 35 | { 36 | saveName = parts.pop(); 37 | if (inDefaultPath==null) 38 | inDefaultPath = parts.join("/"); 39 | } 40 | } 41 | 42 | 43 | #if waxe 44 | var flags = inFlags | FileDialog.SAVE | FileDialog.OVERWRITE_PROMPT; 45 | 46 | var dialog = new wx.FileDialog( 47 | null, 48 | inMessage, 49 | inDefaultPath, 50 | saveName, 51 | inExtension==null ? null : "*." + inExtension, 52 | flags); 53 | if (dialog.showModal()) 54 | { 55 | var dir = dialog.directory; 56 | var name = dir + "/" + dialog.file; 57 | onResult(name); 58 | } 59 | else 60 | onResult(null); 61 | #elseif flash 62 | #else 63 | 64 | var openScreen = new gm2d.ui.FileOpenScreen(inMessage, inDefaultPath==null?"":inDefaultPath, 65 | null, inExtension, inFlags | FileOpen.SAVE, saveName ); 66 | openScreen.onSaveResult = onResult; 67 | openScreen.onError = onError; 68 | 69 | #end 70 | } 71 | 72 | } 73 | 74 | 75 | -------------------------------------------------------------------------------- /gm2d/swf/DepthSlot.hx: -------------------------------------------------------------------------------- 1 | package gm2d.swf; 2 | 3 | import gm2d.swf.Character; 4 | import gm2d.swf.DisplayAttributes; 5 | import nme.geom.ColorTransform; 6 | import nme.geom.Matrix; 7 | 8 | 9 | 10 | class DepthSlot 11 | { 12 | //static var sInstanceID = 1; 13 | 14 | public var mID:Int; 15 | public var mAttribs : DisplayAttributesList; 16 | public var mCharacter : Character; 17 | 18 | // This is used when building 19 | var mCurrentAttrib : DisplayAttributes; 20 | 21 | 22 | public function new(inCharacter:Character,inCharacterID:Int, 23 | inAttribs:DisplayAttributes) 24 | { 25 | mID = inCharacterID; 26 | mAttribs = []; 27 | mAttribs.push(inAttribs); 28 | mCurrentAttrib = inAttribs; 29 | mCharacter = inCharacter; 30 | } 31 | 32 | public function toString() return 'DepthSlot($mID:$mAttribs,$mCharacter)'; 33 | 34 | public function Move(inFrame:Int, 35 | inMatrix:Matrix, inColTx:ColorTransform, 36 | inRatio:Null) 37 | { 38 | mCurrentAttrib = mCurrentAttrib.clone(); 39 | mCurrentAttrib.mFrame = inFrame; 40 | if (inMatrix!=null) mCurrentAttrib.mMatrix = inMatrix; 41 | if (inColTx!=null) mCurrentAttrib.mColorTransform = inColTx; 42 | if (inRatio!=null) mCurrentAttrib.mRatio = inRatio; 43 | mAttribs.push(mCurrentAttrib); 44 | } 45 | 46 | 47 | 48 | public function FindClosestFrame(inHintFrame:Int,inFrame:Int) 49 | { 50 | var last = inHintFrame; 51 | var n = mAttribs.length; 52 | if (last>=mAttribs.length) 53 | last = 0; 54 | else if (last>0) 55 | { 56 | if ( mAttribs[last-1].mFrame > inFrame) 57 | last = 0; 58 | } 59 | 60 | for(i in last...n) 61 | { 62 | if (mAttribs[i].mFrame > inFrame) 63 | { 64 | return last; 65 | } 66 | last = i; 67 | } 68 | 69 | return last; 70 | } 71 | 72 | 73 | } 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /gm2d/blit/Layer.hx: -------------------------------------------------------------------------------- 1 | package gm2d.blit; 2 | 3 | 4 | class Layer 5 | { 6 | public var offsetX(default,set):Float; 7 | public var offsetY(default,set):Float; 8 | public var worldWidth(get,null):Float; 9 | public var worldHeight(get,null):Float; 10 | public var viewWidth(get,null):Float; 11 | public var viewHeight(get,null):Float; 12 | public var visible(default,set):Bool; 13 | public var blendAdd:Bool; 14 | 15 | 16 | var mViewport:Viewport; 17 | 18 | function new(inVP:Viewport) 19 | { 20 | mViewport = inVP; 21 | visible = true; 22 | offsetX = 0; 23 | offsetY = 0; 24 | blendAdd = false; 25 | } 26 | 27 | public function gm2dRender(inOX:Float, inOY:Float) { } 28 | 29 | public function resize(inWidth:Int, inHeight:Int) { } 30 | 31 | public function gm2dClear() { } 32 | 33 | public function addTile(inTile:Tile, inX:Float, inY:Float) { } 34 | 35 | dynamic public function dynamicRender(inOX:Float, inOY:Float) : Void { } 36 | 37 | public function drawTile(inTile:Tile, inX:Float, inY:Float) { } 38 | 39 | public function isPersistent() : Bool { return false; } 40 | 41 | public function set_visible(inVis:Bool) : Bool 42 | { 43 | visible= inVis; 44 | if (mViewport!=null) { mViewport.invalidate(); } 45 | return inVis; 46 | } 47 | 48 | public function clear() 49 | { 50 | if (mViewport!=null) { mViewport.invalidate(); } 51 | gm2dClear(); 52 | } 53 | 54 | 55 | function set_offsetX(inVal:Float):Float 56 | { 57 | offsetX = Std.int(inVal); 58 | return inVal; 59 | } 60 | 61 | function set_offsetY(inVal:Float):Float 62 | { 63 | offsetY = Std.int(inVal); 64 | return inVal; 65 | } 66 | 67 | function get_worldWidth() { return mViewport.worldWidth; } 68 | function get_worldHeight() { return mViewport.worldWidth; } 69 | function get_viewWidth() { return mViewport.viewWidth; } 70 | function get_viewHeight() { return mViewport.viewWidth; } 71 | } 72 | -------------------------------------------------------------------------------- /gm2d/ui/MenuGroup.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import gm2d.skin.Skin; 4 | 5 | 6 | class MenuGroup 7 | { 8 | public var onItem:String->Void; 9 | public var items:Array; 10 | public var callbacks:ArrayVoid>; 11 | public var menu:MenuItem; 12 | public var current:String; 13 | public var bitmapFactory: String->Int->nme.display.BitmapData; 14 | public var defaultValue:String; 15 | 16 | public function new(inMenu:MenuItem,?inOnItem:String->Void,defaultValue:String=null) 17 | { 18 | menu = inMenu; 19 | onItem = inOnItem; 20 | items = []; 21 | callbacks = []; 22 | current = defaultValue; 23 | } 24 | public function onSelect(inItem:MenuItem) 25 | { 26 | var key = inItem.id; 27 | setState(key); 28 | if (onItem!=null) 29 | onItem(current); 30 | for(i in 0...items.length) 31 | if (items[i].id==key) 32 | { 33 | if (callbacks[i]!=null) 34 | callbacks[i](); 35 | break; 36 | } 37 | Game.closePopup(); 38 | } 39 | public function setState(inKey:String) 40 | { 41 | current = inKey; 42 | for(i in 0...items.length) 43 | items[i].checked = current==items[i].id; 44 | } 45 | 46 | public function add(inText:String, ?inKey:String, ?inOnItem:Void->Void,?inShortcut:String) : MenuItem 47 | { 48 | var item = new MenuItem(inText, onSelect); 49 | item.id = inKey!=null ? inKey : inText; 50 | item.shortcut = inShortcut; 51 | item.checkStyle = "MenuRadiobox"; 52 | 53 | if (inKey!=null && nme.Assets.exists(inKey) ) 54 | { 55 | var bmp = Skin.getSkin().createBitmapData(inKey,16); 56 | item.icon = bmp; 57 | } 58 | item.checkable = true; 59 | if (current==null) 60 | current = item.id; 61 | item.checked = current==item.id; 62 | callbacks.push(inOnItem); 63 | items.push(item); 64 | menu.add(item); 65 | return item; 66 | } 67 | } 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /samples/SvgDir/Svg.hx: -------------------------------------------------------------------------------- 1 | import nme.display.*; 2 | import gm2d.svg.SvgRenderer; 3 | using StringTools; 4 | 5 | 6 | class Svg extends Sprite 7 | { 8 | var allSvgs:Array; 9 | var pos = 0; 10 | 11 | function new() 12 | { 13 | super(); 14 | 15 | allSvgs = []; 16 | 17 | var args = Sys.args(); 18 | if (args.length==0) 19 | { 20 | Sys.println("Usage: SvgDir dirname | name1.svg name2.svg ..."); 21 | } 22 | else 23 | { 24 | for(a in args) 25 | { 26 | if (a.endsWith(".svg")) 27 | allSvgs.push(a); 28 | else 29 | { 30 | try 31 | { 32 | for(f in sys.FileSystem.readDirectory(a)) 33 | if (f.endsWith(".svg")) 34 | allSvgs.push(a + "/" + f); 35 | } 36 | catch(e:Dynamic) 37 | { 38 | trace("Error:" + e); 39 | } 40 | } 41 | } 42 | } 43 | Sys.println("Found " + allSvgs.length + " files"); 44 | if (allSvgs.length>0) 45 | { 46 | stage.addEventListener( nme.events.MouseEvent.CLICK, (_)->next() ); 47 | next(); 48 | } 49 | } 50 | function next() 51 | { 52 | var filename = allSvgs[pos]; 53 | pos = (pos+1)%allSvgs.length; 54 | while(numChildren>0) 55 | removeChildAt(0); 56 | 57 | try 58 | { 59 | var file = sys.io.File.getContent(filename); 60 | 61 | var xml:Xml = Xml.parse(file); 62 | var svg = new gm2d.svg.Svg(xml,true); 63 | var renderer = new SvgRenderer(svg,0x000040); 64 | var shape = renderer.createShape(); 65 | var scale = Math.min( stage.stageWidth/svg.width, stage.stageHeight/svg.height); 66 | shape.scaleX = shape.scaleY = scale; 67 | shape.x = (stage.stageWidth-svg.width*scale)*0.5; 68 | shape.y = (stage.stageHeight-svg.height*scale)*0.5; 69 | addChild(shape); 70 | Sys.println(filename); 71 | } 72 | catch(e:Dynamic) 73 | { 74 | trace('Error loading: $filename, $e'); 75 | } 76 | 77 | } 78 | } 79 | 80 | -------------------------------------------------------------------------------- /gm2d/gfx/Gfx2Haxe.hx: -------------------------------------------------------------------------------- 1 | package gm2d.gfx; 2 | 3 | import nme.display.GradientType; 4 | import nme.display.SpreadMethod; 5 | import nme.display.InterpolationMethod; 6 | import nme.display.CapsStyle; 7 | import nme.display.JointStyle; 8 | import nme.display.LineScaleMode; 9 | import nme.geom.Matrix; 10 | 11 | 12 | class Gfx2Haxe extends Gfx 13 | { 14 | public var commands : Array; 15 | 16 | public function new( ) 17 | { 18 | super(); 19 | commands = []; 20 | } 21 | 22 | function f2a(f:Float):String 23 | { 24 | if (Math.abs(f)<0.000001) return "0"; 25 | if (Math.abs(1-f)<0.000001) return "1"; 26 | return f+""; 27 | } 28 | 29 | 30 | function newMatrix(m:Matrix) 31 | { 32 | return "new Matrix(" + f2a(m.a) + "," + f2a(m.b) + "," + f2a(m.c) + "," + f2a(m.d) + "," + f2a(m.tx) + "," + f2a(m.ty) + ")"; 33 | } 34 | 35 | 36 | override public function beginGradientFill(grad:Gradient) 37 | { 38 | commands.push("g.beginGradientFill(" + grad.type + ","+ grad.colors + "," + grad.alphas + "," + 39 | grad.ratios + "," + newMatrix(grad.matrix) + "," + grad.spread + "," + 40 | grad.interp+ "," + grad.focus + ");" ); 41 | } 42 | 43 | override public function beginFill(color:Int, alpha:Float) 44 | { 45 | commands.push("g.beginFill(" + color + "," + f2a(alpha) + ");"); 46 | } 47 | override public function endFill() { commands.push("g.endFill();"); } 48 | 49 | 50 | override public function lineStyle(style:LineStyle) 51 | { 52 | commands.push("g.lineStyle("+f2a(style.thickness)+","+style.color+","+f2a(style.alpha)+"," + style.pixelHinting + "," + style.scaleMode + "," + style.capsStyle + "," + style.jointStyle + "," + f2a(style.miterLimit) + ");" ); 53 | } 54 | 55 | 56 | override public function endLineStyle() { commands.push("g.lineStyle();"); } 57 | 58 | override public function moveTo(inX:Float, inY:Float) 59 | { commands.push("g.moveTo(" + inX + "," + inY + ");"); } 60 | override public function lineTo(inX:Float, inY:Float) 61 | { commands.push("g.lineTo(" + inX + "," + inY + ");"); } 62 | override public function curveTo(inCX:Float, inCY:Float,inX:Float,inY:Float) 63 | { commands.push("g.curveTo(" + inCX + "," + inCY + "," + inX + "," + inY + ");"); } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /gm2d/ui/Image.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import nme.display.BitmapData; 4 | import nme.display.Bitmap; 5 | import nme.display.Sprite; 6 | import gm2d.ui.Layout; 7 | import gm2d.skin.Skin; 8 | import gm2d.skin.Renderer; 9 | import gm2d.svg.SvgRenderer; 10 | 11 | 12 | class Image extends Widget 13 | { 14 | public var bitmapData(get,set):BitmapData; 15 | var bitmap:Bitmap; 16 | 17 | public function new(?skin:Skin, ?inBmp:BitmapData, ?inLineage:Array, ?inAttribs:{}) 18 | { 19 | super(skin,Widget.addLine(inLineage,"Image"),inAttribs); 20 | var bmp = inBmp != null ? inBmp : getBitmap(); 21 | if (bmp!=null) 22 | { 23 | bitmap = new Bitmap(bmp, nme.display.PixelSnapping.AUTO, attribBool("smooth", true)); 24 | addChild(bitmap); 25 | var bmpScale = attribFloat("bmpScale",1.0); 26 | if (bmpScale!=1.0) 27 | bitmap.scaleX = bitmap.scaleY = bmpScale; 28 | var align = attribInt("alignBitmap", Layout.AlignGraphcsRect|Layout.AlignKeepAspect ); 29 | setItemLayout( new DisplayLayout(bitmap,align) ); 30 | } 31 | applyStyles(); 32 | } 33 | 34 | /* 35 | override public function onWidgetDrawn() { 36 | if (bitmap!=null) 37 | { 38 | bitmap.width = mRect.width; 39 | bitmap.height = mRect.height; 40 | } 41 | } 42 | */ 43 | 44 | public static function fromSvg(?skin:Skin,resoName:String, inScale = 1.0,?inLineage:Array, ?inAttribs:{}) 45 | { 46 | if (skin==null) 47 | skin = Skin.getSkin(); 48 | var svg = new SvgRenderer(gm2d.reso.Resources.loadSvg(resoName)); 49 | 50 | var w = skin.scale(svg.width*inScale); 51 | var h = skin.scale(svg.height*inScale); 52 | var bmp = new BitmapData(w,h,true, gm2d.RGB.CLEAR ); 53 | 54 | var shape = svg.createShape(); 55 | var scaled = new Sprite(); 56 | scaled.addChild(shape); 57 | shape.scaleX = w/svg.width; 58 | shape.scaleY = h/svg.height; 59 | bmp.draw(scaled); 60 | 61 | return new Image(skin, bmp, inLineage, inAttribs); 62 | } 63 | 64 | function get_bitmapData() return bitmap==null ? null : bitmap.bitmapData; 65 | function set_bitmapData(inData:BitmapData) :BitmapData 66 | { 67 | if (bitmap!=null) 68 | bitmap.bitmapData = inData; 69 | return inData; 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /gm2d/ui/MenuItem.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import gm2d.Screen; 4 | import gm2d.Game; 5 | import nme.display.BitmapData; 6 | import nme.display.Graphics; 7 | import nme.events.MouseEvent; 8 | import nme.events.KeyboardEvent; 9 | 10 | class MenuItem 11 | { 12 | public var text:String; 13 | public var data:Dynamic; 14 | public var shortcut(get,set):String; 15 | public var icon:BitmapData; 16 | public var checkable:Bool; 17 | public var checked:Bool; 18 | public var enabled:Bool; 19 | public var id:String; 20 | public var wxId:Int; 21 | public var onSelect:MenuItem->Void; 22 | public var checkStyle = "MenuCheckbox"; 23 | var keyboardAccel:KeyboardAccel; 24 | 25 | //public var gmPopup:PopupMenu; 26 | public var children:Array; 27 | 28 | 29 | public function new(inText:String,inOnSelect:MenuItem->Void=null) 30 | { 31 | text = inText; 32 | checkable = false; 33 | checked = false; 34 | onSelect = inOnSelect; 35 | enabled = true; 36 | id = null; 37 | wxId = -1; 38 | } 39 | 40 | public function set_shortcut(inShortcut:String) : String 41 | { 42 | if (inShortcut==null || inShortcut=="") 43 | keyboardAccel = null; 44 | else 45 | keyboardAccel = new KeyboardAccel(inShortcut); 46 | return inShortcut; 47 | } 48 | 49 | public function get_shortcut() : String 50 | { 51 | if (keyboardAccel==null) 52 | return null; 53 | return keyboardAccel.shortcutText; 54 | } 55 | 56 | public function onKey(key:KeyboardEvent) : Bool 57 | { 58 | if (enabled && keyboardAccel!=null && keyboardAccel.matches(key)) 59 | { 60 | if (checkable) 61 | checked = !checked; 62 | if (onSelect!=null) 63 | onSelect(this); 64 | return true; 65 | } 66 | if (enabled && children!=null) 67 | for(child in children) 68 | if (child!=null && child.onKey(key)) 69 | return true; 70 | return false; 71 | } 72 | 73 | 74 | public function addSeparator() 75 | { 76 | add(null); 77 | } 78 | public function add(inItem:MenuItem) 79 | { 80 | if (children==null) 81 | children = []; 82 | children.push(inItem); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /gm2d/ui/ChoiceButtons.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import nme.text.TextField; 4 | import nme.display.BitmapData; 5 | import nme.events.MouseEvent; 6 | import gm2d.ui.Button; 7 | import gm2d.ui.Layout; 8 | import gm2d.skin.Skin; 9 | 10 | class ChoiceButtons extends Control 11 | { 12 | var group:RadioGroup; 13 | var layout:Layout; 14 | 15 | public function new(inOnChoice:String->Void,?inItemsPerRow:Null,?inLineage:Array,?inAttribs:Dynamic) 16 | { 17 | super(Widget.addLine(inLineage,"ChoiceButtons"), inAttribs); 18 | 19 | group = new RadioGroup(inOnChoice); 20 | 21 | if (!mRenderer.getDefaultBool("overlapped", false ) ) 22 | { 23 | var grid = new GridLayout(inItemsPerRow,"button"); 24 | grid.setSpacing(1,1); 25 | layout = grid; 26 | } 27 | else 28 | { 29 | var paged = new PagedLayout(); 30 | group.onItem = function(p) { 31 | paged.setPage(p); 32 | if (inOnChoice!=null) 33 | inOnChoice( group.keys[p] ); 34 | }; 35 | layout = paged; 36 | } 37 | 38 | setItemLayout(layout); 39 | build(); 40 | } 41 | 42 | public static function create(inOnIndex:Int->Void,inKeys:Array, inBitmaps:Map, ?inItemsPerRow:Int, ?inAttribs:Dynamic ) 43 | { 44 | var keys:Array = inKeys.map( function(x) return Std.string(x) ); 45 | 46 | var result = new ChoiceButtons( function(x) inOnIndex(Lambda.indexOf(keys,x)), inItemsPerRow,null,inAttribs ); 47 | 48 | for(key in keys) 49 | { 50 | if (!inBitmaps.exists(key)) 51 | throw "ChoiceButtons : missing bitmap " + key; 52 | var button = Button.BitmapButton(inBitmaps.get(key),null,["ChoiceButton","SimpleButton"],inAttribs); 53 | result.add( button, key ); 54 | } 55 | return result; 56 | } 57 | 58 | public function add(inButton:Button,?inKey:String) 59 | { 60 | addChild(inButton); 61 | layout.add(inButton.getLayout().pixelAlign()); 62 | if (inKey==null) 63 | inKey = inButton.getId(); 64 | group.add(inButton,inKey); 65 | } 66 | public function setValue(inKey:String) 67 | { 68 | group.setState(inKey); 69 | } 70 | 71 | public function setIndex(inIndex:Int) 72 | { 73 | group.setIndex(inIndex); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /gm2d/blit/NMELayer.hx: -------------------------------------------------------------------------------- 1 | package gm2d.blit; 2 | 3 | #if !flash 4 | import nme.display.Graphics; 5 | 6 | class NMELayer extends Layer 7 | { 8 | var mXYID:Array; 9 | var mCurrentSheet:Tilesheet; 10 | public var gm2dShape:nme.display.Shape; 11 | 12 | function new(inVP:NMEViewport) 13 | { 14 | gm2dShape = new nme.display.Shape(); 15 | mXYID = []; 16 | mCurrentSheet = null; 17 | super(inVP); 18 | } 19 | 20 | function Flush() 21 | { 22 | if (mXYID.length>0) 23 | { 24 | gm2dShape.graphics.drawTiles(mCurrentSheet.gm2dSheet,mXYID,blendAdd?Graphics.TILE_BLEND_ADD:0); 25 | mCurrentSheet = null; 26 | mXYID = []; 27 | } 28 | } 29 | 30 | public static function gm2dCreate(inVP:NMEViewport) 31 | { 32 | return new NMELayer(inVP); 33 | } 34 | 35 | public override function gm2dRender(inOX:Float, inOY:Float) 36 | { 37 | inOX -= offsetX; 38 | inOY -= offsetY; 39 | gm2dShape.x = -inOX; 40 | gm2dShape.y = -inOY; 41 | 42 | if (dynamicRender!=null) 43 | dynamicRender(inOX,inOY); 44 | 45 | Flush(); 46 | } 47 | 48 | 49 | public override function isPersistent() : Bool { return true; } 50 | 51 | public override function drawTile(inTile:Tile, inX:Float, inY:Float) 52 | { 53 | var sheet = inTile.sheet; 54 | if (sheet!=mCurrentSheet) 55 | { 56 | Flush(); 57 | mCurrentSheet = sheet; 58 | } 59 | mXYID.push(inX-inTile.hotX); 60 | mXYID.push(inY-inTile.hotY); 61 | mXYID.push(inTile.id); 62 | } 63 | 64 | 65 | public override function addTile(inTile:Tile, inX:Float, inY:Float) 66 | { 67 | var sheet = inTile.sheet; 68 | if (sheet!=mCurrentSheet) 69 | { 70 | Flush(); 71 | mCurrentSheet = sheet; 72 | } 73 | mXYID.push(inX-inTile.hotX); 74 | mXYID.push(inY-inTile.hotY); 75 | mXYID.push(inTile.id); 76 | } 77 | 78 | override public function set_visible(inVis:Bool) : Bool 79 | { 80 | gm2dShape.visible = inVis; 81 | return super.set_visible(inVis); 82 | } 83 | 84 | 85 | public override function gm2dClear() 86 | { 87 | mCurrentSheet = null; 88 | mXYID = []; 89 | gm2dShape.graphics.clear(); 90 | } 91 | 92 | } 93 | 94 | #end 95 | -------------------------------------------------------------------------------- /gm2d/swf/Frame.hx: -------------------------------------------------------------------------------- 1 | package gm2d.swf; 2 | 3 | import gm2d.swf.Character; 4 | import gm2d.swf.DepthSlot; 5 | import gm2d.swf.DisplayAttributes; 6 | import nme.geom.Matrix; 7 | import nme.geom.ColorTransform; 8 | 9 | 10 | #if haxe3 11 | typedef DepthObjects = haxe.ds.IntMap; 12 | #else 13 | typedef DepthObjects = IntHash; 14 | #end 15 | 16 | 17 | class Frame 18 | { 19 | var mObjects : DepthObjects; 20 | var mFrame : Int; 21 | 22 | public function new(?inPrev:Frame) 23 | { 24 | mObjects = new DepthObjects(); 25 | if (inPrev!=null) 26 | { 27 | var objs = inPrev.mObjects; 28 | for(depth in objs.keys()) 29 | mObjects.set( depth, objs.get(depth) ); 30 | mFrame = inPrev.mFrame + 1; 31 | } 32 | else 33 | mFrame = 1; 34 | } 35 | 36 | public function toString() return 'Frame($mFrame: $mObjects)'; 37 | 38 | public function CopyObjectSet() 39 | { 40 | var c = new DepthObjects(); 41 | for(d in mObjects.keys()) 42 | c.set(d,mObjects.get(d)); 43 | return c; 44 | } 45 | 46 | public function Remove(inDepth:Int) 47 | { 48 | mObjects.remove(inDepth); 49 | } 50 | 51 | public function Place(inCharID:Int, inChar:Character, inDepth:Int, 52 | inMatrix:Matrix, inColTx:ColorTransform, 53 | inRatio:Null, inName:String) 54 | { 55 | var old = mObjects.get(inDepth); 56 | if (old!=null) 57 | throw("Overwriting non-empty depth"); 58 | var attrib = new DisplayAttributes( ); 59 | attrib.mFrame = mFrame; 60 | attrib.mMatrix = inMatrix; 61 | attrib.mColorTransform = inColTx; 62 | attrib.mRatio = inRatio; 63 | attrib.mName = inName; 64 | attrib.mCharacterID = inCharID; 65 | var obj = new DepthSlot(inChar,inCharID,attrib); 66 | mObjects.set(inDepth,obj); 67 | } 68 | 69 | public function Move(inDepth:Int, 70 | inMatrix:Matrix, inColTx:ColorTransform, 71 | inRatio:Null) 72 | { 73 | var obj = mObjects.get(inDepth); 74 | if (obj==null) 75 | throw("depth has no object"); 76 | 77 | obj.Move(mFrame, inMatrix, inColTx, inRatio); 78 | } 79 | 80 | public function GetFrame() { return mFrame; } 81 | 82 | } 83 | 84 | typedef Frames = Array; 85 | -------------------------------------------------------------------------------- /gm2d/blit/Tilesheets.hx: -------------------------------------------------------------------------------- 1 | package gm2d.blit; 2 | 3 | import nme.display.BitmapData; 4 | import gm2d.blit.Tile; 5 | import gm2d.blit.Tilesheet; 6 | 7 | 8 | class Tilesheets 9 | { 10 | var mConstructTilesheet:Tilesheet; 11 | 12 | public function new() 13 | { 14 | } 15 | 16 | function NextPOT(inVal:Int) 17 | { 18 | var result = 1; 19 | while(result512) w = 512; 33 | if (w512) h = 512; 36 | if (h 0; 55 | var fx = (inTransform & FLIP_X) > 0; 56 | var fy = (inTransform & FLIP_Y) > 0; 57 | if (fxy) { var t = fx; fx = fy; fy=t; } 58 | var w = Std.int(fxy ? r.height : r.width); 59 | var h = Std.int(fxy ? r.width : r.height); 60 | var data = new BitmapData(w,h,true); 61 | var src = inTile.sheet.gm2dData; 62 | var x0 = Std.int(r.x); 63 | var y0 = Std.int(r.y); 64 | for(y in 0...Std.int(r.height)) 65 | for(x in 0...Std.int(r.width)) 66 | { 67 | var xi = x; 68 | var yi = y; 69 | if (fx) yi = h - 1 - yi; 70 | if (fy) xi = w - 1 - xi; 71 | if (fxy) 72 | { 73 | var t = xi; 74 | xi = yi; 75 | yi = w - 1 - t; 76 | } 77 | data.setPixel32( x, y, src.getPixel32(x0 + xi, y0 + yi) ); 78 | } 79 | return addData(data); 80 | } 81 | } 82 | 83 | 84 | -------------------------------------------------------------------------------- /gm2d/blit/GridHandler.hx: -------------------------------------------------------------------------------- 1 | package gm2d.blit; 2 | 3 | import gm2d.blit.Grid; 4 | 5 | 6 | class GridHandler 7 | { 8 | var mLayer:Layer; 9 | var mGrid:Grid; 10 | var mGridW:Int; 11 | var mGridH:Int; 12 | var mTileW:Int; 13 | var mTileH:Int; 14 | 15 | var mLastX0:Int; 16 | var mLastY0:Int; 17 | var mLastX1:Int; 18 | var mLastY1:Int; 19 | 20 | public function new(inLayer:Layer, inGrid:Grid) 21 | { 22 | mLayer = inLayer; 23 | mGrid = inGrid; 24 | 25 | mGridH = mGrid.length; 26 | mTileW = mTileH = mGridW = 0; 27 | 28 | for(row in mGrid) 29 | { 30 | if (row.length>mGridW) mGridW = row.length; 31 | for(tile in row) 32 | { 33 | if (tile.rect.width>mTileW) 34 | mTileW = Std.int(tile.rect.width); 35 | if (tile.rect.height>mTileH) 36 | mTileH = Std.int(tile.rect.height); 37 | } 38 | } 39 | 40 | inLayer.dynamicRender = doRender; 41 | mLastX0 = mLastY0 = mLastX1 = mLastY1 = 0; 42 | } 43 | 44 | function doRender(inOX:Float, inOY:Float) : Void 45 | { 46 | var x0 = Std.int(Math.floor(inOX/mTileW)); 47 | var y0 = Std.int(Math.floor(inOY/mTileH)); 48 | var x1 = Std.int(Math.ceil((mLayer.viewWidth+inOX)/mTileW)); 49 | var y1 = Std.int(Math.ceil((mLayer.viewHeight+inOY)/mTileH)); 50 | 51 | if (x1<0 || y1<0 || x0>=mGridW || y0>=mGridH ) 52 | return; 53 | 54 | if (mLayer.isPersistent()) 55 | { 56 | if (x0>=mLastX0 && y0>=mLastY0 && x1<=mLastX1 && y1<=mLastY1) 57 | return; 58 | 59 | // Add gap, so we don't have to re-do the map too often 60 | x0--; 61 | y0--; 62 | x1++; 63 | y1++; 64 | // Don't need to re-do if it is in these bounds 65 | mLastX0 = x0; 66 | mLastY0 = y0; 67 | mLastX1 = x1; 68 | mLastY1 = y1; 69 | } 70 | 71 | mLayer.clear(); 72 | 73 | if (x0<0) x0 = 0; 74 | if (y0<0) y0 = 0; 75 | if (x1>mGridW) x1=mGridW; 76 | if (y1>mGridH) y1=mGridH; 77 | 78 | if (x0>=x1 || y0>=y1) return; 79 | 80 | for(y in y0...y1) 81 | { 82 | var row = mGrid[y]; 83 | var ty = y*mTileH; 84 | for(x in x0...x1) 85 | { 86 | var tile = row[x]; 87 | if (tile!=null) 88 | { 89 | mLayer.drawTile(tile,x*mTileW,ty); 90 | } 91 | } 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /gm2d/ui/TabBar.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import nme.geom.Rectangle; 4 | import nme.display.Sprite; 5 | import nme.display.Shape; 6 | import nme.display.Bitmap; 7 | import nme.display.BitmapData; 8 | import nme.display.DisplayObjectContainer; 9 | import nme.text.TextField; 10 | //import gm2d.ui.HitBoxes; 11 | import nme.geom.Point; 12 | import nme.events.MouseEvent; 13 | import gm2d.ui.HitBoxes; 14 | import gm2d.ui.Dock; 15 | import gm2d.ui.DockPosition; 16 | import gm2d.Game; 17 | import gm2d.skin.Skin; 18 | import gm2d.skin.TabRenderer; 19 | import gm2d.ui.WidgetState; 20 | import gm2d.ui.Layout; 21 | 22 | 23 | class TabBar extends Widget 24 | { 25 | public var currentDockable:IDockable; 26 | public var isMaximised:Bool; 27 | 28 | var tabsWidth:Float; 29 | var tabsHeight:Float; 30 | var mHitBoxes:HitBoxes; 31 | var mDockables:Array; 32 | var tabRenderer:TabRenderer; 33 | var allowRestore:Bool; 34 | 35 | public function new(?inSkin:Skin, inDockables:Array, inOnHitBox: HitAction->MouseEvent->Void, inAllowRestore:Bool) 36 | { 37 | super(inSkin,["TabBar"] ); 38 | mDockables = inDockables; 39 | tabRenderer = skin.tabRenderer(); 40 | mHitBoxes = new HitBoxes(skin,this,inOnHitBox); 41 | var layout = new Layout(); 42 | layout.setAlignment(Layout.AlignStretch); 43 | layout.onLayout = layoutTabs; 44 | setItemLayout(layout); 45 | mLayout.setAlignment(Layout.AlignStretch | Layout.AlignTop); 46 | tabsWidth = tabsHeight = 0; 47 | allowRestore = inAllowRestore; 48 | //build(); 49 | } 50 | 51 | override public function redraw() 52 | { 53 | super.redraw(); 54 | 55 | mHitBoxes.clear(); 56 | 57 | var flags = TabRenderer.SHOW_TEXT | TabRenderer.SHOW_ICON | TabRenderer.SHOW_POPUP | TabRenderer.SHOW_CLOSE; 58 | if (isMaximised && allowRestore) 59 | flags |= TabRenderer.SHOW_RESTORE; 60 | tabRenderer.renderTabs(mChrome, new Rectangle(0,0,tabsWidth,tabsHeight), 61 | mDockables, currentDockable, mHitBoxes, TabRenderer.TOP, flags); 62 | } 63 | 64 | public function setTop(inCurrent:IDockable, inIsMaximised:Bool) 65 | { 66 | currentDockable = inCurrent; 67 | isMaximised = inIsMaximised; 68 | redraw(); 69 | } 70 | 71 | 72 | function layoutTabs(inX:Float, inY:Float, inW:Float, inH:Float) 73 | { 74 | tabsWidth = inW; 75 | tabsHeight = inH; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /gm2d/ui/MiniWin.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import gm2d.Screen; 4 | import gm2d.ScreenScaleMode; 5 | import gm2d.skin.Skin; 6 | import gm2d.ui.Layout; 7 | import gm2d.ui.HitBoxes; 8 | import nme.display.Sprite; 9 | import nme.geom.Point; 10 | import nme.geom.Rectangle; 11 | import nme.events.MouseEvent; 12 | 13 | class MiniWin extends Sprite 14 | { 15 | public var pane(default,null) : Pane; 16 | 17 | var mScreen : Screen; 18 | var mHitBoxes:HitBoxes; 19 | var mClientWidth:Float; 20 | var mClientHeight:Float; 21 | var mClientOffset:Point; 22 | var mDragStage:nme.display.Stage; 23 | 24 | public function new(inPane:Pane, inScreen:Screen ) 25 | { 26 | super(); 27 | pane = inPane; 28 | mHitBoxes = new HitBoxes(this, onHitBox); 29 | mScreen = inScreen; 30 | addChild(inPane.displayObject); 31 | 32 | mClientOffset = Skin.getMiniWinClientOffset(); 33 | pane.displayObject.x = mClientOffset.x; 34 | pane.displayObject.y = mClientOffset.y; 35 | x = 20; 36 | y = 100; 37 | alpha = 0.5; 38 | mClientWidth = 200; 39 | mClientHeight = 200; 40 | //pane.displayObject.scrollRect = new Rectangle(20,20,mClientWidth, mClientHeight); 41 | Skin.renderMiniWin(this,pane,new Rectangle(0,0,mClientWidth,mClientHeight),mHitBoxes,true); 42 | addChild(pane.displayObject); 43 | mScreen.addChild(this); 44 | } 45 | 46 | public function destroy() 47 | { 48 | parent.removeChild(this); 49 | } 50 | 51 | function onHitBox(inAction:HitAction, e) 52 | { 53 | switch(inAction) 54 | { 55 | case DRAG(_pane): 56 | stage.addEventListener(MouseEvent.MOUSE_UP,onEndDrag); 57 | mDragStage = stage; 58 | startDrag(); 59 | case TITLE(pane): 60 | Dock.raise(pane); 61 | case BUTTON(pane,id): 62 | if (id==MiniButton.CLOSE) 63 | pane.closeRequest(false); 64 | redraw(); 65 | case REDRAW: 66 | redraw(); 67 | default: 68 | } 69 | } 70 | 71 | function saveRect() 72 | { 73 | } 74 | 75 | function redraw() 76 | { 77 | Skin.renderMiniWin(this,pane,new Rectangle(0,0,mClientWidth,mClientHeight),mHitBoxes,true); 78 | } 79 | 80 | function onEndDrag(_) 81 | { 82 | mDragStage.removeEventListener(MouseEvent.MOUSE_UP,onEndDrag); 83 | stopDrag(); 84 | saveRect(); 85 | } 86 | 87 | 88 | } 89 | 90 | 91 | -------------------------------------------------------------------------------- /gm2d/ui/TabWidget.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import nme.text.TextFormat; 4 | import gm2d.ui.Layout; 5 | import nme.filters.BitmapFilter; 6 | import nme.filters.DropShadowFilter; 7 | import gm2d.ui.HitBoxes; 8 | import nme.geom.Rectangle; 9 | import gm2d.skin.Skin; 10 | import gm2d.skin.Renderer; 11 | 12 | 13 | class TabWidget extends Widget 14 | { 15 | var currentWidget:Widget; 16 | var widgets:Array; 17 | var tabBar:Widget; 18 | 19 | public function new(inWidgets:Array, inCurrent:Widget, ?inLineage:Array, ?inAttribs:{}) 20 | { 21 | widgets = inWidgets.copy(); 22 | 23 | super(Widget.addLines(inLineage,["Tabs"]), inAttribs); 24 | 25 | doSetCurrent(inCurrent); 26 | build(); 27 | } 28 | 29 | public function setCurrent(inWidget:Widget) 30 | { 31 | if (inWidget!=currentWidget) 32 | { 33 | if (currentWidget!=null) 34 | removeChild(currentWidget); 35 | currentWidget = inWidget; 36 | if (currentWidget!=null) 37 | addChild(currentWidget); 38 | } 39 | } 40 | 41 | override public function addWidget(inWidget:Widget) 42 | { 43 | widgets.push(inWidget); 44 | doSetCurrent(inWidget); 45 | onChildLayoutChanged(); 46 | return this; 47 | } 48 | 49 | function doSetCurrent(inWidget:Widget) 50 | { 51 | if (currentWidget!=null) 52 | removeChild(currentWidget); 53 | 54 | if (tabBar!=null) 55 | removeChild(tabBar); 56 | var lineage:Array = attribDynamic("tabBoxLineage", ["TabBox"]); 57 | tabBar = new Widget(lineage); 58 | addChild(tabBar); 59 | 60 | currentWidget = inWidget; 61 | if (currentWidget!=null) 62 | addChild(currentWidget); 63 | 64 | var hlayout = new HorizontalLayout(); 65 | var allWidgets = new StackLayout(); 66 | var buttonLineage:Array = attribDynamic("tabButtonLineage",["TabButton"]); 67 | var group = new RadioGroup(setCurrent); 68 | for(w in widgets) 69 | { 70 | var ico = w.getBitmap(); 71 | var button = new Button(buttonLineage, { text:w.name, bitmapData:ico, toggle:true } ); 72 | group.add(button, w); 73 | addChild(button); 74 | hlayout.add( button.getLayout() ); 75 | allWidgets.add( w.getLayout() ); 76 | } 77 | tabBar.setItemLayout(hlayout); 78 | tabBar.build(); 79 | 80 | var vlayout = new VerticalLayout(); 81 | vlayout.add(tabBar.getLayout()); 82 | 83 | group.setState(currentWidget); 84 | 85 | vlayout.add(allWidgets.stretch()); 86 | setItemLayout(vlayout); 87 | } 88 | } 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /gm2d/ui/FileBox.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import nme.text.TextField; 4 | import gm2d.ui.Button; 5 | import gm2d.ui.Layout; 6 | import gm2d.skin.Skin; 7 | import gm2d.skin.Renderer; 8 | 9 | 10 | class FileBox extends TextInput 11 | { 12 | var mButtonX:Float; 13 | var onText:String->Void; 14 | var isDir:Bool; 15 | var rightAlign = true; 16 | var defaultText:String; 17 | 18 | public function new(inVal="", ?inLineage:Array, ?inAttribs:{}) 19 | { 20 | super(inVal, null, Widget.addLine(inLineage,"FileBox"), inAttribs); 21 | isDir = attribBool("directory",false); 22 | setText( inVal ); 23 | if (inVal=="" || inVal==null) 24 | { 25 | var rememberKey = attribString("dir_id",""); 26 | if (rememberKey=="") 27 | rememberKey = null; 28 | if (rememberKey!=null) 29 | { 30 | var def = nme.system.Dialog.getDefaultPath(rememberKey); 31 | setText( def ); 32 | if (!isDir) 33 | defaultText = def; 34 | } 35 | else 36 | { 37 | setText( inVal ); 38 | } 39 | } 40 | } 41 | 42 | override public function get(inValue:Dynamic) : Void 43 | { 44 | if (Reflect.hasField(inValue,name)) 45 | { 46 | var value = getText(); 47 | if (defaultText==null || value!=defaultText) 48 | Reflect.setField(inValue, name, value ); 49 | } 50 | } 51 | 52 | function onBrowse() 53 | { 54 | var title = attribString("browseTitle",isDir ? "Select Directory" : "Select File"); 55 | // remembered in panel 56 | var rememberKey = attribString("dir_id",""); 57 | if (rememberKey=="") 58 | rememberKey = null; 59 | if (isDir) 60 | { 61 | nme.system.Dialog.getDirectory(title,"Directory", function(f) if (f!=null) setTextEnter(f),rememberKey ); 62 | } 63 | else 64 | { 65 | var flags = attribInt("browseFlags",0); 66 | var ext = attribString("browseFilter","All Files|*.*"); 67 | var start = getText(); 68 | nme.system.Dialog.fileDialog(title,"File", getText(), ext, 69 | function(f) if (f!=null) setTextEnter(f), rememberKey, flags ); 70 | } 71 | } 72 | 73 | function setTextEnter(val:String) 74 | { 75 | setText(val); 76 | if (onTextEnter!=null) 77 | onTextEnter(val); 78 | } 79 | 80 | override public function createExtraWidgetLayout() : Layout 81 | { 82 | var browseButton = Button.TextButton("Browse",onBrowse); 83 | addChild(browseButton); 84 | return browseButton.getLayout(); 85 | } 86 | 87 | } 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /gm2d/ui/SecondaryWin.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import gm2d.Screen; 4 | import gm2d.ScreenScaleMode; 5 | import gm2d.skin.Skin; 6 | import gm2d.ui.Layout; 7 | import nme.display.Sprite; 8 | import nme.geom.Point; 9 | import nme.geom.Rectangle; 10 | import gm2d.ui.HitBoxes; 11 | import nme.events.Event; 12 | import nme.events.MouseEvent; 13 | 14 | class SecondaryWin extends DocumentParent implements IDock 15 | { 16 | var window:nme.app.Window; 17 | var dragOx:Int; 18 | var dragOy:Int; 19 | 20 | public function new(?inSkin:Skin, ?pane:Pane,inW:Float, inH:Float) 21 | { 22 | super(inSkin,true); 23 | 24 | dragOx = dragOy = 0; 25 | 26 | var title = pane==null ? nme.Lib.title : pane.getTitle(); 27 | var fps = 0.0; 28 | 29 | window = nme.Lib.createSecondaryWindow( 30 | Std.int(inW), Std.int(inH), title, 31 | nme.app.Application.HARDWARE | nme.app.Application.RESIZABLE, 32 | nme.Lib.nmeStage.opaqueBackground, fps, pane==null ? null : pane.getIcon() ); 33 | var stage = window.stage; 34 | stage.scaleMode = nme.display.StageScaleMode.NO_SCALE; 35 | stage.addEventListener( Event.RESIZE, (_) -> { 36 | mLayout.setRect(0,0, stage.stageWidth, stage.stageHeight); 37 | }); 38 | stage.onCloseRequest = onClose; 39 | stage.current.addChild(this); 40 | setClientSize(0,0,stage.stageWidth, stage.stageHeight); 41 | } 42 | 43 | public function onClose() 44 | { 45 | getCurrent().closeRequest(true); 46 | } 47 | 48 | function trackMouse() 49 | { 50 | var timer = new haxe.Timer(10); 51 | timer.run = () -> { 52 | var state = window.globalMouseState; 53 | if (state.getButton(0)) 54 | { 55 | window.setPosition(state.x + dragOx,state.y + dragOy); 56 | DocumentParent.showGlobalDockZones(state.x,state.y, this); 57 | } 58 | else 59 | { 60 | timer.stop(); 61 | var pane = current.asPane(); 62 | if (pane!=null) 63 | DocumentParent.dropGlobalDockZones(pane,state.x,state.y, this); 64 | DocumentParent.hideGlobalDropZones(); 65 | } 66 | }; 67 | } 68 | 69 | public function continueDrag(watcher:MouseWatcher) 70 | { 71 | dragOx = -5; 72 | dragOy = 20; 73 | watcher.onDrag = null; 74 | trackMouse(); 75 | } 76 | 77 | override public function removeDockable(inPane:IDockable):IDockable 78 | { 79 | super.removeDockable(inPane); 80 | if (mDockables.length==0) 81 | { 82 | unregister(); 83 | window.close(); 84 | } 85 | return this; 86 | } 87 | 88 | } 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /gm2d/ui/AsyncThumbnailer.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import sys.thread.Mutex; 4 | import sys.thread.Thread; 5 | import nme.display.*; 6 | import gm2d.svg.*; 7 | 8 | private class Job 9 | { 10 | var filename:String; 11 | var widget:Widget; 12 | var size:Size; 13 | var bmp:BitmapData; 14 | 15 | public function new(inFilename:String, inWidget:Widget, inSize:Size) 16 | { 17 | filename = inFilename; 18 | widget = inWidget; 19 | size = inSize; 20 | } 21 | 22 | public function run() 23 | { 24 | try 25 | { 26 | var content = sys.io.File.getContent(filename); 27 | var xml = Xml.parse(content); 28 | var svg = new Svg(xml,true); 29 | var renderer = new SvgRenderer(svg); 30 | var scale = Math.min(size.x/svg.width, size.y/svg.height); 31 | bmp = renderer.renderBitmap(scale); 32 | } 33 | catch(e:Dynamic) 34 | { 35 | } 36 | } 37 | 38 | public function ok() return bmp!=null; 39 | 40 | public function apply() 41 | { 42 | if (bmp!=null) 43 | { 44 | //trace("apply " + bmp.width + "x" + bmp.height); 45 | widget.setBitmap(bmp); 46 | } 47 | } 48 | } 49 | 50 | class AsyncThumbnailer 51 | { 52 | static var lock:Mutex; 53 | static var queue = new Array(); 54 | static var procThread:Thread; 55 | 56 | static function add(job:Job) 57 | { 58 | if (lock==null) 59 | { 60 | lock = new Mutex(); 61 | lock.acquire(); 62 | procThread = Thread.create(threadLoop); 63 | } 64 | else 65 | lock.acquire(); 66 | 67 | queue.push(job); 68 | if (queue.length==1) 69 | procThread.sendMessage(null); 70 | lock.release(); 71 | } 72 | static function remove(job:Job) 73 | { 74 | lock.acquire(); 75 | queue.remove(job); 76 | lock.release(); 77 | } 78 | 79 | static function threadLoop() 80 | { 81 | while(true) 82 | { 83 | var job:Job = null; 84 | lock.acquire(); 85 | if (queue.length>0) 86 | job = queue.shift(); 87 | lock.release(); 88 | if (job!=null) 89 | { 90 | job.run(); 91 | if (job.ok()) 92 | nme.app.Application.runOnMainThread( job.apply ); 93 | } 94 | else 95 | Thread.readMessage(true); 96 | } 97 | } 98 | 99 | public static function factory(filename:String, widget:Widget, size:Size) 100 | { 101 | var job = new Job(filename,widget,size); 102 | add(job); 103 | widget.addEventListener( nme.events.Event.REMOVED_FROM_STAGE, (_)->remove(job) ); 104 | } 105 | } 106 | 107 | -------------------------------------------------------------------------------- /gm2d/reso/Resources.hx: -------------------------------------------------------------------------------- 1 | package gm2d.reso; 2 | 3 | import nme.utils.IDataInput; 4 | import nme.Assets; 5 | import gm2d.svg.Svg; 6 | import gm2d.svg.SvgRenderer; 7 | 8 | 9 | class Resources 10 | { 11 | static public function loadAsset(inName:String, ?inCache:Bool) : Dynamic 12 | { 13 | var i = Assets.getInfo(inName); 14 | if (i==null) 15 | throw "Missing asset: " + inName; 16 | 17 | var cached = i.getCache(); 18 | if (cached!=null) 19 | return cached; 20 | switch(i.type) 21 | { 22 | case BINARY, TEXT: return Assets.getBytes(inName,inCache); 23 | case FONT: return Assets.getFont(inName,inCache); 24 | case IMAGE: return Assets.getBitmapData(inName,inCache); 25 | case MUSIC, SOUND: return Assets.getSound(inName,inCache); 26 | case _: throw "Unknown asset type: " + i.type; 27 | } 28 | 29 | return null; 30 | } 31 | 32 | 33 | static public function loadBitmap(inAssetName:String, ?inCache:Bool) : nme.display.BitmapData 34 | { 35 | return Assets.getBitmapData(inAssetName,inCache); 36 | } 37 | 38 | static public function loadScaledBitmap(inAssetName:String, ?inCache:Bool) : nme.display.BitmapData 39 | { 40 | return gm2d.skin.Skin.scaleBitmap(Assets.getBitmapData(inAssetName,inCache)); 41 | } 42 | 43 | 44 | static public function loadBytes(inAssetName:String, ?inCache:Bool) : nme.utils.ByteArray 45 | { 46 | return Assets.getBytes(inAssetName,inCache); 47 | } 48 | 49 | 50 | static public function loadString(inAssetName:String, ?inCache:Bool) : String 51 | { 52 | return Assets.getString(inAssetName,inCache); 53 | } 54 | 55 | static public function loadXml(inAssetName:String, ?inCache:Bool) : Xml 56 | { 57 | var str = loadString(inAssetName,inCache); 58 | if (str==null) 59 | return null; 60 | var xml:Xml = Xml.parse(str); 61 | if (xml==null) 62 | return null; 63 | //if (inCache) 64 | // mLoaded.set(inAssetName,xml); 65 | return xml; 66 | } 67 | 68 | static public function loadSvg(inAssetName:String, ?inCache:Bool) : Svg 69 | { 70 | //var cached = mLoaded.get(inAssetName); 71 | //if (cached!=null && Std.is(cached,Svg)) 72 | // return cached; 73 | 74 | var xml:Xml = loadXml(inAssetName,inCache); 75 | if (xml==null) 76 | return null; 77 | var svg = new Svg(xml); 78 | //if (inCache) 79 | // mLoaded.set(inAssetName,svg); 80 | return svg; 81 | } 82 | 83 | static public function loadSvgRenderer(inAssetName:String, ?inCache:Bool) : SvgRenderer 84 | { 85 | return new SvgRenderer(loadSvg(inAssetName,inCache)); 86 | } 87 | 88 | 89 | 90 | static public function loadSound(inAssetName:String, ?inCache:Bool) : nme.media.Sound 91 | { 92 | return loadAsset(inAssetName,inCache); 93 | } 94 | 95 | } 96 | 97 | 98 | -------------------------------------------------------------------------------- /gm2d/blit/BMPLayer.hx: -------------------------------------------------------------------------------- 1 | package gm2d.blit; 2 | 3 | import nme.display.BitmapData; 4 | import nme.geom.Point; 5 | 6 | class LayerTile 7 | { 8 | public function new(inTile:Tile,inX:Float,inY:Float) 9 | { 10 | tile = inTile; 11 | x = inX - inTile.hotX; 12 | y = inY - inTile.hotY; 13 | next = null; 14 | } 15 | public var tile:Tile; 16 | public var x:Float; 17 | public var y:Float; 18 | public var next:LayerTile; 19 | } 20 | 21 | class BMPLayer extends Layer 22 | { 23 | var mHead:LayerTile; 24 | var mLast:LayerTile; 25 | var mDynamicOX:Float; 26 | var mDynamicOY:Float; 27 | var mPos:Point; 28 | var mBMPViewport:BMPViewport; 29 | public var bitmap(default,null):BitmapData; 30 | 31 | function new(inVP:BMPViewport) 32 | { 33 | super(inVP); 34 | mHead = null; 35 | mLast = null; 36 | mDynamicOX = mDynamicOY = 0; 37 | mPos = new Point(); 38 | mBMPViewport = inVP; 39 | bitmap = mBMPViewport.gm2dBitmapData; 40 | } 41 | 42 | public static function gm2dCreate(inVP:BMPViewport) 43 | { 44 | return new BMPLayer(inVP); 45 | } 46 | 47 | public override function resize(inWidth:Int, inHeight:Int) 48 | { 49 | bitmap = mBMPViewport.gm2dBitmapData; 50 | } 51 | 52 | 53 | public override function drawTile(inTile:Tile, inX:Float, inY:Float) 54 | { 55 | var p = mPos; 56 | p.x = inX + mDynamicOX -inTile.hotX; 57 | p.y = inY + mDynamicOY -inTile.hotY; 58 | bitmap.copyPixels(inTile.sheet.gm2dData, inTile.rect, p, null, null, inTile.sheet.useAlpha); 59 | } 60 | 61 | public override function gm2dRender(inOX:Float, inOY:Float) 62 | { 63 | var tile = mHead; 64 | var pos = new nme.geom.Point(); 65 | var ox = offsetX - inOX; 66 | var oy = offsetY - inOY; 67 | while(tile!=null) 68 | { 69 | pos.x = tile.x + ox; 70 | pos.y = tile.y + oy; 71 | var t = tile.tile; 72 | bitmap.copyPixels(t.sheet.gm2dData, t.rect, pos, null, null, t.sheet.useAlpha); 73 | tile = tile.next; 74 | } 75 | 76 | if (dynamicRender!=null) 77 | { 78 | mDynamicOX = ox; 79 | mDynamicOY = oy; 80 | dynamicRender(inOX,inOY); 81 | } 82 | } 83 | 84 | public override function addTile(inTile:Tile, inX:Float, inY:Float) 85 | { 86 | if (mViewport!=null) { mViewport.invalidate(); } 87 | if (mLast==null) 88 | { 89 | mLast = mHead = new LayerTile(inTile,inX,inY); 90 | } 91 | else 92 | { 93 | mLast.next = new LayerTile(inTile,inX,inY); 94 | mLast = mLast.next; 95 | } 96 | } 97 | 98 | public override function gm2dClear() 99 | { 100 | if (mHead!=null && mViewport!=null) 101 | mViewport.invalidate(); 102 | mHead = mLast = null; 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /gm2d/ui/ProgressBar.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | import gm2d.skin.Skin; 3 | import gm2d.skin.ProgressStyle; 4 | import nme.events.Event; 5 | 6 | 7 | class ProgressBar extends Widget 8 | { 9 | var mMax:Float; 10 | var mFraction:Float; 11 | var ball:nme.display.Shape; 12 | var ballRad:Float; 13 | var t0:Float; 14 | 15 | public function new(?inSkin:Skin, inMax:Float,?inLineage:Array,?inAttribs:{}) 16 | { 17 | super(Widget.addLine(inLineage,"ProgressBar"),inAttribs); 18 | mMax = inMax; 19 | mFraction = 0.0; 20 | //build(); 21 | } 22 | 23 | public function update(inValue:Float) 24 | { 25 | mFraction = inValue / mMax; 26 | if (mFraction>1) mFraction = 1; 27 | if (mFraction<0) mFraction = 0; 28 | redraw(); 29 | } 30 | 31 | function updateBallPos() 32 | { 33 | if (mFraction<1) 34 | { 35 | var w = mRect.width - ballRad*2; 36 | var h = mRect.height - ballRad*2; 37 | 38 | var bpos = ((haxe.Timer.stamp()-t0)*0.5) % 2; 39 | if (bpos>1) 40 | bpos = 2-bpos; 41 | ball.x = ballRad + w*bpos; 42 | ball.y = ballRad + h*0.5; 43 | 44 | if (stage!=null) 45 | stage.invalidate(); 46 | } 47 | } 48 | 49 | override public function redraw() 50 | { 51 | var gfx = graphics; 52 | 53 | gfx.clear(); 54 | var style:ProgressStyle = attribDynamic("progressStyle",null); 55 | if (style==null) 56 | return; 57 | switch(style) 58 | { 59 | case ProgressRoundRect(outline, fill, empty, lineWidth, rad): 60 | var w = mRect.width; 61 | var h = mRect.height; 62 | 63 | var off = (Std.int(lineWidth) & 1) > 0 ? 0.5 : 0.0; 64 | gfx.beginFill(empty); 65 | gfx.drawRoundRect(off,off,w,h,rad,rad); 66 | gfx.lineStyle(); 67 | gfx.beginFill(fill); 68 | gfx.drawRoundRect(off,off,w*mFraction,h,rad,rad); 69 | gfx.endFill(); 70 | gfx.lineStyle(lineWidth,outline); 71 | gfx.drawRoundRect(off,off,w,h,rad,rad); 72 | 73 | case ProgressRoundRectBall(outline, fill, empty, lineWidth, rad): 74 | var w = mRect.width; 75 | var h = mRect.height; 76 | 77 | var off = (Std.int(lineWidth) & 1) > 0 ? 0.5 : 0.0; 78 | gfx.beginFill(empty); 79 | gfx.lineStyle(lineWidth,outline); 80 | gfx.drawRoundRect(off,off,w,h,rad,rad); 81 | 82 | if (ball==null && mFraction<1) 83 | { 84 | ball = new nme.display.Shape(); 85 | addChild(ball); 86 | ballRad = rad; 87 | var g = ball.graphics; 88 | g.beginFill(fill); 89 | g.drawCircle(0,0,rad); 90 | t0 = haxe.Timer.stamp(); 91 | 92 | addEventListener( Event.ENTER_FRAME, (_) -> updateBallPos() ); 93 | addEventListener( Event.RENDER, (_) -> updateBallPos() ); 94 | 95 | updateBallPos(); 96 | } 97 | } 98 | } 99 | } 100 | 101 | -------------------------------------------------------------------------------- /gm2d/skin/ShadowCache.hx: -------------------------------------------------------------------------------- 1 | package gm2d.skin; 2 | 3 | import nme.display.BitmapData; 4 | import nme.display.Sprite; 5 | import nme.display.Shape; 6 | import nme.geom.Rectangle; 7 | import nme.filters.BitmapFilter; 8 | import nme.filters.BitmapFilterType; 9 | import nme.filters.DropShadowFilter; 10 | import nme.filters.GlowFilter; 11 | 12 | 13 | 14 | class ShadowCache 15 | { 16 | static var now = 0.0; 17 | static var instances = new Array(); 18 | static var drawing:Sprite; 19 | 20 | static public function create(skin:Skin, lineStyle:LineStyle, fillStyle:FillStyle, depth:Float,flags:Int,rad:Float) 21 | { 22 | var result:ShadowInstance = null; 23 | for(i in instances) 24 | if (i.matches(lineStyle, fillStyle, depth, flags, rad)) 25 | { 26 | result = i; 27 | break; 28 | } 29 | 30 | if (result==null) 31 | { 32 | var bmp = new BitmapData(32,32,true,0x0000ff); 33 | initGfx(); 34 | var child = new Shape(); 35 | drawing.addChild(child); 36 | 37 | var gfx = child.graphics; 38 | Renderer.setFill(skin,gfx,fillStyle,0,0); 39 | Renderer.setLine(skin,gfx,lineStyle); 40 | 41 | var lw = Renderer.getLineWidth(lineStyle)*0.5; 42 | var rectMode = (flags & EdgeFlags.Rect) > 0; 43 | var gap = rectMode ? lw : 6.0; 44 | 45 | var x0 = gap; 46 | var y0 = gap; 47 | var x1 = 32.0-gap; 48 | var y1 = 32.0-gap; 49 | var avoid = lw + rad; 50 | 51 | if ( (flags&EdgeFlags.TopSolid)>0 ) 52 | y0 = - avoid; 53 | else if ( (flags&EdgeFlags.TopLine)>0 ) 54 | y0 = lw; 55 | 56 | if ( (flags&EdgeFlags.LeftSolid)>0 ) 57 | x0 = - avoid; 58 | else if ( (flags&EdgeFlags.LeftLine)>0 ) 59 | x0 = lw; 60 | 61 | if ( (flags&EdgeFlags.RightSolid)>0 ) 62 | x1 = 32+avoid; 63 | else if ( (flags&EdgeFlags.RightLine)>0 ) 64 | x1 = 32-lw; 65 | 66 | 67 | if ( (flags&EdgeFlags.BottomSolid)>0 ) 68 | y1 = 32+avoid; 69 | else if ( (flags&EdgeFlags.BottomLine)>0 ) 70 | y1 = 32-lw; 71 | 72 | if (rad==0) 73 | gfx.drawRect(x0,y0,x1-x0,y1-y0); 74 | else 75 | gfx.drawRoundRect(x0,y0,x1-x0,y1-y0,rad,rad); 76 | 77 | if (depth>0) 78 | child.filters = [ new DropShadowFilter(depth,90,0,0.8,depth*2+3,depth*2+3,1) ]; 79 | else 80 | child.filters = null; 81 | 82 | bmp.draw(drawing); 83 | 84 | var inner = new Rectangle(10,10,12,12); 85 | result = new ShadowInstance(lineStyle, fillStyle, depth, flags, rad, bmp, inner); 86 | instances.push(result); 87 | } 88 | 89 | result.use( now++ ); 90 | 91 | return result; 92 | } 93 | 94 | static function initGfx() 95 | { 96 | if (drawing==null) 97 | drawing = new Sprite(); 98 | else 99 | { 100 | drawing.graphics.clear(); 101 | while(drawing.numChildren>0) 102 | drawing.removeChildAt( drawing.numChildren-1 ); 103 | } 104 | } 105 | 106 | } 107 | 108 | -------------------------------------------------------------------------------- /gm2d/tween/Timeline.hx: -------------------------------------------------------------------------------- 1 | package gm2d.tween; 2 | 3 | import haxe.Timer; 4 | 5 | class Timeline 6 | { 7 | public var time(default,null):Float; 8 | var tweens:Array; 9 | var timer:Timer; 10 | 11 | public function new( ) 12 | { 13 | tweens = new Array(); 14 | time = 0; 15 | } 16 | public function onActivate(isActive:Bool) 17 | { 18 | if (isActive) 19 | { 20 | if (timer!=null) 21 | { 22 | timer.stop(); 23 | timer = null; 24 | } 25 | } 26 | else 27 | { 28 | // Huh? 29 | if (timer!=null) 30 | return; 31 | checkTimer(); 32 | } 33 | } 34 | 35 | function checkTimer() 36 | { 37 | if ( (timer!=null) != (tweens.length>0) ) 38 | { 39 | if (tweens.length>0) 40 | { 41 | timer = new Timer(50); 42 | timer.run = Game.update; 43 | } 44 | else 45 | { 46 | timer.stop(); 47 | timer = null; 48 | } 49 | } 50 | } 51 | 52 | public function clearAll(inWithCallback = true) 53 | { 54 | if (inWithCallback) 55 | for(tween in tweens) 56 | if (tween.onComplete!=null) 57 | tween.onComplete(); 58 | tweens = new Array(); 59 | checkTimer(); 60 | } 61 | public function remove(inName:String, inWithCallback = true) 62 | { 63 | for(i in 0...tweens.length) 64 | { 65 | var tween = tweens[i]; 66 | if (tween.name==inName) 67 | { 68 | tweens.splice(i,1); 69 | if (inWithCallback && tween.onComplete!=null) 70 | tween.onComplete(); 71 | checkTimer(); 72 | return; 73 | } 74 | } 75 | } 76 | public function update(inDT:Float) 77 | { 78 | //if (inDT>0.2) trace(inDT); 79 | time += inDT; 80 | if (tweens.length>0) 81 | { 82 | var curr_tweens = tweens; 83 | tweens = new Array(); 84 | for(tween in curr_tweens) 85 | { 86 | if (tween.t1>time) 87 | { 88 | if (tween.onUpdate!=null) 89 | tween.onUpdate( (time-tween.t0)/(tween.t1-tween.t0) ); 90 | tweens.push(tween); 91 | } 92 | else 93 | { 94 | if (tween.onUpdate!=null) 95 | tween.onUpdate(1.0); 96 | if (tween.onComplete!=null) 97 | tween.onComplete(); 98 | } 99 | } 100 | } 101 | checkTimer(); 102 | } 103 | 104 | 105 | public function createTween(inName:String,inVal0:Float,inVal1:Float, 106 | inSeconds:Float, 107 | inOnUpdate:Float->Void, 108 | ?inOnComplete:Void->Void, 109 | ?inEasing:Float->Float ) : Tween 110 | { 111 | var tween = new Tween(inName, time, time+inSeconds, null, inOnComplete); 112 | if (inOnUpdate!=null) 113 | { 114 | if (inEasing==null) 115 | tween.onUpdate = function(x:Float) inOnUpdate( inVal0 + x*(inVal1-inVal0) ); 116 | else 117 | tween.onUpdate = function(x:Float) inOnUpdate( inVal0 + inEasing(x)*(inVal1-inVal0) ); 118 | tween.onUpdate(0); 119 | } 120 | tweens.push(tween); 121 | checkTimer(); 122 | return tween; 123 | } 124 | } 125 | 126 | 127 | -------------------------------------------------------------------------------- /gm2d/ui/KeyboardAccel.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | import nme.events.KeyboardEvent; 3 | import nme.ui.Keyboard; 4 | 5 | class KeyboardAccel 6 | { 7 | public var shortcutText:String; 8 | public var ctrl:Bool; 9 | public var shift:Bool; 10 | public var alt:Bool; 11 | public var code:Int; 12 | 13 | public function new(inShortcut:String) 14 | { 15 | shortcutText = inShortcut; 16 | ctrl = shift = alt = false; 17 | code = -1; 18 | 19 | for(part in inShortcut.split("+")) 20 | { 21 | if (part.length>1 && part.substr(0,1)=="F") 22 | { 23 | code = Std.parseInt( part.substr(1) ) + 111; 24 | } 25 | else if (part>="0" && part<="9") 26 | { 27 | code = part.charCodeAt(0); 28 | } 29 | else 30 | switch(part) 31 | { 32 | case "Ctrl" : ctrl = true; 33 | case "Alt" : alt = true; 34 | case "Shift" : shift = true; 35 | case "Del" : code = Keyboard.DELETE; 36 | case "Insert" : code = Keyboard.INSERT; 37 | case "PgUp" : code = Keyboard.PAGE_UP; 38 | case "PgDn" : code = Keyboard.PAGE_DOWN; 39 | case "Enter" : code = Keyboard.ENTER; 40 | case "End" : code = Keyboard.END; 41 | case "Home" : code = Keyboard.HOME; 42 | case "=" : code = Keyboard.EQUAL; 43 | case "Down" : code = Keyboard.DOWN; 44 | case "Up" : code = Keyboard.UP; 45 | case "Left" : code = Keyboard.LEFT; 46 | case "Right" : code = Keyboard.RIGHT; 47 | case "Esc" : code = Keyboard.ESCAPE; 48 | case "-" : code = Keyboard.MINUS; 49 | case "`" : code = Keyboard.BACKQUOTE; 50 | case "," : code = Keyboard.COMMA; 51 | case ";" : code = Keyboard.SEMICOLON; 52 | case "(" : code = Keyboard.LEFTBRACKET; 53 | case ")" : code = Keyboard.RIGHTBRACKET; 54 | case "." : code = Keyboard.PERIOD; 55 | case "[" : code = 219; 56 | case "]" : code = 221; 57 | default: 58 | var upper= part.toUpperCase(); 59 | if (upper.charCodeAt(0)>='A'.code && upper.charCodeAt(0)<='Z'.code) 60 | code = upper.charCodeAt(0); 61 | else 62 | { 63 | var f = Reflect.field(Keyboard,upper); 64 | if (Std.isOfType(f,Int)) 65 | { 66 | code = f; 67 | } 68 | else 69 | { 70 | //throw "Unknown key : " + part; 71 | trace("Unknown key : "); 72 | } 73 | } 74 | } 75 | } 76 | if (code<0) 77 | throw "No key code specified"; 78 | } 79 | 80 | public function matches(key:KeyboardEvent) : Bool 81 | { 82 | var match = (Std.int(key.keyCode)==code || (code==Keyboard.DELETE && key.keyCode==8) ) 83 | && shift==key.shiftKey && alt==key.altKey && ctrl==key.ctrlKey; 84 | return match; 85 | // return Std.int(key.keyCode)==code && shift==key.shiftKey && alt==key.altKey && ctrl==key.ctrlKey; 86 | } 87 | 88 | public function toString() 89 | { 90 | return 'KeyboardAccel($shortcutText,$code,$shift,$alt,$ctrl)'; 91 | } 92 | } 93 | 94 | 95 | -------------------------------------------------------------------------------- /gm2d/ui/DockSizeHandler.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import nme.geom.Rectangle; 4 | import nme.display.Sprite; 5 | import nme.events.MouseEvent; 6 | import nme.geom.Point; 7 | 8 | class DockSizeHandler 9 | { 10 | var container:Sprite; 11 | var overlayContainer:Sprite; 12 | var resizeBox:Rectangle; 13 | var resizeListen:Bool; 14 | 15 | 16 | public function new(inContainer:Sprite, inOverlay:Sprite, inHitBoxes:HitBoxes) 17 | { 18 | container = inContainer; 19 | overlayContainer = inOverlay; 20 | inHitBoxes.onOverDockSize = onOverDockSize; 21 | inHitBoxes.onDockSizeDown = onDockSizeDown; 22 | resizeListen = false; 23 | } 24 | 25 | public function onOverDockSize(inDock:SideDock, inIndex:Int, inX:Float, inY:Float, inRect:Rectangle ) 26 | { 27 | //trace("onOverDockSize!"); 28 | showResizeHint(inX,inY,inDock.isHorizontal()); 29 | 30 | resizeBox = inRect; 31 | if (!resizeListen) 32 | { 33 | container.stage.addEventListener(MouseEvent.MOUSE_MOVE,checkResizeDock); 34 | resizeListen = true; 35 | } 36 | } 37 | 38 | public function onDockSizeDown(inDock:SideDock, inIndex:Int, inX:Float, inY:Float, inRect:Rectangle ) 39 | { 40 | //trace("Drag dock " + inX + "," + inY); 41 | resizeBox = null; 42 | container.stage.removeEventListener(MouseEvent.MOUSE_MOVE,checkResizeDock); 43 | resizeListen = false; 44 | 45 | var watcher = MouseWatcher.watchDrag(container,inX,inY, 46 | function(_) onDockSize(inDock,inIndex,_) , clearOverlay ); 47 | watcher.combineDragEvents(0.25); 48 | } 49 | 50 | function onDockSize(inDock:SideDock, inIndex:Int, inEvent:MouseEvent) 51 | { 52 | showResizeHint(inEvent.stageX,inEvent.stageY,inDock.isHorizontal()); 53 | inDock.tryResize(inIndex, inDock.isHorizontal() ? inEvent.stageX : inEvent.stageY ); 54 | //trace(inEvent); 55 | } 56 | 57 | public function checkResizeDock(inMouse:MouseEvent) 58 | { 59 | if (resizeBox!=null) 60 | { 61 | var pos = container.globalToLocal( new Point(inMouse.stageX,inMouse.stageY) ); 62 | if (!resizeBox.contains(pos.x,pos.y)) 63 | { 64 | resizeBox = null; 65 | container.removeEventListener(MouseEvent.MOUSE_MOVE,checkResizeDock); 66 | resizeListen = false; 67 | clearOverlay(); 68 | } 69 | } 70 | } 71 | 72 | function clearOverlay(?_:Dynamic) 73 | { 74 | overlayContainer.graphics.clear(); 75 | overlayContainer.x = 0; 76 | overlayContainer.y = 0; 77 | overlayContainer.scaleX = overlayContainer.scaleY = 1.0; 78 | while(overlayContainer.numChildren>0) 79 | overlayContainer.removeChildAt(0); 80 | } 81 | 82 | 83 | function showResizeHint(inX:Float, inY:Float, inHorizontal:Bool) 84 | { 85 | overlayContainer.x = inX-16; 86 | overlayContainer.y = inY-16; 87 | overlayContainer.cacheAsBitmap = true; 88 | overlayContainer.mouseEnabled = false; 89 | var gfx = overlayContainer.graphics; 90 | gfx.clear(); 91 | if (inHorizontal) 92 | new gm2d.icons.EastWest().render(gfx); 93 | else 94 | new gm2d.icons.NorthSouth().render(gfx); 95 | var scale = gm2d.skin.Skin.dpiScale; 96 | if (scale!=1) 97 | overlayContainer.scaleX = overlayContainer.scaleY = scale; 98 | } 99 | 100 | 101 | } 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /gm2d/icons/Folder.hx: -------------------------------------------------------------------------------- 1 | package gm2d.icons; 2 | 3 | import gm2d.gfx.GfxBytes; 4 | import gm2d.gfx.GfxGraphics; 5 | import nme.display.Graphics; 6 | 7 | 8 | class Folder extends Icon 9 | { 10 | static var data = "eNqNV2tYlNUWHjH1CMgIDAwwDN8WROUWpdwUhLWWejya6TFLRY+YaHq8xSNYeaHDRbSUTEwTEbmKiUpyU5CLIFdTDExR4yChYoJKXhJCDJvz7WE+yuMPneeZed9nzXr33uvda+/5ph+BTMbfNtgvr5teuz3HQNZfpntpwrSfw0bZj/M+k/ZNsUXQbHbNyxL9lj0kiya33qQ+oUCW6ZV/Eud6E0H7VR8RvzI0sxG/rBJptkE/PT5470Q+pkb60qzep/fWkdVqI7JIUeimkDRMIlo0sDvdGzB+v1aLFk1/7w0w/xItjtjzfW/A+VKjhIxsIjTk3GhCdpogcppqysghtJkcCkzpddtWGtlvKaPR3z2k4VMKyb2hgliaPSOvu3vI+o+dWrS4ltgbUBQeJY+ldmRsIWM05kY2DfnoXXKN8yX90hOMnP5ZQ3/TNyP7tBgauG4xI+HJe31LF1GQiOiJzp7nPSn+P0/g2Vsn/uKJpGES0SL3REtET7TIPdES0RMtck969+VSo4QMrqUN455A1slUrScQ9b0t9wT8xuZrPfG7kzOHe+L3WWy31hPfr39byT3RIvdES0RP/FYpa7Se+FXve4N7AiPr/6H1BFbNX889gQM7dmk9gQuPVvQtnXsiEdETiMlZTVald0VPGGMaWUFBgUYz3m4QFX7m+bF347fR470G7cAzm8PJtDNC54mkYRDTGUiqhWdgV9hJUj15ymCPvhFZf+UCcb+HkFrfhEFCewOpI55A6mV7UteMZ3DoVDDZKCIho3g2R4FMbi/nhJHplkmckEJ1QJtKimwZ15KZbaJ2MDLb7cNHJ7PLodrpyNy8mM9P5kYL+ILEwWYEo2dAByOTyQp0a95Exp1ncfQGsVGM08LwDbNWMh7xDr7uMZPR0PQR6Dy7kIYaqNHpzTRG8g8V6Gi4g4xqPTkKmLsmkxOG2c8cOMEsX090kHcwPBY2CUeZzsOMmxPR/pEXw6OTJqBdnTkekQUiC/6NYXpRBKrNr2C6tw1azKkR8MDsZ1Cv+oJhanMs1EzegSmHB0Nlz06GycEboCR7Fyb+kgKFGYsYJvz7DOQdcsX42qFwvNqV4b4xcyHnZ1fc+ziZowDbbio4YbC5xZETiPDyhROucxist0qF/PVhECwrhCKvwwxW3L4IJV2XYOnFq1BRtppBYMk1+C56ICyeWA3fb70jSLvZR3hXHAI/PB4u0w9OqvMLl8kU4gc/M5zzF4TzNtAlCTSkq4cTLkzxD8Xdzwv7vyDUJYnCjh854cKkRT/hFNlzQtkLQl2SKHxcxQkXZsxfRnrwkhl1SaLwaTknXJg19Trpw0tq1CWJwp6LnEg1Rr1KjVFSjVG9NSYvyMDlspfMqEviwumccGFCxA/o8DKhLknAlKQYTrgwvvMcDv6rMEzz7AWhLknABNrKCRceWXwUb72sRl2SuNTuIk648LDnRawPf8k+6pK4cAAnUstVvkrLVUotV9kr/GZiEKY9L+z3glCXxIUhnEg1drxKjR1SjR3hfZ1j8iqdYyJ1jklv55S7/kSqteUGMj2NRtMs02j+kGm8A3bm+BRbrDg1xePLcRfkdmWtQhreCjkvXbY6DYPyQBNStadD2Vwbsn5bvEpPT3ck62/F4+1ZQdZ3KhkUD5tPavt8KDAX0SOAQZ7BPFJPHgA53h+TWjASJMLg2Mposu5SwlFYQ9ZFwxmkm80l67DRcLDSn6xdJzA4EOJPqub3IFVpQaqNqxgkF14llTISkj+PJ6uk/QJEurXAxfZEBpF6mVDnshYiu+rgvNtXDDa1P4Sz3lmwubUfnHGcxuCzG6ZQZdEK22pboEITz2B7cS6U354OOzc2cRQwtnQWlC2MY7g304YTjHtWAhWBvzOMn7YQqpYuwP37b8C5iTHi/fjLYqizrcAk47fh6uT/iDeouyc0r/LC5LrdcO/YHQEPLjVD25YWhmk2KmSWgAeWPUWbRani7Zv9X7Q+0h9TvR6jVdsshimnDdFyRCqmzJOj+fl3xcE6jFERPBCTpy3AoYGviafC8Bg8WXeB4f4lIfDgVCjGL9WDu5/6iPfyshj42acH46bEwM0PB4hrd4qB5iQjjB08B34qXs/w61Y1NDW04O6uWRwFyF97kBMGuSc2cgJZudHQbDiVwbfZ8XDdNxuOJi0RB/NgcHi7C9xKKIL0TQ+gNbNQ/OnckA13ywrgUMY9uB8uXthV2XK+RYLUI32EPwDKyw+h15ZsfbHT/PSclvQFmJZ43gsm+eFF6DlmixiIsUKPjftIvtwL3a/1iAGag+6+C0lumo1u9XJGRj8boNvyEjIqnCZivoBZ4q+g2/uZTCKY4y9D97YmhrmnrqPnGkPM8/oQx06dyfBkTg962+3BYlUy+uQsYVgaNRF9cQxWRNeg7/QQgeS1+uj3qTvTEl/HUyQ/PwHHv6UUA+c2os9Kcanf+aN3TrIYqPbAcd11JK8MwnF4qbeYsVuvStUJEuEWCLbiM4b+dfG4Ldpdo5GJx1WjObk9eWTRpHCZt/jmHCvzLWlw49De46a9rtw+SHvuKEvjMGINe0nd3UG2bz0gtdsVRnYlk8k66CQN/yGIVE4tjOxvxZJlmxGNiF5NFoCMRo6eQOZ719LId8JJUe7IaFTkF9Q/aB055AzBNpkBI8cbX+LZYfbkVD8csx+tZuRcXYj7yo6TS4AbbncPZ+TSmYlh7+yTkNHrxh/gp1c+IZcODYaucBIzfozDDc+ayWXXR7j+erUYmD4T11VkkHObDa4zWyMOGnEPP1nmSc76AzkKqO95mRMmERwQmyw2bn+Gsq5VmBOwEn6rL8NLTtMZ3Cs8go+fvAk3NyAN+uY8g4axDWQ2M1xCBlcbHpD5uQSory0gC7aLwQ8VUWT58edwXj6LrGLF+6V6vh2p8svgVBgj67h2BscPqEkdqoRDKbFkMyRZkFzuI/yJ3bJ9M27Ks+4jAjkc9MSocQ0C2fkvIRMhRNyDsf3JtPAO2V5RkeLiNUa2IWPI7G4tDduPZL5nlLhtVTNIiZEkLPqKlNGFjNTPLpPy8iNSNdZwFP+9DLHTBgbG/4uUF8oZts1yImXNLizO2EbKqnkMdw5oI2XpMHyvKJqUBb8yHLxyEimPl8OvPgkcGXTqjyPl2J3QJZ9B5tHFDLoVi8ms6TY8DTxCZuPnMvg96yEp9tdAz8xJpHAIZdDzaB+Z5rlAT2cBmWYNFvrKlEivB1sx4qyCH+TxeY3L+wICDsIO/ON+GJMI2sS6YnepNUP39hXYsaMQAwJew/uzxVO5aVkdttnIMDF5N968n8iwoMEfm0q98cfOdI4Mnxh3cUKDcuOw7v0q8Xk8wBPL9GaQyn4qZlaKNtq2B2DiFhmNqGvDmJHbxM7NDeYLkVD4c2U6Ymgm+x/agVUR"; 11 | 12 | 13 | 14 | public var gfx:GfxBytes; 15 | 16 | public function new() 17 | { 18 | super(); 19 | gfx = GfxBytes.fromString(data); 20 | } 21 | 22 | public override function render(g:Graphics) 23 | { 24 | gfx.iterate(new GfxGraphics(g)); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /samples/07-RenderToImage/RenderToImage.hx: -------------------------------------------------------------------------------- 1 | import nme.display.Sprite; 2 | import nme.display.BitmapData; 3 | import gm2d.svg.SVG2Gfx; 4 | 5 | import haxe.io.Path; 6 | 7 | class RenderToImage 8 | { 9 | static public function Usage() 10 | { 11 | neko.Lib.print("Usage RenderToImage [-w Width] [-h Height] [-ox OX] [-oy OY] file.svg outfile.png"); 12 | } 13 | 14 | static public function main() 15 | { 16 | var in_file = ""; 17 | var out_file = ""; 18 | var out_width = 32; 19 | var out_height = 32; 20 | var bmp_w:Null = null; 21 | var bmp_h:Null = null; 22 | var ox:Null = null; 23 | var oy:Null = null; 24 | var scale:Null = null; 25 | var alpha = 0xff; 26 | var bg = 0xffffff; 27 | var quality = 0.75; 28 | 29 | #if haxe3 30 | var args = Sys.args(); 31 | #elseif neko 32 | var args = neko.Sys.args(); 33 | #elseif cpp 34 | var args = cpp.Sys.args(); 35 | #end 36 | 37 | var skip = false; 38 | var i = 0; 39 | while(iVoid, showTime = false, ?inStyle:ProgressStyle ) 29 | { 30 | var panel = new Panel(inTitle); 31 | 32 | var status = statusText==null ? null : new TextLabel(statusText); 33 | if (status!=null) 34 | panel.addLabelUI("Status", status); 35 | 36 | var attribs:{ } = null; 37 | if (inStyle!=null) 38 | attribs = { progressStyle : inStyle } 39 | var progress = new ProgressBar(inMax, attribs ); 40 | panel.addLabelUI(inLabel, progress); 41 | 42 | var button:Button = null; 43 | if (inOnCancel!=null) 44 | panel.addButton( button = Button.TextButton("Cancel", inOnCancel ) ); 45 | 46 | var ipsText:TextLabel = null; 47 | var timeText:TextLabel = null; 48 | if (showTime) 49 | { 50 | if (inMax>1) 51 | { 52 | ipsText = new TextLabel("0ms" ); 53 | ipsText.getLayout().stretch(); 54 | panel.addLabelObj("Item Time:",ipsText); 55 | } 56 | 57 | timeText = new TextLabel("0:0" ); 58 | timeText.getLayout().stretch(); 59 | panel.addLabelObj("Total Time:",timeText); 60 | } 61 | 62 | 63 | panel.setSizeHint(500); 64 | 65 | return new ProgressDialog(panel.getPane(),progress, status, button, inMax, ipsText, timeText); 66 | } 67 | 68 | public function setStatus(text:String) 69 | { 70 | if (statusCtrl!=null) 71 | statusCtrl.setText(text); 72 | } 73 | 74 | public function setButton(text:String, ?onClick:Void->Void) 75 | { 76 | if (button!=null) 77 | { 78 | button.setText(text); 79 | if (onClick!=null) 80 | button.mCallback = onClick; 81 | } 82 | } 83 | 84 | public static function formatTime(t:Float) 85 | { 86 | var sec = Std.int(t); 87 | if (sec<60) 88 | return '$sec' + 's'; 89 | var min = Std.int(sec/60); 90 | sec = sec%60; 91 | var ssec = sec<10 ? '0' +sec : Std.string(sec); 92 | if (min<60) 93 | return '$min:$ssec'; 94 | var hours = Std.int(min/60); 95 | min = min%60; 96 | var smin = min<10 ? '0' +min : Std.string(min); 97 | 98 | return '$hours:$smin:$ssec'; 99 | } 100 | 101 | 102 | public function update(inValue:Float) 103 | { 104 | progress.update(inValue); 105 | 106 | var now = haxe.Timer.stamp(); 107 | var dt = now-time0; 108 | if (ipsText!=null) 109 | { 110 | var ti = dt/Math.max(inValue,1); 111 | ipsText.setText( Std.int(ti*1000) + "ms" ); 112 | } 113 | 114 | if (timeText!=null) 115 | { 116 | var frac = inValue/maxVal; 117 | if (frac>0) 118 | { 119 | var estTime = dt/frac - dt; 120 | timeText.setText( formatTime(dt) + " : " + formatTime(estTime) ); 121 | } 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /gm2d/input/LRInput.hx: -------------------------------------------------------------------------------- 1 | package gm2d.input; 2 | 3 | import gm2d.Screen; 4 | import gm2d.ui.*; 5 | import gm2d.ui.Layout; 6 | import gm2d.skin.Shape; 7 | import nme.display.*; 8 | import nme.events.*; 9 | import nme.ui.Keyboard; 10 | 11 | class LRInput extends Input 12 | { 13 | public var leftJustDown:Bool; 14 | public var rightJustDown:Bool; 15 | public var leftDown:Bool; 16 | public var rightDown:Bool; 17 | public var autoRepeatDirection:Float; 18 | public var autoKeyboard:Bool; 19 | 20 | public var onLeft:Void->Void; 21 | public var onRight:Void->Void; 22 | 23 | var leftButton:Widget; 24 | var rightButton:Widget; 25 | 26 | public function new(inAutoKeyboard=true ) 27 | { 28 | super(); 29 | autoRepeatDirection = 0.0; 30 | autoKeyboard = inAutoKeyboard; 31 | controlLayout = createButtons(); 32 | } 33 | 34 | function onLeftDown() 35 | { 36 | leftJustDown = true; 37 | if (onLeft!=null) 38 | onLeft(); 39 | } 40 | 41 | function onRightDown() 42 | { 43 | rightJustDown = true; 44 | if (onRight!=null) 45 | onRight(); 46 | } 47 | 48 | 49 | public function createButtons() 50 | { 51 | var layout = new StackLayout(); 52 | 53 | var s = gm2d.skin.Skin.dpiScale; 54 | var rad = s * 30; 55 | 56 | var d = new Sprite(); 57 | var gfx = d.graphics; 58 | gfx.lineStyle(s*2,0xff0000); 59 | gfx.beginFill(0xff0000,0.5); 60 | gfx.drawCircle(rad,rad,rad); 61 | leftButton = new Button(d, onLeftDown, { 62 | shape:ShapeNone, 63 | itemAlign: Layout.AlignLeft | Layout.AlignBottom, 64 | onState:(s) -> leftDown = (s & Widget.DOWN)!= 0, 65 | wantsFocus : false, 66 | }); 67 | addChild(leftButton); 68 | layout.add(leftButton.getLayout().stretch()); 69 | 70 | var d = new Sprite(); 71 | var gfx = d.graphics; 72 | gfx.lineStyle(s*2,0xff0000); 73 | gfx.beginFill(0xff0000,0.5); 74 | gfx.drawCircle(rad,rad,rad); 75 | rightButton = new Button(d, onRightDown, { 76 | shape:ShapeNone, 77 | itemAlign: Layout.AlignRight | Layout.AlignBottom, 78 | onState:(s) -> rightDown = (s & Widget.DOWN)!= 0, 79 | wantsFocus : false, 80 | }); 81 | addChild(rightButton); 82 | layout.add(rightButton.getLayout().stretch()); 83 | 84 | return layout; 85 | } 86 | 87 | override public function onUpdated() 88 | { 89 | leftJustDown = false; 90 | rightJustDown = false; 91 | } 92 | 93 | public function showButtons(show:Bool) 94 | { 95 | leftButton.visible = show; 96 | rightButton.visible = show; 97 | } 98 | 99 | function onKeyDown(ev:KeyboardEvent) 100 | { 101 | if (ev.keyCode==Keyboard.LEFT) 102 | { 103 | onLeftDown(); 104 | if (autoKeyboard) 105 | showButtons(false); 106 | } 107 | else if (ev.keyCode==Keyboard.RIGHT) 108 | { 109 | onRightDown(); 110 | if (autoKeyboard) 111 | showButtons(false); 112 | } 113 | } 114 | 115 | function onKeyUp(ev:KeyboardEvent) 116 | { 117 | } 118 | 119 | function onMouseMove(m:MouseEvent) 120 | { 121 | if (autoKeyboard) 122 | showButtons(true); 123 | } 124 | 125 | override public function addEventListeners() 126 | { 127 | if (autoKeyboard) 128 | { 129 | eventStage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); 130 | eventStage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp); 131 | eventStage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); 132 | } 133 | } 134 | 135 | override public function removeEventListeners() 136 | { 137 | if (autoKeyboard) 138 | { 139 | eventStage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); 140 | eventStage.removeEventListener(KeyboardEvent.KEY_UP, onKeyUp); 141 | eventStage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); 142 | } 143 | } 144 | 145 | 146 | } 147 | 148 | 149 | -------------------------------------------------------------------------------- /gm2d/swf/Bitmap.hx: -------------------------------------------------------------------------------- 1 | package gm2d.swf; 2 | 3 | import nme.display.BitmapData; 4 | import nme.geom.Rectangle; 5 | import nme.utils.ByteArray; 6 | 7 | 8 | class Bitmap 9 | { 10 | #if flash 11 | var mLoader:flash.display.Loader; 12 | var mAlpha:ByteArray; 13 | #end 14 | 15 | var mBitmap:BitmapData; 16 | 17 | /* 18 | 1 = RGBA index 19 | 2 = 32-bit RGB 20 | fmt : 3 = RGB index 21 | 4 = 15-bit RGB 22 | 5 = 24-bit RGB 23 | */ 24 | 25 | 26 | public function new(inStream:SWFStream,inLossless:Bool,inVersion:Int) 27 | { 28 | mBitmap = null; 29 | 30 | #if flash9 31 | mLoader = null; 32 | #end 33 | 34 | if (inLossless) 35 | { 36 | var fmt = inStream.ReadByte(); 37 | var w = inStream.ReadUI16(); 38 | var h = inStream.ReadUI16(); 39 | var table_size = fmt==3 ? (inStream.ReadByte()+1) : 0; 40 | 41 | var buffer:nme.utils.ByteArray = inStream.readFlashBytes(inStream.BytesLeft()); 42 | buffer.uncompress(); 43 | 44 | if (inVersion==2) 45 | { 46 | if (fmt==4) 47 | throw("No 15-bit format in DefineBitsLossless2"); 48 | else 49 | fmt = fmt==3 ? 1 : 2; 50 | } 51 | 52 | mBitmap = new BitmapData(w,h,fmt<3); 53 | 54 | mBitmap.setPixels(new Rectangle(0,0,w,h), buffer ); 55 | 56 | //SetPixelData(buffer.getData(),fmt,table_size); 57 | } 58 | else 59 | { 60 | var buffer:ByteArray = null; 61 | var alpha:ByteArray = null; 62 | 63 | if (inVersion==2) 64 | { 65 | var size = inStream.BytesLeft(); 66 | buffer = inStream.ReadBytes(size); 67 | } 68 | else if (inVersion==3) 69 | { 70 | var size = inStream.ReadInt(); 71 | buffer = inStream.ReadBytes(size); 72 | 73 | alpha = inStream.readFlashBytes(inStream.BytesLeft()); 74 | alpha.uncompress(); 75 | } 76 | 77 | 78 | #if flash 79 | mLoader = new flash.display.Loader(); 80 | mAlpha = alpha; 81 | if (mAlpha!=null) 82 | mLoader.addEventListener(flash.events.Event.COMPLETE, AddAlpha ); 83 | mLoader.loadBytes(buffer); 84 | #else 85 | mBitmap = BitmapData.loadFromHaxeBytes(buffer,alpha); 86 | #end 87 | } 88 | 89 | } 90 | 91 | public function GetBitmap() 92 | { 93 | #if flash 94 | if (mBitmap==null && mLoader!=null) 95 | { 96 | if (mLoader.content==null) 97 | return null; 98 | //trace(mLoader.content); 99 | var bitmap:flash.display.Bitmap = untyped mLoader.content; 100 | mBitmap = bitmap.bitmapData; 101 | } 102 | #end 103 | 104 | return mBitmap; 105 | } 106 | 107 | function AddAlpha(inEvt:nme.events.Event) 108 | { 109 | #if flash 110 | var bitmap = GetBitmap(); 111 | var w = bitmap.width; 112 | var h = bitmap.height; 113 | if (Std.int(mAlpha.length) != Std.int(w*h)) 114 | throw("Alpha size mismatch"); 115 | var idx = 0; 116 | var a = mAlpha; 117 | for(y in 0...h) 118 | for(x in 0...w) 119 | bitmap.setPixel32(x,y, bitmap.getPixel(x,y) | (a[idx++]<<24) ); 120 | #end 121 | } 122 | 123 | 124 | #if flash 125 | 126 | function SetPixelData(inData:ByteArray, inFormat:Int, inTableSize:Int ) 127 | { 128 | mBitmap.lock(); 129 | var w = mBitmap.width; 130 | var h = mBitmap.height; 131 | 132 | if (inFormat==2) 133 | { 134 | for(y in 0...h) 135 | for(x in 0...w) 136 | { 137 | mBitmap.setPixel32(x,y, inData.readUnsignedInt() ); 138 | } 139 | } 140 | mBitmap.lock(); 141 | } 142 | 143 | #end 144 | 145 | 146 | } 147 | 148 | -------------------------------------------------------------------------------- /gm2d/swf/StaticText.hx: -------------------------------------------------------------------------------- 1 | package gm2d.swf; 2 | 3 | import gm2d.swf.SWFStream; 4 | import gm2d.swf.SWF; 5 | import nme.display.Graphics; 6 | 7 | import nme.geom.Rectangle; 8 | import nme.geom.Matrix; 9 | 10 | typedef TextRecord = 11 | { 12 | var mSWFFont:Font; 13 | 14 | var mOffsetX:Int; 15 | var mOffsetY:Int; 16 | var mHeight:Float; 17 | 18 | var mColour:Int; 19 | var mAlpha:Float; 20 | 21 | var mGlyphs:Array; 22 | var mAdvances:Array; 23 | } 24 | 25 | typedef TextRecords = Array; 26 | 27 | class StaticText 28 | { 29 | var mBounds:Rectangle; 30 | var mTextMatrix:Matrix; 31 | var mRecords:TextRecords; 32 | 33 | 34 | public function new(inSWF:SWF, inStream:SWFStream, inVersion:Int) 35 | { 36 | inStream.AlignBits(); 37 | 38 | mRecords = new TextRecords(); 39 | mBounds = inStream.ReadRect(); 40 | //trace("StaticText " + mBounds); 41 | 42 | mTextMatrix = inStream.ReadMatrix(); 43 | 44 | var glyph_bits = inStream.ReadByte(); 45 | var advance_bits = inStream.ReadByte(); 46 | var font:Font = null; 47 | var height = 32.0; 48 | var colour = 0; 49 | var alpha = 1.0; 50 | 51 | inStream.AlignBits(); 52 | while(inStream.ReadBool()) 53 | { 54 | inStream.Bits(3); 55 | var has_font = inStream.ReadBool(); 56 | var has_colour = inStream.ReadBool(); 57 | var has_y = inStream.ReadBool(); 58 | var has_x = inStream.ReadBool(); 59 | if (has_font) 60 | { 61 | var font_id = inStream.ReadID(); 62 | var ch = inSWF.GetCharacter(font_id); 63 | switch(ch) 64 | { 65 | case charFont(f): 66 | font = f; 67 | default: 68 | throw "Not font character"; 69 | } 70 | } 71 | else if (font==null) 72 | throw "No font - not implemented"; 73 | 74 | if (has_colour) 75 | { 76 | colour = inStream.ReadRGB(); 77 | if (inVersion>=2) 78 | alpha = inStream.ReadByte()/255.0; 79 | } 80 | 81 | var x_off = has_x ? inStream.ReadSI16() : 0; 82 | var y_off = has_y ? inStream.ReadSI16() : 0; 83 | if (has_font) 84 | height = inStream.ReadUI16() * 0.05; 85 | var count = inStream.ReadByte(); 86 | 87 | //trace("Glyphs : " + count); 88 | 89 | var glyphs = new Array(); 90 | var advances = new Array(); 91 | 92 | for(i in 0...count) 93 | { 94 | glyphs.push( inStream.Bits(glyph_bits) ); 95 | advances.push( inStream.Bits(advance_bits,true) ); 96 | } 97 | 98 | //trace("Using static font " + font + ":'" +glyphs.map(String.fromCharCode).join("") + "'" ); 99 | 100 | mRecords.push( { mSWFFont:font, 101 | mOffsetX : x_off, 102 | mOffsetY : y_off, 103 | mGlyphs : glyphs, 104 | mColour : colour, 105 | mAlpha : alpha, 106 | mHeight : height, 107 | mAdvances : advances } ); 108 | 109 | 110 | inStream.AlignBits(); 111 | } 112 | } 113 | 114 | public function Render(inGfx:Graphics) 115 | { 116 | for(rec in mRecords) 117 | { 118 | var scale = rec.mHeight/1024; 119 | var m = mTextMatrix.clone(); 120 | m.scale(scale,scale); 121 | m.tx += rec.mOffsetX * 0.05; 122 | m.ty += rec.mOffsetY * 0.05; 123 | inGfx.lineStyle(); 124 | for(i in 0...rec.mGlyphs.length) 125 | { 126 | var tx = m.tx; 127 | inGfx.beginFill(rec.mColour,rec.mAlpha); 128 | rec.mSWFFont.RenderGlyph(inGfx,rec.mGlyphs[i], m ); 129 | inGfx.endFill(); 130 | m.tx += rec.mAdvances[i] * 0.05; 131 | } 132 | } 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /samples/05-BitmapFont/READ_ME.TXT: -------------------------------------------------------------------------------- 1 | The fonts contained in this archive are Freeware. 2 | No payment is required for the use of these fonts. They're free! 3 | Commercial use? Sure, but a donation or a product sample would be 4 | appreciated. 5 | 6 | $40 US is the usual amount per font for commercial use but any amount is appreciated. 7 | 8 | I make all the fonts (around 360 of them) on my web page and they're all free. 9 | I offer Deluxe versions of some of my fonts for sale. They contain several 10 | weights and styles of each font. Just click on the Deluxe button at Larabie Fonts to see them. 11 | 12 | The page is called Larabie Fonts 13 | It can be found at various mirror sites. 14 | 15 | try: 16 | http://www.larabiefonts.com 17 | http://uk.zarcrom.com/font/ 18 | http://swankarmy.net/larabiefonts/ 19 | http://come.to/larabiefonts 20 | 21 | I've provided the world with about 360 free fonts, 22 | so if you'd like to make a donation I'd be more than happy to accept it. 23 | 24 | No donation is too small! Music and artwork are good too. 25 | If you have some CD's you're not listening to anymore, send 'em along! 26 | 27 | Send anything at all to 28 | 29 | Ray Larabie 30 | 61 Wesley Ave. 31 | Port Credit 32 | Ontario, CANADA 33 | L5H 2M8 34 | 35 | If you decide to send a cheque (that's how we spell it in Canada) 36 | make it payable to Ray Larabie. If you want to double check the address 37 | have a look at the donation section on any of my webpages. 38 | 39 | Canadian or US funds? Any funds are fine with me. 40 | Whatever's easy for you. 41 | 42 | 43 | Ray Larabie 44 | drowsy@cheerful.com 45 | or... 46 | rlarabie@hotmail.com 47 | 48 | ------------------------------- 49 | Larabie Fonts End-user license agreement software product from Larabie Fonts 50 | --------------------------------------------------- 51 | 52 | SOFTWARE PRODUCT LICENSE 53 | 54 | The SOFTWARE PRODUCT is protected by copyright laws and international copyright treaties, 55 | as well as other intellectual property laws and treaties. The SOFTWARE PRODUCT is licensed, 56 | not sold. 57 | 58 | 1. GRANT OF LICENSE. This document grants you the following rights: 59 | 60 | - Installation and Use. You may install and use an unlimited number of copies of the 61 | SOFTWARE PRODUCT. 62 | 63 | - Reproduction and Distribution. You may reproduce and distribute an unlimited number of 64 | copies of the SOFTWARE PRODUCT; provided that each copy shall be a true and complete copy, 65 | including all copyright and trademark notices (if applicable) , and shall be accompanied by 66 | a copy of this text file. Copies of the SOFTWARE PRODUCT may not be distributed for profit 67 | either on a standalone basis or included as part of your own product unless by prior 68 | permission of Larabie Fonts. 69 | 70 | 2. DESCRIPTION OF OTHER RIGHTS AND LIMITATIONS. 71 | 72 | - Restrictions on Alteration. You may not rename, edit or create any derivative works from 73 | the SOFTWARE PRODUCT, other than subsetting when embedding them in documents unless you have 74 | permission from Larabie Fonts. 75 | 76 | LIMITED WARRANTY 77 | NO WARRANTIES. Larabie Fonts expressly disclaims any warranty for the SOFTWARE PRODUCT. The 78 | SOFTWARE PRODUCT and any related documentation is provided "as is" without warranty of any 79 | kind, either express or implied, including, without limitation, the implied warranties or 80 | merchantability, fitness for a particular purpose, or noninfringement. The entire risk 81 | arising out of use or performance of the SOFTWARE PRODUCT remains with you. 82 | 83 | NO LIABILITY FOR CONSEQUENTIAL DAMAGES. In no event shall Larabie Fonts be liable for any 84 | damages whatsoever (including, without limitation, damages for loss of business profits, 85 | business interruption, loss of business information, or any other pecuniary loss) arising 86 | out of the use of or inability to use this product, even if Larabie Fonts has been advised 87 | of the possibility of such damages. 88 | 89 | 3. MISCELLANEOUS 90 | 91 | Should you have any questions concerning this document, or if you desire to contact 92 | Larabie Fonts for any reason, please contact rlarabie@hotmail.com , or write: Ray Larabie, 93 | 61 Wesley Ave. Mississauga, ON Canada L5H 2M8 -------------------------------------------------------------------------------- /gm2d/swf/EditText.hx: -------------------------------------------------------------------------------- 1 | package gm2d.swf; 2 | 3 | import nme.geom.Rectangle; 4 | import nme.text.TextField; 5 | import nme.text.TextFieldType; 6 | import nme.text.TextFormat; 7 | import nme.text.TextFieldAutoSize; 8 | 9 | import gm2d.swf.SWF; 10 | import gm2d.swf.SWFStream; 11 | 12 | class EditText 13 | { 14 | var mRect:Rectangle; 15 | var mWordWrap:Bool; 16 | var mMultiLine:Bool; 17 | var mPassword:Bool; 18 | var mReadOnly:Bool; 19 | var mAutoSize:Bool; 20 | var mNoSelect:Bool; 21 | var mBorder:Bool; 22 | var mWasStatic:Bool; 23 | var mHTML:Bool; 24 | var mUseOutlines:Bool; 25 | var mAlpha:Float; 26 | var mMaxLen:Int; 27 | var mInitialText:String; 28 | var mTextFormat:TextFormat; 29 | 30 | public function new(inSWF:SWF,inStream:SWFStream, inVersion:Int) 31 | { 32 | mRect = inStream.ReadRect(); 33 | mTextFormat = new TextFormat(); 34 | inStream.AlignBits(); 35 | //trace(mRect); 36 | var has_text = inStream.ReadBool(); 37 | mWordWrap = inStream.ReadBool(); 38 | mMultiLine = inStream.ReadBool(); 39 | //trace(mMultiLine); 40 | mPassword = inStream.ReadBool(); 41 | mReadOnly = inStream.ReadBool(); 42 | var has_colour = inStream.ReadBool(); 43 | //trace(has_colour); 44 | var has_max_len = inStream.ReadBool(); 45 | //trace(has_max_len); 46 | var has_font = inStream.ReadBool(); 47 | //trace("has font:" + has_font); 48 | var has_font_class = inStream.ReadBool(); 49 | //trace("has font class:" + has_font_class); 50 | mAutoSize = inStream.ReadBool(); 51 | var has_layout = inStream.ReadBool(); 52 | mNoSelect = inStream.ReadBool(); 53 | mBorder = inStream.ReadBool(); 54 | mWasStatic = inStream.ReadBool(); 55 | mHTML = inStream.ReadBool(); 56 | mUseOutlines = inStream.ReadBool(); 57 | //trace("Use outlines:" + mUseOutlines); 58 | 59 | if (has_font) 60 | { 61 | var font_id = inStream.ReadID(); 62 | switch(inSWF.GetCharacter(font_id)) 63 | { 64 | case charFont(font): 65 | mTextFormat.font = font.GetName(); 66 | //trace("Font :" + mFont.GetName()); 67 | default: 68 | throw("Specified font is incorrect type"); 69 | } 70 | mTextFormat.size = inStream.ReadUTwips(); 71 | } 72 | else if (has_font_class) 73 | { 74 | var font_name = inStream.ReadString(); 75 | throw("Can't reference external font :" + font_name); 76 | } 77 | 78 | if (has_colour) 79 | { 80 | mTextFormat.color = inStream.ReadRGB(); 81 | mAlpha = inStream.ReadByte() / 255.0; 82 | } 83 | 84 | mMaxLen = has_max_len ? inStream.ReadUI16() : 0; 85 | //trace("MaxLen : " + mMaxLen ); 86 | if (has_layout) 87 | { 88 | mTextFormat.align = inStream.ReadAlign(); 89 | mTextFormat.leftMargin = inStream.ReadUTwips(); 90 | mTextFormat.rightMargin = inStream.ReadUTwips(); 91 | mTextFormat.indent = inStream.ReadUTwips(); 92 | mTextFormat.leading = inStream.ReadSTwips(); 93 | } 94 | 95 | var var_name = inStream.ReadString(); 96 | mInitialText = has_text ? inStream.ReadString() : ""; 97 | } 98 | 99 | public function Apply(inText:TextField) 100 | { 101 | inText.wordWrap = mWordWrap; 102 | inText.multiline = mMultiLine; 103 | inText.width = mRect.width; 104 | inText.height = mRect.height; 105 | inText.displayAsPassword = mPassword; 106 | if (mMaxLen > 0) 107 | inText.maxChars = mMaxLen; 108 | inText.border = mBorder; 109 | inText.borderColor = 0x000000; 110 | inText.type = mReadOnly ? TextFieldType.DYNAMIC : TextFieldType.INPUT; 111 | inText.autoSize = mAutoSize ? TextFieldAutoSize.CENTER : TextFieldAutoSize.NONE; 112 | inText.setTextFormat(mTextFormat); 113 | 114 | 115 | //inText.embedFonts = mUseOutlines; 116 | 117 | 118 | if (mHTML) 119 | inText.htmlText = mInitialText; 120 | else 121 | inText.text = mInitialText; 122 | 123 | // if (!mReadOnly) inText.stage.focus = inText; 124 | } 125 | 126 | 127 | 128 | } 129 | -------------------------------------------------------------------------------- /gm2d/Screen.hx: -------------------------------------------------------------------------------- 1 | package gm2d; 2 | 3 | import gm2d.Game; 4 | import gm2d.ui.Dialog; 5 | import gm2d.ui.Widget; 6 | import gm2d.ui.Layout; 7 | import nme.events.MouseEvent; 8 | import nme.events.KeyboardEvent; 9 | import nme.ui.Keyboard; 10 | import gm2d.tween.Timeline; 11 | import gm2d.input.Input; 12 | import gm2d.skin.Skin; 13 | 14 | class Screen extends gm2d.ui.Window 15 | { 16 | var mPaused:Bool; 17 | public var timeline(default,null):Timeline; 18 | public var controller(default,set):Input; 19 | 20 | 21 | public function new(?inSkin:Skin, ?inLineage:Array, ?inAttribs:Dynamic ) 22 | { 23 | Game.create(); 24 | mPaused = false; 25 | timeline = new Timeline(); 26 | super(inSkin,Widget.addLine(inLineage,"Screen"),inAttribs); 27 | } 28 | 29 | public function makeCurrent() 30 | { 31 | applyStyles(); 32 | Game.setCurrentScreen(this); 33 | relayout(); 34 | } 35 | 36 | public function screenLayout(w:Int, h:Int) 37 | { 38 | if (controller!=null) 39 | controller.layout(w,h); 40 | } 41 | 42 | override public function relayout() 43 | { 44 | super.relayout(); 45 | if (stage!=null) 46 | { 47 | screenLayout( stage.stageWidth, stage.stageHeight ); 48 | } 49 | } 50 | 51 | public function set_controller(inController:Input) 52 | { 53 | if (controller!=null) 54 | { 55 | removeChild(controller); 56 | if (Game.screen==this) 57 | { 58 | controller.onActivate(this,false); 59 | controller.setRunning(false); 60 | } 61 | } 62 | 63 | controller = inController; 64 | 65 | if (controller!=null) 66 | { 67 | addChild(controller); 68 | if (Game.screen==this) 69 | { 70 | controller.setRunning(true); 71 | controller.onActivate(this,true); 72 | } 73 | } 74 | return inController; 75 | } 76 | 77 | 78 | public function setRunning(inRun:Bool) 79 | { 80 | mPaused = !inRun; 81 | setActive(inRun); 82 | } 83 | public function isPaused() { return mPaused; } 84 | 85 | public function onActivate(inActive:Bool) 86 | { 87 | if (controller!=null) 88 | controller.onActivate(this,inActive); 89 | } 90 | public function getUpdateFrequency() { return 0.0; } 91 | public function onUpdated() 92 | { 93 | if (controller!=null) 94 | controller.onUpdated(); 95 | } 96 | public function updateTimeline(inDT:Float) 97 | { 98 | if (!mPaused) 99 | timeline.update(inDT); 100 | } 101 | public function updateDelta(inDT:Float) { } 102 | public function updateFixed() { } 103 | public function render(inFraction:Float) { } 104 | public function wantsCursor() : Bool { return true; } 105 | public function goBack() : Bool 106 | { 107 | if (!Game.popScreen()) 108 | Game.close(); 109 | return true; 110 | } 111 | public function getTime() : Float 112 | { 113 | if (timeline==null) 114 | return 0.0; 115 | return timeline.time; 116 | } 117 | public function closeIfDialog() { } 118 | 119 | public function getScaleMode() : ScreenScaleMode { return ScreenScaleMode.TOPLEFT_UNSCALED; } 120 | 121 | function setScreen(inName:String) { return Game.setScreen(inName); } 122 | function showDialog(inName:String) { Game.showDialog(inName); } 123 | 124 | function isDown(inCode:Int) { return Game.isDown(inCode); } 125 | 126 | public function onStageActivate(inActive:Bool) 127 | { 128 | } 129 | 130 | override public function setItemLayout(inLayout:Layout) 131 | { 132 | var layout = super.setItemLayout(inLayout); 133 | mLayout.setMinSize(Game.screenWidth, Game.screenHeight); 134 | mLayout.stretch(); 135 | return layout; 136 | } 137 | 138 | 139 | public function scaleScreen(inScale:Float) 140 | { 141 | if (mLayout!=null) 142 | { 143 | mLayout.setMinSize(Game.screenWidth, Game.screenHeight); 144 | mLayout.setRect(0,0, Game.screenWidth, Game.screenHeight ); 145 | } 146 | if (stage!=null) 147 | screenLayout( stage.stageWidth, stage.stageHeight ); 148 | } 149 | 150 | 151 | 152 | 153 | } 154 | 155 | 156 | -------------------------------------------------------------------------------- /gm2d/ui/MultiTouchButton.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | 3 | import gm2d.svg.BitmapDataManager; 4 | import gm2d.reso.Resources; 5 | import gm2d.svg.SvgRenderer; 6 | 7 | import nme.display.Sprite; 8 | import nme.events.MouseEvent; 9 | import nme.events.TouchEvent; 10 | import nme.display.Bitmap; 11 | import nme.display.BitmapData; 12 | 13 | 14 | class MultiTouchButton extends Sprite 15 | { 16 | public var w:Float; 17 | public var h:Float; 18 | var up:Bitmap; 19 | var down:Bitmap; 20 | var isDown:Bool; 21 | var onChange:Bool->Void; 22 | var mFilename:String; 23 | var mDownTime:Float; 24 | var minDownMS:Int; 25 | var mScale:Float; 26 | var mSeparateUpDown:Bool; 27 | 28 | public function new(inFilename:String,inSeparateUpDown:Bool,inScale:Float,inOnChange:Bool->Void) 29 | { 30 | super(); 31 | onChange = null; 32 | #if !flash 33 | nme.ui.Multitouch.inputMode = nme.ui.MultitouchInputMode.TOUCH_POINT; 34 | var addMouseListeners = !nme.ui.Multitouch.supportsTouchEvents; 35 | #else 36 | var addMouseListeners = true; 37 | #end 38 | 39 | mFilename = inFilename; 40 | mSeparateUpDown = inSeparateUpDown; 41 | up = new Bitmap(); 42 | down = new Bitmap(); 43 | mScale = 0.0; 44 | if (inScale>0) 45 | scale(inScale); 46 | 47 | mDownTime = 0; 48 | minDownMS = 0; 49 | 50 | addChild(up); 51 | addChild(down); 52 | down.visible = true; 53 | isDown = true; 54 | setState(false); 55 | var me = this; 56 | 57 | if (addMouseListeners) 58 | { 59 | addEventListener(MouseEvent.MOUSE_DOWN, function(_) me.setState(true) ); 60 | addEventListener(MouseEvent.MOUSE_UP, function(_) me.setState(false) ); 61 | addEventListener(MouseEvent.ROLL_OUT, function(_) me.setState(false) ); 62 | } 63 | 64 | #if !flash 65 | addEventListener(TouchEvent.TOUCH_END, function(_) me.setState(false) ); 66 | addEventListener(TouchEvent.TOUCH_BEGIN, function(_) me.setState(true) ); 67 | addEventListener(TouchEvent.TOUCH_OVER, function(_) me.setState(true) ); 68 | addEventListener(TouchEvent.TOUCH_OUT, function(_) me.setState(false) ); 69 | #end 70 | onChange = inOnChange; 71 | } 72 | 73 | public function scale(inScale:Float) 74 | { 75 | mScale = inScale; 76 | BitmapDataManager.setCacheScale(inScale); 77 | if (mFilename!="") 78 | { 79 | var svg:SvgRenderer = new SvgRenderer(Resources.loadSvg(mFilename)); 80 | if (mSeparateUpDown) 81 | { 82 | up.bitmapData = BitmapDataManager.create(mFilename,"up",inScale); 83 | down.bitmapData = BitmapDataManager.create(mFilename,"down",inScale); 84 | w = up.width; 85 | h = up.height; 86 | down.x = 0; 87 | down.y = 0; 88 | } 89 | else 90 | { 91 | up.bitmapData = BitmapDataManager.create(mFilename,"",inScale, true); 92 | down.bitmapData = BitmapDataManager.create(mFilename,"",inScale*0.8, true); 93 | w = up.width; 94 | h = up.height; 95 | down.x = (w-down.width)*0.5; 96 | down.y = (h-down.height)*0.5; 97 | } 98 | } 99 | } 100 | 101 | public function setGraphicsSource(inFilename:String) 102 | { 103 | mFilename = inFilename; 104 | scale(mScale); 105 | } 106 | 107 | function fakeUp() 108 | { 109 | if (isDown) 110 | { 111 | trace(" fake up"); 112 | setState(false); 113 | } 114 | else 115 | { 116 | trace("Skip fake up"); 117 | } 118 | } 119 | 120 | public function setState(inDown:Bool) 121 | { 122 | if (inDown!=isDown) 123 | { 124 | var now:Float = haxe.Timer.stamp(); 125 | if (inDown) 126 | mDownTime = now; 127 | else 128 | { 129 | var been = Std.int( (now-mDownTime) * 1000 ); 130 | if (been < minDownMS) 131 | { 132 | trace("Only been : " + been); 133 | haxe.Timer.delay( fakeUp, minDownMS-been ); 134 | return; 135 | } 136 | } 137 | 138 | isDown = inDown; 139 | up.visible = !isDown; 140 | down.visible = isDown; 141 | //trace("Down.visible " + down.visible ); 142 | if (onChange!=null) 143 | onChange(isDown); 144 | } 145 | } 146 | } 147 | 148 | 149 | -------------------------------------------------------------------------------- /samples/10-Wwx2014/Particles.hx: -------------------------------------------------------------------------------- 1 | import nme.geom.Point; 2 | import nme.geom.Rectangle; 3 | import nme.display.Sprite; 4 | import nme.display.DisplayObject; 5 | import nme.display.BitmapData; 6 | import gm2d.blit.Tile; 7 | import gm2d.blit.Tilesheet; 8 | import nme.Assets; 9 | 10 | class Particle 11 | { 12 | public var x:Float; 13 | public var y:Float; 14 | public var dx:Float; 15 | public var dy:Float; 16 | public var phase:Float; 17 | public var dphase:Float; 18 | public var tile:Int; 19 | 20 | public static var GRAVITY_X = 0.0; 21 | public static var GRAVITY_Y = -9.8; 22 | 23 | public function new(inP:Point) 24 | { 25 | x = inP.x; 26 | y = inP.y; 27 | phase = 0; 28 | dphase = Rand(0.5,2.5); 29 | var theta = Rand(0,Math.PI*2.0); 30 | var vel = Rand(5,10); 31 | dx = Math.cos(theta)*vel; 32 | dy = Math.sin(theta)*vel; 33 | tile = 0; 34 | } 35 | public function move(inDT:Float):Bool 36 | { 37 | phase += dphase*inDT; 38 | tile = Std.int(phase); 39 | if (tile>=4) 40 | return false; 41 | x+=dx*inDT; 42 | y+=dy*inDT; 43 | if (phase<2) 44 | { 45 | dx += GRAVITY_X*inDT; 46 | dy += GRAVITY_Y*inDT; 47 | } 48 | 49 | return true; 50 | } 51 | public function pushTo(outData:Array) 52 | { 53 | outData.push(x); 54 | outData.push(y); 55 | outData.push(tile); 56 | } 57 | 58 | function Rand(inR0:Float, inR1:Float) 59 | { 60 | return inR0 + Math.random()*(inR1-inR0); 61 | } 62 | } 63 | 64 | 65 | class Particles extends Sprite 66 | { 67 | var mTiles:Array; 68 | var mTilesheet:Tilesheet; 69 | var mParticles:Array; 70 | var mSeeds:Array; 71 | var mViewport:gm2d.blit.Viewport; 72 | var mParticleLayer:gm2d.blit.Layer; 73 | 74 | public function new(inWidth:Int, inHeight:Int) 75 | { 76 | super(); 77 | mParticles = []; 78 | mSeeds = []; 79 | 80 | var bmp = Assets.getBitmapData("Blobs.png"); 81 | mTilesheet = new Tilesheet(bmp); 82 | mTiles = mTilesheet.partition(16,16); 83 | for(tile in mTiles) 84 | tile.hotX = tile.hotY = 0; 85 | 86 | mViewport = gm2d.blit.Viewport.create(inWidth, inHeight, gm2d.blit.Viewport.BG_DONT_CARE, 0x000000); 87 | addChild(mViewport); 88 | 89 | mParticleLayer = mViewport.createLayer(); 90 | mParticleLayer.dynamicRender = renderParticles; 91 | mParticleLayer.blendAdd = true; 92 | 93 | } 94 | 95 | public function setDisplaySource(inObj:DisplayObject) 96 | { 97 | mSeeds = []; 98 | var x0 = inObj.x; 99 | var y0 = inObj.y; 100 | var w = Std.int(inObj.width); 101 | var h = Std.int(inObj.height); 102 | var bmp = new BitmapData(w,h,false,0xffffff); 103 | bmp.draw(inObj); 104 | var pixels = bmp.getPixels(new Rectangle(0,0,w,h) ); 105 | pixels.position = 0; 106 | for(y in 0...h) 107 | for(x in 0...w) 108 | if ( (pixels.readInt() & 0x0000ff) < 128 ) 109 | mSeeds.push( new Point(x+x0, y+y0) ); 110 | } 111 | 112 | function renderParticles(inX,inY) 113 | { 114 | mParticleLayer.clear(); 115 | for(particle in mParticles) 116 | mParticleLayer.drawTile(mTiles[particle.tile], particle.x, particle.y ); 117 | } 118 | 119 | 120 | public function update() 121 | { 122 | var alive = new Array(); 123 | 124 | var dt = 0.020; 125 | for(p in mParticles) 126 | { 127 | if (p.move(dt)) 128 | alive.push(p); 129 | } 130 | 131 | mParticles = alive; 132 | if (mSeeds.length>0) 133 | { 134 | for(p in 0...50) 135 | mParticles.push( new Particle(mSeeds[ Std.int(Math.random() * mSeeds.length) ] ) ); 136 | } 137 | 138 | mViewport.invalidate(); 139 | 140 | /* 141 | var gfx = graphics; 142 | gfx.clear(); 143 | 144 | var n = mParticles.length; 145 | if (n>0) 146 | { 147 | var data = new Array(); 148 | for(particle in mParticles) 149 | particle.pushTo(data); 150 | mTilesheet.drawTiles(gfx, data, false, nme.display.Graphics.TILE_BLEND_ADD); 151 | } 152 | */ 153 | } 154 | } 155 | 156 | -------------------------------------------------------------------------------- /gm2d/ui/Toolbar.hx: -------------------------------------------------------------------------------- 1 | package gm2d.ui; 2 | import nme.display.Sprite; 3 | import nme.display.BitmapData; 4 | import nme.display.DisplayObject; 5 | import gm2d.ui.DockPosition; 6 | import nme.geom.Rectangle; 7 | 8 | import gm2d.ui.Pane; 9 | 10 | /* 11 | class ToolbarItem 12 | { 13 | public function new(inWin:Widget, inWidth:Float, inHeight:Float) 14 | { 15 | win = inWin; 16 | w = inWidth; 17 | h = inHeight; 18 | } 19 | public var win:Widget; 20 | public var w:Float; 21 | public var h:Float; 22 | } 23 | */ 24 | 25 | class Toolbar extends Pane 26 | { 27 | var root:Sprite; 28 | var items:Array; 29 | public var padX:Float; 30 | public var padY:Float; 31 | public var layoutRows:Int; 32 | 33 | public function new(inTitle:String) 34 | { 35 | root = new Sprite(); 36 | items = new Array(); 37 | padX = 2.0; 38 | padY = 2.0; 39 | super(root, inTitle, Dock.RESIZABLE | Dock.TOOLBAR ); 40 | getLayout().setAlignment( Layout.AlignTop | Layout.AlignLeft ); 41 | getLayout().onLayout = setRect; 42 | } 43 | 44 | public function addTool(inTool:Widget) 45 | { 46 | root.addChild(inTool); 47 | items.push(inTool); 48 | } 49 | public function getRoot() { return root; } 50 | 51 | public function layout(inW:Float, inDoMove:Bool) 52 | { 53 | var max = inW-padX; 54 | var x = padX; 55 | var y = padY; 56 | var row_height = 0.0; 57 | var maxX = 0.0; 58 | layoutRows = 1; 59 | for(item in items) 60 | { 61 | var size = item.getLayout().getBestSize(); 62 | var w = size.x; 63 | var h = size.y; 64 | if (row_height>0 && x+w>max) 65 | { 66 | y+=row_height + padY*2; 67 | x = padX; 68 | row_height = 0; 69 | layoutRows++; 70 | } 71 | if (inDoMove) 72 | item.getLayout().setRect(x,y,w,h); 73 | if (h>row_height) 74 | row_height = h; 75 | x+=w+padX; 76 | if (x>maxX) 77 | maxX = x; 78 | x+=padX; 79 | } 80 | setBestSize(maxX,y+row_height+padY); 81 | } 82 | 83 | override public function isLocked():Bool { return true; } 84 | 85 | 86 | /* 87 | override public function getMinSize():Size 88 | { 89 | return new Size(bestWidth,bestHeight); 90 | } 91 | 92 | override public function getBestSize(inSlot:Int):Size 93 | { 94 | if (bestSize[inSlot]==null) 95 | { 96 | if (inSlot==Dock.DOCK_SLOT_VERT) 97 | layout(10000,false); 98 | else 99 | layout(1,false); 100 | 101 | bestSize[inSlot] = new Size(bestWidth, bestHeight); 102 | } 103 | return bestSize[inSlot].clone(); 104 | } 105 | */ 106 | 107 | 108 | override public function getLayoutSize(w:Float,h:Float,inLimitX:Bool):Size 109 | { 110 | if (inLimitX) 111 | layout(w,false); 112 | else 113 | { 114 | // Calculate minimum width while keeping height <= h 115 | 116 | // Start with 1 column... 117 | var minWidth = 0.0; 118 | for(item in items) 119 | { 120 | var w = getLayout().getBestSize().x; 121 | if (w>minWidth) 122 | minWidth = w; 123 | } 124 | 125 | var tryWidth = minWidth; 126 | layout(tryWidth,false); 127 | while(getLayout().getBestSize().y>h && layoutRows>1) 128 | { 129 | tryWidth += minWidth; 130 | layout(tryWidth,false); 131 | } 132 | 133 | //trace("Find " + h + " = " + bestHeight + " -> width " + bestWidth ); 134 | } 135 | return getLayout().getBestSize(); 136 | //return new Size(bestWidth,bestHeight); 137 | } 138 | 139 | public function setRect(x:Float,y:Float,w:Float,h:Float):Void 140 | { 141 | // todo:set best size... 142 | layout(w,true); 143 | 144 | /* 145 | if (dock!=null) 146 | { 147 | var slot = dock.getSlot(); 148 | bestSize[slot] = getLayout().getBestSize(); 149 | } 150 | if (displayObject!=null) 151 | { 152 | displayObject.x = x; 153 | displayObject.y = y; 154 | displayObject.scrollRect = new Rectangle(scrollX,scrollY,w,h); 155 | } 156 | */ 157 | } 158 | } 159 | 160 | 161 | --------------------------------------------------------------------------------