diff --git a/CHANGELOG.md b/CHANGELOG.md index ac4744f..ea27a80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [1.0.1] +- more null safety migrations. +- experimental GDropShadowFilter.innerShadow (hurts performance). +- add SceneBuilderWidget.autoSize to auto expand the scene on the parent widget. +- fix bug with GText in `LayoutUtils.row`. +- fix `EventSignal` bug, remove() callbacks while dispatching them. +- prevents assigning `NaN` to GDisplayObject transform properties based on `double`. +- some minor fixes and forced non-nullable properties. + ## [1.0.0-nullsafety.0] - initial migration to null-safety - fix non-working examples. diff --git a/README.md b/README.md index db81ac5..229ea96 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ To get some extended, boring explanations, and eventually some sample codes, che #### news! -- WIP Support for [null-safety](https://github.com/roipeker/graphx/tree/null-safety) +- Support for [null-safety](https://github.com/roipeker/graphx/tree/null-safety) - Support for HotReload diff --git a/example/lib/demos/breakout/scene/data.dart b/example/lib/demos/breakout/scene/data.dart index 87d6a5d..d2b6e26 100644 --- a/example/lib/demos/breakout/scene/data.dart +++ b/example/lib/demos/breakout/scene/data.dart @@ -23,4 +23,4 @@ const kColorMap = { 3: Colors.orange, 2: Colors.green, 1: Colors.yellow, -}; \ No newline at end of file +}; diff --git a/example/lib/demos/demos.dart b/example/lib/demos/demos.dart index a4781a8..7529898 100644 --- a/example/lib/demos/demos.dart +++ b/example/lib/demos/demos.dart @@ -30,7 +30,6 @@ export 'murat_coffee/murat_coffee.dart'; export 'nico_loading_indicator/nico_loading_indicator.dart'; export 'nokia_snake/nokia_snake.dart'; export 'page_indicator/page_indicator.dart'; -export 'path_chart_stress/path_chart_stress.dart'; export 'pie_chart/pie_chart.dart'; export 'pizza_box/pizza_box.dart'; export 'raster_draw/raster_draw.dart'; diff --git a/example/lib/demos/drawing_pad_bezier/drawing_pad/bezier.dart b/example/lib/demos/drawing_pad_bezier/drawing_pad/bezier.dart index 2d56811..856ad66 100644 --- a/example/lib/demos/drawing_pad_bezier/drawing_pad/bezier.dart +++ b/example/lib/demos/drawing_pad_bezier/drawing_pad/bezier.dart @@ -4,15 +4,12 @@ import 'point.dart'; class BezierDraw { static BezierDraw fromPoints(List points, double w1, double w2) { - var c2 = - BezierDraw.controlPoints(points[0], points[1], points[2])[1]; - var c3 = - BezierDraw.controlPoints(points[1], points[2], points[3])[0]; + var c2 = BezierDraw.controlPoints(points[0], points[1], points[2])[1]; + var c3 = BezierDraw.controlPoints(points[1], points[2], points[3])[0]; return BezierDraw(points[1], c2, c3, points[2], w1, w2); } - static List controlPoints( - PadPoint s1, PadPoint s2, PadPoint s3) { + static List controlPoints(PadPoint s1, PadPoint s2, PadPoint s3) { final dx1 = s1.x - s2.x; final dy1 = s1.y - s2.y; final dx2 = s2.x - s3.x; diff --git a/example/lib/demos/drawing_pad_bezier/drawing_pad_bezier.dart b/example/lib/demos/drawing_pad_bezier/drawing_pad_bezier.dart index 05b14c8..c2ec254 100644 --- a/example/lib/demos/drawing_pad_bezier/drawing_pad_bezier.dart +++ b/example/lib/demos/drawing_pad_bezier/drawing_pad_bezier.dart @@ -14,9 +14,7 @@ class DrawingPadBezierMain extends StatelessWidget { children: [ SceneBuilderWidget( builder: () => SceneController( - back: DrawPadScene(), - config: SceneConfig.tools - ), + back: DrawPadScene(), config: SceneConfig.tools), ), Positioned(left: 0, right: 0, bottom: 0, child: PadSettings()), ], diff --git a/example/lib/demos/drawing_pad_bezier/pad_settings.dart b/example/lib/demos/drawing_pad_bezier/pad_settings.dart index 05fa1f1..0dfa6e1 100644 --- a/example/lib/demos/drawing_pad_bezier/pad_settings.dart +++ b/example/lib/demos/drawing_pad_bezier/pad_settings.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:graphx/graphx.dart'; diff --git a/example/lib/demos/dripping_iv/scene/svgs.dart b/example/lib/demos/dripping_iv/scene/svgs.dart index 2886593..2702201 100644 --- a/example/lib/demos/dripping_iv/scene/svgs.dart +++ b/example/lib/demos/dripping_iv/scene/svgs.dart @@ -1,4 +1,3 @@ - const tubeSvgString = ''' diff --git a/example/lib/demos/expander_fab_menu/expander_fab_menu.dart b/example/lib/demos/expander_fab_menu/expander_fab_menu.dart index 233af38..6b5e417 100644 --- a/example/lib/demos/expander_fab_menu/expander_fab_menu.dart +++ b/example/lib/demos/expander_fab_menu/expander_fab_menu.dart @@ -138,16 +138,14 @@ class MyCoolMenuScene extends GSprite { button = MyButton(); } - void updatePosition(GRect position) { button.x = position.x + position.width / 2; buttonY = position.y + position.height / 2; - if( !isOpen ){ + if (!isOpen) { button.y = buttonY; } } - @override void addedToStage() { super.addedToStage(); @@ -159,10 +157,10 @@ class MyCoolMenuScene extends GSprite { _buildMenu(); addChild(button); - stage!.onResized.add((){ + stage!.onResized.add(() { requestPositionCallback.call(); menuContainer.setPosition(sw / 2, sh / 2); - if( isOpen ){ + if (isOpen) { _renderCurt(); } }); diff --git a/example/lib/demos/fb_reactions/fb_reactions.dart b/example/lib/demos/fb_reactions/fb_reactions.dart index b240406..fe36c2a 100644 --- a/example/lib/demos/fb_reactions/fb_reactions.dart +++ b/example/lib/demos/fb_reactions/fb_reactions.dart @@ -23,34 +23,34 @@ class FacebookReactionsMain extends StatelessWidget { appBar: AppBar( centerTitle: false, title: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 16, sigmaY: 16,), + filter: ImageFilter.blur( + sigmaX: 16, + sigmaY: 16, + ), child: Text( 'Facebook Reactions', style: TextStyle( - color: _kBlue, - fontSize: 18, - fontWeight: FontWeight.bold, + color: _kBlue, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + backgroundColor: Colors.white.withOpacity(.6), + elevation: 0, + ), + backgroundColor: Color(0xffebebeb), + body: SceneBuilderWidget( + builder: () => SceneController(front: MenuScene()), + child: Scrollbar( + child: ListView.separated( + padding: EdgeInsets.symmetric(vertical: 54, horizontal: 0), + separatorBuilder: (context, index) => const SizedBox(height: 8), + itemBuilder: (context, index) => InnerCardItem(data: posts[index]), + itemCount: posts.length, ), ), ), - backgroundColor: Colors.white.withOpacity(.6), - elevation: 0, - ), - backgroundColor: Color(0xffebebeb), - body: SceneBuilderWidget( - builder: () => SceneController(front: MenuScene()), - child: Scrollbar( - child: ListView.separated( - padding: EdgeInsets.symmetric(vertical: 54, horizontal: 0), - separatorBuilder: (context, index) => const SizedBox(height: 8), - itemBuilder: (context, index) => InnerCardItem(data: posts[index]), - itemCount: posts.length, - ) - , - ) - , - ) - , ); } } @@ -80,6 +80,7 @@ class InnerCardItem extends StatelessWidget { CircleAvatar( backgroundColor: Colors.grey.withOpacity(.3), radius: 24, + /// dev channel // foregroundImage: NetworkImage(data.profileImageUrl), child: Text(data!.username[0].toUpperCase()), diff --git a/example/lib/demos/fb_reactions/model.dart b/example/lib/demos/fb_reactions/model.dart index 5ae47af..2ac3e31 100644 --- a/example/lib/demos/fb_reactions/model.dart +++ b/example/lib/demos/fb_reactions/model.dart @@ -51,16 +51,16 @@ class PostVo { ); static PostVo random() { - var vo = PostVo._( + var vo = PostVo._( randomName(), randomTitle(), randomProfilePic(), randomImage(), randomTime(), ); - vo.numLikes=Math.randomRangeInt(2, 40); - vo.numComments=Math.randomRangeInt(1, 234); - vo.shares= '${Math.randomRangeInt(2, 500)} Shares'; + vo.numLikes = Math.randomRangeInt(2, 40); + vo.numComments = Math.randomRangeInt(1, 234); + vo.shares = '${Math.randomRangeInt(2, 500)} Shares'; return vo; } @@ -87,10 +87,10 @@ class PostVo { return 'https://randomuser.me/api/portraits/$value/$id.jpg'; } - static String randomTitle(){ + static String randomTitle() { var numWords = Math.randomRangeInt(5, 20); - var offset = Math.randomRangeInt(0, _kLoremWords.length-22); - var phrase = _kLoremWords.sublist(offset, offset+numWords).join(' '); + var offset = Math.randomRangeInt(0, _kLoremWords.length - 22); + var phrase = _kLoremWords.sublist(offset, offset + numWords).join(' '); return phrase[0].toUpperCase() + phrase.substring(1); } } @@ -101,4 +101,5 @@ Etiam nec malesuada dolor. Cras auctor malesuada lorem vitae mollis. Fusce odio Morbi fringilla lacus nunc, at blandit odio eleifend sit amet. Suspendisse scelerisque bibendum hendrerit. Duis suscipit dictum massa, pharetra fermentum sapien placerat a. Integer gravida aliquam congue. Morbi maximus in mauris eu consequat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Nullam pulvinar massa eget pellentesque feugiat. Mauris interdum, massa et consequat tempus, neque nibh convallis odio, et tempus lorem erat eu quam. Maecenas condimentum dapibus orci, quis ultricies velit. Phasellus laoreet mattis elit eu facilisis. In id blandit nisl. Mauris posuere tellus in lectus ornare varius. Vivamus nulla risus, mattis quis rutrum et, iaculis ut felis. Mauris lobortis dui vel metus dictum, eu auctor purus ullamcorper. Sed neque nulla, faucibus sed consequat in, rutrum sed felis. Suspendisse ut ligula dignissim, laoreet tellus sit amet, molestie eros. Nullam turpis tortor, rhoncus a nisi et, ornare euismod leo. Aliquam dictum, sapien et ultrices facilisis, quam orci interdum arcu, quis sodales sapien mauris non nibh. Aenean rutrum erat mi, at egestas neque vulputate a. Maecenas vel sollicitudin ipsum. Suspendisse varius tortor neque, vitae laoreet purus vulputate ut. Nulla pulvinar accumsan rhoncus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus et faucibus turpis. Duis maximus enim lacus, vitae commodo leo ultrices non. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Duis tristique quam in dolor rhoncus laoreet. Fusce malesuada sit amet augue non facilisis. Phasellus vitae molestie sapien. Duis egestas sem vitae vestibulum euismod. Nunc vulputate luctus ipsum, a aliquam eros maximus ac. Praesent sit amet luctus erat. Phasellus et eleifend ipsum, non placerat purus. Donec convallis a arcu eu aliquam. Nullam sagittis, diam ac porta sodales, purus dui aliquet nisl, nec lobortis mi ex id sapien. Pellentesque id faucibus purus, nec ultricies tortor. -'''.split(' '); +''' + .split(' '); diff --git a/example/lib/demos/feeling_switch/scene.dart b/example/lib/demos/feeling_switch/scene.dart index 856240e..e17e0a4 100644 --- a/example/lib/demos/feeling_switch/scene.dart +++ b/example/lib/demos/feeling_switch/scene.dart @@ -35,9 +35,10 @@ class FeelingSwitch extends GSprite { .endFill(); var smile = GShape(); + /// for now, we avoid saving based on object bounds, as it will /// crop the line edges. - smile.$useSaveLayerBounds = false ; + smile.$useSaveLayerBounds = false; smile.graphics.lineStyle( 3, Color(0xff71a745).withOpacity(.8), diff --git a/example/lib/demos/flower_gradient/scene.dart b/example/lib/demos/flower_gradient/scene.dart index 44d8bf2..8a7a1fa 100644 --- a/example/lib/demos/flower_gradient/scene.dart +++ b/example/lib/demos/flower_gradient/scene.dart @@ -54,15 +54,15 @@ class FlowerScene extends GSprite { GTween.delayedCall( 2, () { - for (var i = 0; i < numLines; ++i) { + for (var i = 0; i < flower.numChildren; ++i) { var j = numLines - i; - flower.children[i].tween( - duration: .6, - rotation: 0, - delay: j * .08, - // overwrite: 1, - ease: GEase.easeInBack, - ); + flower.getChildAt(i).tween( + duration: .6, + rotation: 0, + delay: j * .08, + // overwrite: 1, + ease: GEase.easeInBack, + ); } }, ); diff --git a/example/lib/demos/graphics_clipper_demo/graphics_clipper_demo.dart b/example/lib/demos/graphics_clipper_demo/graphics_clipper_demo.dart index 5d0dc17..3ea011f 100644 --- a/example/lib/demos/graphics_clipper_demo/graphics_clipper_demo.dart +++ b/example/lib/demos/graphics_clipper_demo/graphics_clipper_demo.dart @@ -47,7 +47,8 @@ class MyCurvyPath extends GraphicsClipper { final curveSize = 60.0; final targetW = size.width; final targetH = size.height; - g.moveTo(0, curveSize) + g + .moveTo(0, curveSize) .curveTo(0, 0, curveSize, 0) .lineTo(targetW - curveSize, 0) .curveTo(targetW, 0, targetW, -curveSize) diff --git a/example/lib/demos/isma_chart/scene/chart_scene.dart b/example/lib/demos/isma_chart/scene/chart_scene.dart index 14c7a52..3f0dcb8 100644 --- a/example/lib/demos/isma_chart/scene/chart_scene.dart +++ b/example/lib/demos/isma_chart/scene/chart_scene.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:graphx/graphx.dart'; diff --git a/example/lib/demos/isma_chart/widgets/orange_box.dart b/example/lib/demos/isma_chart/widgets/orange_box.dart index 2998039..97f2b54 100644 --- a/example/lib/demos/isma_chart/widgets/orange_box.dart +++ b/example/lib/demos/isma_chart/widgets/orange_box.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; class OrangeBox extends StatelessWidget { diff --git a/example/lib/demos/mouse_repulsion/scene.dart b/example/lib/demos/mouse_repulsion/scene.dart index 78d0c7c..bccf66b 100644 --- a/example/lib/demos/mouse_repulsion/scene.dart +++ b/example/lib/demos/mouse_repulsion/scene.dart @@ -75,6 +75,10 @@ class MouseRepulsionScene extends GSprite { var dy = d.y - my; var dsq = dx * dx + dy * dy; if (dsq < radiusSq) { + /// can't divide by 0 + if (dsq == 0) { + dsq = 200; + } var dist = Math.sqrt(dsq); var tx = mx + dx / dist * radius; var ty = my + dy / dist * radius; @@ -87,10 +91,7 @@ class MouseRepulsionScene extends GSprite { d.vy *= damp; d.x += d.vx; d.y += d.vy; - if (d.x.isNaN) d.x = 0; - if (d.y.isNaN) d.y = 0; } - draw(container.graphics); } @@ -125,7 +126,7 @@ class MouseRepulsionScene extends GSprite { } class GraphPoint extends GShape { - double tx = 0, ty = 0, vx = 0, vy = 0; + double tx = 0, ty = 0, vx = 0.0, vy = 0.0; GraphPoint() { mouseEnabled = false; diff --git a/example/lib/demos/nico_loading_indicator/scene.dart b/example/lib/demos/nico_loading_indicator/scene.dart index 37ef363..eca9a94 100644 --- a/example/lib/demos/nico_loading_indicator/scene.dart +++ b/example/lib/demos/nico_loading_indicator/scene.dart @@ -35,8 +35,7 @@ class CustomLoadingIndicatorSprite extends GSprite { @override void addedToStage() { - - stage!.onResized.add((){ + stage!.onResized.add(() { x = stage!.stageWidth / 2; y = stage!.stageHeight / 2; }); diff --git a/example/lib/demos/nokia_snake/game_scene.dart b/example/lib/demos/nokia_snake/game_scene.dart index d017b5e..42d32ef 100644 --- a/example/lib/demos/nokia_snake/game_scene.dart +++ b/example/lib/demos/nokia_snake/game_scene.dart @@ -207,7 +207,7 @@ class SnakeGameScene extends GSprite { } void onKeyDown(KeyboardEventData event) { - final key = event.rawEvent!.logicalKey; + final key = event.rawEvent.logicalKey; if (key == Keys.LEFT_KEY) { changeState(SnakeCommands.left); } diff --git a/example/lib/demos/nokia_snake/mobile_button_widget.dart b/example/lib/demos/nokia_snake/mobile_button_widget.dart index 666e3d9..6357aa9 100644 --- a/example/lib/demos/nokia_snake/mobile_button_widget.dart +++ b/example/lib/demos/nokia_snake/mobile_button_widget.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; diff --git a/example/lib/demos/page_indicator/scene.dart b/example/lib/demos/page_indicator/scene.dart index 4b29b73..54b45c0 100644 --- a/example/lib/demos/page_indicator/scene.dart +++ b/example/lib/demos/page_indicator/scene.dart @@ -140,6 +140,7 @@ class PageIndicatorPaged extends BaseScene { dot.tween( duration: .3, alpha: targetAlpha, + /// for a zoom in effect // scale: targetAlpha == 1 ? 1 : .25, // y: targetAlpha == 1 ? 0.0 : dotSize / 2, diff --git a/example/lib/demos/path_chart_stress/path_chart_stress.dart b/example/lib/demos/path_chart_stress/path_chart_stress.dart deleted file mode 100644 index 0d09a9f..0000000 --- a/example/lib/demos/path_chart_stress/path_chart_stress.dart +++ /dev/null @@ -1,25 +0,0 @@ -/// roipeker 2020 -/// -import 'package:flutter/material.dart'; -import 'package:graphx/graphx.dart'; - -import 'scene.dart'; - -class PathChartStressTestMain extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - centerTitle: false, - title: Text('path chart'), - elevation: 0, - backgroundColor: Colors.black26, - ), - body: Center( - child: SceneBuilderWidget( - builder: () => SceneController(front: PathChartScene()), - ), - ), - ); - } -} diff --git a/example/lib/demos/path_chart_stress/scene.dart b/example/lib/demos/path_chart_stress/scene.dart deleted file mode 100644 index 1a893ef..0000000 --- a/example/lib/demos/path_chart_stress/scene.dart +++ /dev/null @@ -1,120 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:graphx/graphx.dart'; - -class PathChartScene extends GSprite { - @override - void addedToStage() { - var colors = [ - // Colors.red, - // Colors.green, - Colors.purple, - ]; - // var colors = [Colors.red]; - - var container = GSprite(); - addChild(container); - - colors.forEach((c) { - var section = ChartSection(c); - container.addChild(section); - var label = section.label; - var idx = colors.indexOf(c); - if (idx == 0) { - addChild(label!); - label.x = 30; - label.y = 80 + 20.0 * idx; - } - }); - - container.x = stage!.stageWidth * .8; - container.y = stage!.stageHeight * .5; - stage!.onEnterFrame.add((event) { - // if (container.width > container.x + 100) { - // tw = container.x + 100; - // container.width = tw; - // container.scaleY = container.scaleX; - // } - // container.width += (tw - container.width) / 20; - // container.scaleY = container.scaleX; - // scaleR += .01; - // var s = (Math.sin(scaleR)/2) + .5 ; - // trace(s); - // container.scale = .2 + s * 1.5; - }); - - // var chartsPath = Path(); - - // graphics.beginFill(Colors.black45); - // graphics.drawPath(chartsPath); - // graphics.endFill(); - // - // graphics.lineStyle(2, Colors.red); - // graphics.drawPath(chartsPath); - // graphics.endFill(); - } - -// @override -// void update(double delta) { -// super.update(delta); -// } -} - -class ChartSection extends GShape { - Path myPath = Path(); - int numQuads = 0; - - Color color; - double lastX = 0.0; - - ChartSection(this.color) { - // List.generate(19, (index) => addSlot()); - } - - GText? label; - int frameCount = 0; - double targetX = 0; - Path maskPath = Path(); - Path outputPath = Path(); - - @override - void addedToStage() { - maskPath.addRect(GRect(0, 0, 300, 300).toNative()); - - label = GText.build( - text: 'color', color: color, fontSize: 14, fontWeight: FontWeight.bold); - stage!.onEnterFrame.add((event) { - if (++frameCount % 3 == 0) { - addSlot(); - pivotX = width; - // x = maxPos; - // if (tempW > maxPos) { - // targetX =-tempW + maxPos; - // } - } - // x += (targetX - x)/10 ; - // scaleRatio += .001; - // scale = 1 + Math.sin(scaleRatio); - }); - } - - // @override - // void update(double delta) { - // super.update(delta); - // addSlot(); - // } - - GRect lastRect = GRect(); - - void addSlot() { - ++numQuads; - label!.text = '$numQuads rects'; - graphics.clear(); - graphics.beginFill(color.withOpacity(.3)); - graphics.lineStyle(2, color); - graphics.drawPath(outputPath); - graphics.endFill(); - - // graphics.drawPath(myPath); - // graphics.endFill(); - } -} diff --git a/example/lib/demos/rating_star/scene/rating_scene.dart b/example/lib/demos/rating_star/scene/rating_scene.dart index 5427e0b..4ce6fcc 100644 --- a/example/lib/demos/rating_star/scene/rating_scene.dart +++ b/example/lib/demos/rating_star/scene/rating_scene.dart @@ -71,4 +71,3 @@ class RatingStarsScene extends GSprite { } } } - diff --git a/example/lib/demos/simple_interactions/simple_interactions_scene.dart b/example/lib/demos/simple_interactions/simple_interactions_scene.dart index 9f13ee4..7ad59fa 100644 --- a/example/lib/demos/simple_interactions/simple_interactions_scene.dart +++ b/example/lib/demos/simple_interactions/simple_interactions_scene.dart @@ -55,7 +55,7 @@ class SimpleInteractionsScene extends GSprite { /// for access modifiers keys, is better to check the raw event itself. /// as multiple physical keys have the same behaviour (shift, command, /// alt, etc) but different key codes. - if (event.rawEvent!.isShiftPressed) { + if (event.rawEvent.isShiftPressed) { pixelsToMove = 30.0; } @@ -71,7 +71,7 @@ class SimpleInteractionsScene extends GSprite { if (event.isKey(LogicalKeyboardKey.arrowUp)) { // arrow key UP ball.y -= pixelsToMove; - } else if (event.rawEvent!.logicalKey == LogicalKeyboardKey.arrowDown) { + } else if (event.rawEvent.logicalKey == LogicalKeyboardKey.arrowDown) { // arrow key DOWN ball.y += pixelsToMove; } diff --git a/example/lib/demos/simple_tween/simple_tween.dart b/example/lib/demos/simple_tween/simple_tween.dart index c1f738c..53474ad 100644 --- a/example/lib/demos/simple_tween/simple_tween.dart +++ b/example/lib/demos/simple_tween/simple_tween.dart @@ -69,7 +69,8 @@ class _TweenMenu extends StatelessWidget { ); } - Widget _addButton({required String label, IconData? icon, VoidCallback? onPressed}) { + Widget _addButton( + {required String label, IconData? icon, VoidCallback? onPressed}) { return TextButton( // color: Colors.red, child: Row( diff --git a/example/lib/demos/splash_intro/scene/svg_assets.dart b/example/lib/demos/splash_intro/scene/svg_assets.dart index 91d1b6f..0501068 100644 --- a/example/lib/demos/splash_intro/scene/svg_assets.dart +++ b/example/lib/demos/splash_intro/scene/svg_assets.dart @@ -7,7 +7,6 @@ /// https://gist.github.com/roipeker/37374272d15539aa60c2bdc39001a035 /// - /// just raw SVG strings... I used Figma to get the outlined texts. const graphxSvgString = ''' @@ -45,4 +44,4 @@ const flutterSvgString = ''' -'''; \ No newline at end of file +'''; diff --git a/example/lib/demos/trigrid/scene/point.dart b/example/lib/demos/trigrid/scene/point.dart index f8398a8..16f29b8 100644 --- a/example/lib/demos/trigrid/scene/point.dart +++ b/example/lib/demos/trigrid/scene/point.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:graphx/graphx.dart'; diff --git a/example/lib/demos/trigrid/scene/scene.dart b/example/lib/demos/trigrid/scene/scene.dart index e151d34..f12adde 100644 --- a/example/lib/demos/trigrid/scene/scene.dart +++ b/example/lib/demos/trigrid/scene/scene.dart @@ -45,6 +45,7 @@ class DrawTriangleGridScene extends GSprite { /// these are the points that we MOVE to update the grid. dots = List.generate(total, (index) { var d = GraphPoint(); + /// uncomment this to see the DOTS. // container.addChild(d); var idx = index % cols; diff --git a/example/lib/main.dart b/example/lib/main.dart index 8a62164..1ddd65b 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -9,7 +9,7 @@ void main() { // home: SimpleTweenMain(), // home: DemoSvgIconsMain(), // home: SimpleInteractionsMain(), - // home: GraphicsClipperDemo(), + home: GraphicsClipperDemo(), // home: FacebookReactionsMain(), // home: DrippingIVMain(), // home: ChartMountainMain(), @@ -55,9 +55,8 @@ void main() { // home: MouseRepulsionMain(), // home: Globe3dMain(), // home: LungsAnimationMain(), - // home: PathChartStressTestMain(), // home: ExpanderFabMenu(), - home: PageIndicatorMain(), + // home: PageIndicatorMain(), ), ); } diff --git a/example/lib/utils/utils.dart b/example/lib/utils/utils.dart index e192797..c28af77 100644 --- a/example/lib/utils/utils.dart +++ b/example/lib/utils/utils.dart @@ -2,4 +2,4 @@ export 'package:flutter/material.dart'; export 'package:graphx/graphx.dart' show SceneBuilderWidget; export 'base_scene.dart'; -export 'demo_scene_widget.dart'; \ No newline at end of file +export 'demo_scene_widget.dart'; diff --git a/example/macos/Runner.xcodeproj/project.pbxproj b/example/macos/Runner.xcodeproj/project.pbxproj index ef1b05f..1d12c89 100644 --- a/example/macos/Runner.xcodeproj/project.pbxproj +++ b/example/macos/Runner.xcodeproj/project.pbxproj @@ -54,7 +54,7 @@ /* Begin PBXFileReference section */ 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -182,8 +182,8 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 0930; - ORGANIZATIONNAME = "The Flutter Authors"; + LastUpgradeCheck = 1250; + ORGANIZATIONNAME = ""; TargetAttributes = { 33CC10EC2044A3C60003C045 = { CreatedOnToolsVersion = 9.2; @@ -202,7 +202,7 @@ }; }; buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 8.0"; + compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -268,7 +268,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n"; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; /* End PBXShellScriptBuildPhase section */ @@ -330,6 +330,7 @@ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CODE_SIGN_IDENTITY = "-"; @@ -359,12 +360,9 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -407,6 +405,7 @@ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CODE_SIGN_IDENTITY = "-"; @@ -460,6 +459,7 @@ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CODE_SIGN_IDENTITY = "-"; @@ -489,12 +489,9 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -513,12 +510,9 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index df12c33..1105cc3 100644 --- a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ - - - - - - - - + + - - =2.12.0 <3.0.0" diff --git a/lib/src/core/scene_controller.dart b/lib/src/core/scene_controller.dart index 22ed664..44d80d3 100644 --- a/lib/src/core/scene_controller.dart +++ b/lib/src/core/scene_controller.dart @@ -57,7 +57,7 @@ class SceneController { /// gets widget's global coordinates. /// useful to compute interactions with children Widgets that gets - GRect? Function()? resolveWindowBounds; + WindowBoundsResolver? resolveWindowBounds; int id = -1; @@ -86,7 +86,7 @@ class SceneController { if (front != null) { frontScene = ScenePainter(this, front); } - this.config = config??SceneConfig.defaultConfig; + this.config = config ?? SceneConfig.defaultConfig; } /// WARNING: Internal method @@ -109,7 +109,12 @@ class SceneController { void setup() { if (!GTween.initializedCommonWraps) { - GTween.registerCommonWraps(); + /// you can add your own `CustomTween.wrap()` registering. + GTween.registerCommonWraps([ + GTweenableBlur.wrap, + GTweenableDropShadowFilter.wrap, + GTweenableGlowFilter.wrap, + ]); } backScene?.$setup(); frontScene?.$setup(); @@ -178,3 +183,5 @@ class SceneController { bool _hasTicker() => _anySceneAutoUpdate() || _config.useTicker; } + +typedef WindowBoundsResolver = GRect? Function(); diff --git a/lib/src/core/scene_painter.dart b/lib/src/core/scene_painter.dart index c132a25..b4dfd67 100644 --- a/lib/src/core/scene_painter.dart +++ b/lib/src/core/scene_painter.dart @@ -26,7 +26,7 @@ class ScenePainter with EventDispatcherMixin { /// Warning: Experimental state bool useOwnCanvas = false; bool _ownCanvasNeedsRepaint = false; - Canvas? $canvas; + late Canvas $canvas; /// Size of the area available in `CustomPainter::paint()` Size size = Size.zero; @@ -93,7 +93,7 @@ class ScenePainter with EventDispatcherMixin { if (useOwnCanvas) { _pictureFromCanvas(); } else { - _stage!.paint($canvas); + _stage!.paint(canvas); } } @@ -146,7 +146,7 @@ class ScenePainter with EventDispatcherMixin { if (!_mouseMoveInputDetected && _lastMouseX != -1000000) { final input = MouseInputData( target: _stage, - dispatcher: _stage, + dispatcher: _stage!, type: MouseInputType.still, ); input.uid = ++MouseInputData.uniqueId; @@ -207,7 +207,7 @@ class ScenePainter with EventDispatcherMixin { void _onInputHandler(PointerEventData e) { var input = MouseInputData( target: stage, - dispatcher: stage, + dispatcher: stage!, type: MouseInputData.fromNativeType(e.type), ); input.rawEvent = e; @@ -233,7 +233,7 @@ class ScenePainter with EventDispatcherMixin { _createPicture(); } if (_canvasPicture != null) { - $canvas!.drawPicture(_canvasPicture!); + $canvas.drawPicture(_canvasPicture!); } } diff --git a/lib/src/debug/display_debugger.dart b/lib/src/debug/display_debugger.dart index b22ee0d..a72f295 100644 --- a/lib/src/debug/display_debugger.dart +++ b/lib/src/debug/display_debugger.dart @@ -1,6 +1,7 @@ import 'dart:ui' as ui; import '../../graphx.dart'; + enum DebugBoundsMode { /// renders the bounding box transformed, inside the current object [paint()] /// method process. diff --git a/lib/src/display/bitmap.dart b/lib/src/display/bitmap.dart index 4f2a6bf..7dad5c6 100644 --- a/lib/src/display/bitmap.dart +++ b/lib/src/display/bitmap.dart @@ -93,7 +93,7 @@ class GBitmap extends GDisplayObject { } @override - void paint(ui.Canvas? canvas) { + void paint(ui.Canvas canvas) { if (texture == null) return; _hasScale9Grid = texture!.scale9Grid != null; if (_hasScale9Grid) { @@ -103,7 +103,7 @@ class GBitmap extends GDisplayObject { } @override - void $applyPaint(ui.Canvas? canvas) { + void $applyPaint(ui.Canvas canvas) { if (hasFilters) { for (var filter in filters!) { filter.update(); diff --git a/lib/src/display/display_object.dart b/lib/src/display/display_object.dart index 0831b3e..978887b 100644 --- a/lib/src/display/display_object.dart +++ b/lib/src/display/display_object.dart @@ -127,7 +127,7 @@ abstract class GDisplayObject } void $dispatchMouseCallback( - MouseInputType? type, + MouseInputType type, GDisplayObject object, MouseInputData input, ) { @@ -174,8 +174,11 @@ abstract class GDisplayObject break; case MouseInputType.out: $mouseOverObj = null; + + /// TODO: check if other object on top receives the event + /// todo. before this one, and Cursor loses the stage. if (useCursor && GMouse.isShowing()) { - GMouse.cursor = null; + GMouse.basic(); } $onMouseOut?.dispatch(mouseInput); break; @@ -290,7 +293,7 @@ abstract class GDisplayObject double get height => getBounds($parent, _sHelperRect)!.height; set width(double? value) { - if (value == null) throw 'width can not be null'; + if (value?.isNaN ?? true) throw '[$this.width] can not be NaN nor null'; double? actualW; var zeroScale = _scaleX < 1e-8 && _scaleX > -1e-8; if (zeroScale) { @@ -299,11 +302,11 @@ abstract class GDisplayObject } else { actualW = (width / _scaleX).abs(); } - scaleX = value / actualW; + scaleX = value! / actualW; } set height(double? value) { - if (value == null) throw 'height can not be null'; + if (value?.isNaN ?? true) throw '[$this.height] can not be NaN nor null'; double? actualH; var zeroScale = _scaleY < 1e-8 && _scaleY > -1e-8; if (zeroScale) { @@ -312,83 +315,82 @@ abstract class GDisplayObject } else { actualH = (height / _scaleY).abs(); } - scaleY = value / actualH; + scaleY = value! / actualH; } set x(double? value) { - if (value == null) throw 'x can not be null'; + if (value?.isNaN ?? true) throw '[$this.x] can not be NaN nor null'; if (_x == value) return; - _x = value; + _x = value!; $setTransformationChanged(); } set y(double? value) { - if (value == null) throw 'y can not be null'; + if (value?.isNaN ?? true) throw '[$this.y] can not be NaN nor null'; if (_y == value) return; - _y = value; + _y = value!; $setTransformationChanged(); } set scaleX(double? value) { - if (value == null) throw 'scaleX can not be null'; + if (value?.isNaN ?? true) throw '[$this.scaleX] can not be NaN nor null'; if (_scaleX == value) return; - _scaleX = value; + _scaleX = value!; $setTransformationChanged(); } set scaleY(double? value) { - if (value == null) throw 'scaleY can not be null'; + if (value?.isNaN ?? true) throw '[$this.scaleY] can not be NaN nor null'; if (_scaleY == value) return; - _scaleY = value; + _scaleY = value!; $setTransformationChanged(); } set pivotX(double value) { + if (value.isNaN) throw '[$this.pivotX] can not be NaN nor null'; if (_pivotX == value) return; _pivotX = value; $setTransformationChanged(); } set pivotY(double value) { + if (value.isNaN) throw '[$this.pivotY] can not be NaN nor null'; if (_pivotY == value) return; _pivotY = value; $setTransformationChanged(); } set skewX(double value) { + if (value.isNaN) throw '[$this.skewX] can not be NaN nor null'; if (_skewX == value) return; _skewX = value; $setTransformationChanged(); } set skewY(double value) { + if (value.isNaN) throw '[$this.skewY] can not be NaN'; if (_skewY == value) return; _skewY = value; $setTransformationChanged(); } set rotation(double? value) { - if (value == null) throw 'rotation can not be null'; + if (value?.isNaN ?? true) throw '[$this.rotation] can not be NaN nor null'; if (_rotation == value) return; - _rotation = value; + _rotation = value!; $setTransformationChanged(); } set rotationX(double value) { + if (value.isNaN) throw '[$this.rotationX] can not be NaN'; if (_rotationX == value) return; _rotationX = value; if (!_isWarned3d) _warn3d(); $setTransformationChanged(); } - static bool _isWarned3d = false; - - void _warn3d() { - print('Warning: 3d transformations still not properly supported'); - _isWarned3d = true; - } - set rotationY(double value) { + if (value.isNaN) throw '[$this.rotationY] can not be NaN'; if (_rotationY == value) return; _rotationY = value; if (!_isWarned3d) _warn3d(); @@ -396,12 +398,20 @@ abstract class GDisplayObject } set z(double value) { + if (value.isNaN) throw '[$this.z] can not be NaN'; if (_z == value) return; _z = value; if (!_isWarned3d) _warn3d(); $setTransformationChanged(); } + static bool _isWarned3d = false; + + void _warn3d() { + print('Warning: 3d transformations still not properly supported'); + _isWarned3d = true; + } + double $alpha = 1; double get alpha => $alpha; @@ -823,7 +833,7 @@ abstract class GDisplayObject /// Do not override this method as it applies the basic /// transformations. Override $applyPaint() if you wanna use /// `Canvas` directly. - void paint(ui.Canvas? canvas) { + void paint(ui.Canvas canvas) { if (!$hasVisibleArea || !visible) { return; } @@ -905,16 +915,16 @@ abstract class GDisplayObject if ($useSaveLayerBounds) { nativeLayerBounds = layerBounds!.toNative(); } - canvas!.saveLayer(nativeLayerBounds, alphaPaint); + canvas.saveLayer(nativeLayerBounds, alphaPaint); } if (needSave) { // onPreTransform.dispatch(); - canvas!.save(); - var m = transformationMatrix.toNative()!; + canvas.save(); + var m = transformationMatrix.toNative(); canvas.transform(m.storage); if (_is3D) { /// TODO: experimental, just transforms - m = GMatrix().toNative()!; + m = GMatrix().toNative(); m.setEntry(3, 2, 0.004); m.rotateX(_rotationX); m.rotateY(_rotationY); @@ -926,7 +936,7 @@ abstract class GDisplayObject } if (hasMask) { - canvas!.save(); + canvas.save(); if (maskRect != null) { $applyMaskRect(canvas); } else { @@ -938,7 +948,8 @@ abstract class GDisplayObject if (_composerFilters != null) { for (var filter in _composerFilters) { - if (filter.hideObject) { + if (filter.hideObject || + (filter is GDropShadowFilter && filter.innerShadow)) { filterHidesObject = true; } filter.process(canvas, $applyPaint); @@ -950,22 +961,22 @@ abstract class GDisplayObject $onPostPaint?.dispatch(canvas); if (hasMask) { - canvas!.restore(); + canvas.restore(); } if (showDebugBounds) { final _paint = $debugBoundsPaint ?? _debugPaint; final linePaint = _paint.clone(); linePaint.color = linePaint.color.withOpacity(.3); final rect = _cacheLocalBoundsRect!.toNative(); - canvas!.drawLine(rect.topLeft, rect.bottomRight, linePaint); + canvas.drawLine(rect.topLeft, rect.bottomRight, linePaint); canvas.drawLine(rect.topRight, rect.bottomLeft, linePaint); canvas.drawRect(rect, _paint); } if (needSave) { - canvas!.restore(); + canvas.restore(); } if (_saveLayer) { - canvas!.restore(); + canvas.restore(); } } @@ -978,7 +989,7 @@ abstract class GDisplayObject /// override this method for custom drawing using Flutter's API. /// Access `$canvas` from here. - void $applyPaint(ui.Canvas? canvas) {} + void $applyPaint(ui.Canvas canvas) {} @mustCallSuper void dispose() { diff --git a/lib/src/display/display_object_container.dart b/lib/src/display/display_object_container.dart index 8a3a0bf..90541fd 100644 --- a/lib/src/display/display_object_container.dart +++ b/lib/src/display/display_object_container.dart @@ -282,7 +282,7 @@ abstract class GDisplayObjectContainer extends GDisplayObject { } @override - void $applyPaint(ui.Canvas? canvas) { + void $applyPaint(ui.Canvas canvas) { if (!$hasVisibleArea) return; for (var child in children) { if (child.$hasVisibleArea) { diff --git a/lib/src/display/shape.dart b/lib/src/display/shape.dart index dbe35c2..95001be 100644 --- a/lib/src/display/shape.dart +++ b/lib/src/display/shape.dart @@ -63,7 +63,7 @@ class GShape extends GDisplayObject { } @override - void $applyPaint(ui.Canvas? canvas) { + void $applyPaint(ui.Canvas canvas) { if (isMask && _graphics != null) { GMatrix matrix; var paths = _graphics!.getPaths(); @@ -72,7 +72,7 @@ class GShape extends GDisplayObject { } else { matrix = transformationMatrix; } - var clipPath = paths.transform(matrix.toNative()!.storage); + var clipPath = paths.transform(matrix.toNative().storage); final inverted = maskInverted || $maskee!.maskInverted; if (inverted) { _initInversePath(); @@ -82,12 +82,12 @@ class GShape extends GDisplayObject { if (SystemUtils.usingSkia) { clipPath = ui.Path.combine( ui.PathOperation.difference, _inverseHugePath!, clipPath); - canvas!.clipPath(clipPath); + canvas.clipPath(clipPath); } else { trace('Shape.maskInverted is unsupported in the current platform'); } } else { - canvas!.clipPath(clipPath); + canvas.clipPath(clipPath); } } else { _graphics?.isMask = isMask; diff --git a/lib/src/display/sprite.dart b/lib/src/display/sprite.dart index 12ae3e2..dc5708a 100644 --- a/lib/src/display/sprite.dart +++ b/lib/src/display/sprite.dart @@ -5,8 +5,8 @@ import '../../graphx.dart'; class GSprite extends GDisplayObjectContainer { @override String toString() { - final msg = name != null ? ' {name: $name}' : ''; - return '$runtimeType (Sprite)$msg'; + final msg = name != null ? '(name:"$name")' : ''; + return '$runtimeType#$hashCode$msg'; } static final _sHelperMatrix = GMatrix(); @@ -44,7 +44,7 @@ class GSprite extends GDisplayObjectContainer { } @override - void $applyPaint(ui.Canvas? canvas) { + void $applyPaint(ui.Canvas canvas) { if (!$hasVisibleArea) return; _graphics?.alpha = worldAlpha; _graphics?.paint(canvas); diff --git a/lib/src/display/stage.dart b/lib/src/display/stage.dart index 008fb9a..adb4d2a 100644 --- a/lib/src/display/stage.dart +++ b/lib/src/display/stage.dart @@ -77,13 +77,13 @@ class Stage extends GDisplayObjectContainer } @override - void paint(ui.Canvas? canvas) { + void paint(ui.Canvas canvas) { /// scene start painting. if (maskBounds && _stageRectNative != null) { - canvas!.clipRect(_stageRectNative!); + canvas.clipRect(_stageRectNative!); } if (_backgroundPaint != null) { - canvas!.drawPaint(_backgroundPaint!); + canvas.drawPaint(_backgroundPaint!); } super.paint(canvas); if (DisplayBoundsDebugger.debugBoundsMode == DebugBoundsMode.stage) { @@ -91,7 +91,7 @@ class Stage extends GDisplayObjectContainer _boundsDebugger.render(); } if (showBoundsRect) { - canvas!.drawPath(_stageBoundsRectPath, _stageBoundsRectPaint); + canvas.drawPath(_stageBoundsRectPath, _stageBoundsRectPaint); } } diff --git a/lib/src/display/text.dart b/lib/src/display/text.dart index afb42e3..356f080 100644 --- a/lib/src/display/text.dart +++ b/lib/src/display/text.dart @@ -218,21 +218,23 @@ class GText extends GDisplayObject { void _layout() { //// Web has a bug for double.infinity for text layout. - final paragraphWidth = _width.isInfinite && !SystemUtils.usingSkia ? _maxTextWidthForWeb : _width; + final paragraphWidth = _width.isInfinite && !SystemUtils.usingSkia + ? _maxTextWidthForWeb + : _width; _paragraph?.layout(ui.ParagraphConstraints(width: paragraphWidth)); _invalidSize = false; } /// Warning: Internal method. /// applies the painting after the DisplayObject transformations. - /// Should be overriden by subclasses. + /// Should be override by subclasses. @override - void $applyPaint(ui.Canvas? canvas) { + void $applyPaint(ui.Canvas canvas) { super.$applyPaint(canvas); if (_text == '') return; validate(); if (backgroundColor != null && backgroundColor!.alpha > 0) { - canvas!.drawRect( + canvas.drawRect( ui.Rect.fromLTWH(0, 0, intrinsicWidth, textHeight), ui.Paint()..color = backgroundColor!, ); @@ -243,11 +245,11 @@ class GText extends GDisplayObject { // final alphaPaint = PainterUtils.getAlphaPaint($alpha); // final alphaPaint = _alphaPaint; // var bounds = Rect.fromLTWH(0, 0, textWidth, textHeight); - canvas!.saveLayer(null, _alphaPaint); + canvas.saveLayer(null, _alphaPaint); canvas.drawParagraph(_paragraph!, ui.Offset.zero); canvas.restore(); } else { - canvas!.drawParagraph(_paragraph!, ui.Offset.zero); + canvas.drawParagraph(_paragraph!, ui.Offset.zero); } } } diff --git a/lib/src/events/keyboard_data.dart b/lib/src/events/keyboard_data.dart index 0a30697..5486294 100644 --- a/lib/src/events/keyboard_data.dart +++ b/lib/src/events/keyboard_data.dart @@ -4,36 +4,32 @@ import 'package:flutter/widgets.dart'; enum KeyEventType { down, up } class KeyboardEventData { - final KeyEventType? type; - final RawKeyEvent? rawEvent; + final KeyEventType type; + final RawKeyEvent rawEvent; - KeyboardEventData({this.type, this.rawEvent}); + KeyboardEventData({required this.type, required this.rawEvent}); - bool isPressed(LogicalKeyboardKey key) { - return rawEvent!.isKeyPressed(key); - } + bool isPressed(LogicalKeyboardKey key) => rawEvent.isKeyPressed(key); - bool isKey(LogicalKeyboardKey key) { - return rawEvent!.logicalKey == key; - } + bool isKey(LogicalKeyboardKey key) => rawEvent.logicalKey == key; } extension MyKeyEventExt on KeyboardEventData { bool get arrowLeft { // return rawEvent.isKeyPressed(LogicalKeyboardKey.arrowLeft); - return rawEvent!.logicalKey == LogicalKeyboardKey.arrowLeft; + return rawEvent.logicalKey == LogicalKeyboardKey.arrowLeft; } bool get arrowRight { - return rawEvent!.logicalKey == LogicalKeyboardKey.arrowRight; + return rawEvent.logicalKey == LogicalKeyboardKey.arrowRight; // return rawEvent.isKeyPressed(LogicalKeyboardKey.arrowRight); } bool get arrowUp { - return rawEvent!.logicalKey == LogicalKeyboardKey.arrowUp; + return rawEvent.logicalKey == LogicalKeyboardKey.arrowUp; } bool get arrowDown { - return rawEvent!.logicalKey == LogicalKeyboardKey.arrowDown; + return rawEvent.logicalKey == LogicalKeyboardKey.arrowDown; } } diff --git a/lib/src/events/mps.dart b/lib/src/events/mps.dart index 741fbf7..e145f7a 100644 --- a/lib/src/events/mps.dart +++ b/lib/src/events/mps.dart @@ -14,9 +14,6 @@ class MPS { final _cacheOnce = >{}; void publishParams(String topic, CallbackParams args) { -// final subs = _cache[topic]; -// subs?.forEach((fn) => Function.apply(fn, args?.positional, args?.named)); - void _send(Function? fn) => Function.apply(fn!, args.positional, args.named); diff --git a/lib/src/events/pointer_data.dart b/lib/src/events/pointer_data.dart index 668fcc6..2a8465c 100644 --- a/lib/src/events/pointer_data.dart +++ b/lib/src/events/pointer_data.dart @@ -11,13 +11,12 @@ enum PointerEventType { enter, exit, hover, - // mouse stuffs. } class PointerEventData { final double stageX; final double stageY; - final PointerEventType? type; + final PointerEventType type; final PointerEvent rawEvent; /// local position in DisplayObject @@ -32,7 +31,7 @@ class PointerEventData { /// 300 milliseconds for double click static int doubleClickTime = 300; - PointerEventData({this.type, required this.rawEvent}) + PointerEventData({required this.type, required this.rawEvent}) : stageX = rawEvent.localPosition.dx, stageY = rawEvent.localPosition.dy { localPosition = GPoint(stageX, stageY); @@ -128,8 +127,8 @@ class MouseInputData { /// display objects GDisplayObject? target; - GDisplayObject? dispatcher; - MouseInputType? type; + GDisplayObject dispatcher; + MouseInputType type; bool buttonDown = false; bool mouseOut = false; double time = 0; @@ -172,11 +171,11 @@ class MouseInputData { } static int uniqueId = 0; - int? uid; - MouseInputData({this.target, this.dispatcher, this.type}); + late int uid; + MouseInputData({this.target, required this.dispatcher, required this.type}); MouseInputData clone( - GDisplayObject target, GDisplayObject dispatcher, MouseInputType? type) { + GDisplayObject target, GDisplayObject dispatcher, MouseInputType type) { var input = MouseInputData( target: target, dispatcher: dispatcher, @@ -191,20 +190,10 @@ class MouseInputData { input._stagePosition.setTo(_stagePosition.x, _stagePosition.y); input.scrollDelta.setTo(scrollDelta.x, scrollDelta.y); input.localPosition.setTo(localPosition.x, localPosition.y); -// input.scrollDeltaX = scrollDeltaX; -// input.scrollDeltaY = scrollDeltaY; input.mouseOut = mouseOut; return input; } -// Offset get scrollDelta { -// if (rawEvent.rawEvent is PointerScrollEvent) { -// return (rawEvent.rawEvent as PointerScrollEvent).scrollDelta; -// } -// return null; -// } -// int get time => rawEvent.rawEvent.timeStamp.inMilliseconds; - static MouseInputType fromNativeType(PointerEventType? nativeType) { if (nativeType == PointerEventType.down) { return MouseInputType.down; diff --git a/lib/src/events/signal.dart b/lib/src/events/signal.dart index acbc6a7..b3ebbe8 100644 --- a/lib/src/events/signal.dart +++ b/lib/src/events/signal.dart @@ -73,6 +73,8 @@ class EventSignal { final _listeners = >[]; int _iterDispatchers = 0; int id = -1; + int _iterLen = 0; + bool debug = false; bool has(EventSignalCallback callback) { return _listeners.contains(callback) || _listenersOnce.contains(callback); @@ -93,7 +95,10 @@ class EventSignal { void remove(EventSignalCallback callback) { final idx = _listeners.indexOf(callback); if (idx > -1) { - if (idx <= _iterDispatchers) _iterDispatchers--; + if (idx <= _iterDispatchers) { + _iterDispatchers--; + } + --_iterLen; _listeners.removeAt(idx); } else { _listenersOnce.remove(callback); @@ -106,12 +111,16 @@ class EventSignal { } void dispatch(T data) { - for (var i = 0; i < _listeners.length; ++i) { -// if (id > 0) print('Calling ::: $i - ${_listeners.length}'); - _listeners[i].call(data); + _iterLen = _listeners.length; + for (_iterDispatchers = 0; + _iterDispatchers < _iterLen; + ++_iterDispatchers) { + _listeners[_iterDispatchers].call(data); } - for (var i = 0; i < _listenersOnce.length; i++) { - _listenersOnce.removeAt(i).call(data); + _iterLen = _listenersOnce.length; + while (_iterLen > 0) { + _listenersOnce.removeAt(0).call(data); + _iterLen--; } } } diff --git a/lib/src/geom/color_matrix.dart b/lib/src/geom/color_matrix.dart index 0e7d932..a673bfa 100644 --- a/lib/src/geom/color_matrix.dart +++ b/lib/src/geom/color_matrix.dart @@ -50,11 +50,11 @@ class ColorMatrix { // ignore: non_constant_identifier_names static final int LENGTH = IDENTITY_MATRIX.length; - final _storage = List.filled(25, null); + final _storage = List.filled(25, 0); - ColorMatrix([List? matrix]) { + ColorMatrix([List matrix = IDENTITY_MATRIX]) { matrix = _fixMatrix(matrix); - copyMatrix(((matrix!.length == LENGTH) ? matrix : IDENTITY_MATRIX)); + copyMatrix(((matrix.length == LENGTH) ? matrix : IDENTITY_MATRIX)); } // public methods: @@ -192,9 +192,9 @@ class ColorMatrix { ]); } - void concat(List? pMatrix) { + void concat(List pMatrix) { pMatrix = _fixMatrix(pMatrix); - if (pMatrix!.length != LENGTH) return; + if (pMatrix.length != LENGTH) return; multiplyMatrix(pMatrix); } @@ -209,15 +209,15 @@ class ColorMatrix { /// private methods: /// copy the specified matrix's values to this matrix: - void copyMatrix(List? pMatrix) { + void copyMatrix(List pMatrix) { for (var i = 0; i < LENGTH; i++) { - _storage[i] = pMatrix![i]; + _storage[i] = pMatrix[i]; } } /// multiplies one matrix against another: - void multiplyMatrix(List? pMatrix) { - var col = List.filled(25, null); + void multiplyMatrix(List pMatrix) { + var col = List.filled(25, 0); for (var i = 0; i < 5; i++) { for (var j = 0; j < 5; j++) { @@ -226,7 +226,7 @@ class ColorMatrix { for (var j = 0; j < 5; j++) { var val = 0.0; for (var k = 0; k < 5; k++) { - val += pMatrix![j + k * 5]! * col[k]!; + val += pMatrix[j + k * 5] * col[k]; } _storage[j + i * 5] = val; } @@ -238,9 +238,8 @@ class ColorMatrix { double _cleanValue(double pVal, double pLimit) => math.min(pLimit, math.max(-pLimit, pVal)); - /// makes sure matrixes are 5x5 (25 long): - List? _fixMatrix([List? pMatrix]) { - if (pMatrix == null) return IDENTITY_MATRIX; + /// makes sure Matrices are 5x5 (25 long): + List _fixMatrix(List pMatrix) { if (pMatrix.length < LENGTH) { pMatrix = List.from(pMatrix) ..addAll(IDENTITY_MATRIX.getRange(pMatrix.length, LENGTH)); diff --git a/lib/src/geom/geom.dart b/lib/src/geom/geom.dart index 97140e7..6883488 100644 --- a/lib/src/geom/geom.dart +++ b/lib/src/geom/geom.dart @@ -1,3 +1,3 @@ -export 'gxmatrix.dart'; -export 'gxpoint.dart'; -export 'gxrect.dart'; +export 'gmatrix.dart'; +export 'gpoint.dart'; +export 'grect.dart'; diff --git a/lib/src/geom/gxmatrix.dart b/lib/src/geom/gmatrix.dart similarity index 77% rename from lib/src/geom/gxmatrix.dart rename to lib/src/geom/gmatrix.dart index 57fb0f5..0786c53 100644 --- a/lib/src/geom/gxmatrix.dart +++ b/lib/src/geom/gmatrix.dart @@ -4,28 +4,23 @@ import 'geom.dart'; class GMatrix { double a = 0.0, b = 0.0, c = 0.0, d = 0.0, tx = 0.0, ty = 0.0; - Matrix4? _native; + final Matrix4 _native = Matrix4.identity(); @override - String toString() { - return 'GxMatrix {a: $a, b: $b, c: $c, d: $d, tx: $tx, ty: $ty}'; - } + String toString() => 'GMatrix {a: $a, b: $b, c: $c, d: $d, tx: $tx, ty: $ty}'; - Matrix4? toNative() { - _native ??= Matrix4.identity(); - _native!.setValues(a, b, 0, 0, c, d, 0, 0, 0, 0, 1, 0, tx, ty, 0, 1); + Matrix4 toNative() { + _native.setValues(a, b, 0, 0, c, d, 0, 0, 0, 0, 1, 0, tx, ty, 0, 1); return _native; } - static GMatrix fromNative(Matrix4 m) { - return GMatrix( - m.storage[0], - m.storage[4], - m.storage[1], - m.storage[5], - m.storage[12], - m.storage[13], - ); - } + static GMatrix fromNative(Matrix4 m) => GMatrix( + m.storage[0], + m.storage[4], + m.storage[1], + m.storage[5], + m.storage[12], + m.storage[13], + ); GMatrix zoomAroundPoint(GPoint center, double zoomFactor) { var t1 = GMatrix(); @@ -143,16 +138,16 @@ class GMatrix { GMatrix concat(GMatrix matrix) { double a1, c1, tx1; - a1 = a * matrix.a+ b* matrix.c; - b = a* matrix.b+ b* matrix.d; + a1 = a * matrix.a + b * matrix.c; + b = a * matrix.b + b * matrix.d; a = a1; - c1 = c* matrix.a+ d* matrix.c; - d = c* matrix.b+ d* matrix.d; + c1 = c * matrix.a + d * matrix.c; + d = c * matrix.b + d * matrix.d; c = c1; - tx1 = tx* matrix.a+ ty* matrix.c+ matrix.tx; - ty = tx* matrix.b+ ty* matrix.d+ matrix.ty; + tx1 = tx * matrix.a + ty * matrix.c + matrix.tx; + ty = tx * matrix.b + ty * matrix.d + matrix.ty; tx = tx1; return this; @@ -186,20 +181,20 @@ class GMatrix { //} GMatrix invert() { - var n = a* d- b* c; + var n = a * d - b * c; if (n == 0) { a = b = c = d = 0; tx = -tx; ty = -ty; } else { n = 1 / n; - var a1 = d* n; - d = a* n; + var a1 = d * n; + d = a * n; a = a1; b *= -n; c *= -n; - var tx1 = -a* tx- c* ty; - ty = -b* tx- d* ty; + var tx1 = -a * tx - c * ty; + ty = -b * tx - d * ty; tx = tx1; } return this; @@ -225,12 +220,12 @@ class GMatrix { var sinY = math.sin(skewY); var cosY = math.cos(skewY); setTo( - a* cosY - b* sinX, - a* sinY + b* cosX, - c* cosY - d* sinX, - c* sinY + d* cosX, - tx* cosY - ty* sinX, - tx* sinY + ty* cosX, + a * cosY - b * sinX, + a * sinY + b * cosX, + c * cosY - d * sinX, + c * sinY + d * cosX, + tx * cosY - ty * sinX, + tx * sinY + ty * cosX, ); } @@ -238,16 +233,16 @@ class GMatrix { final cos = math.cos(angle); final sin = math.sin(angle); - var a1 = a* cos - b* sin; - b = a* sin + b* cos; + var a1 = a * cos - b * sin; + b = a * sin + b * cos; a = a1; - var c1 = c* cos - d* sin; - d = c* sin + d* cos; + var c1 = c * cos - d * sin; + d = c * sin + d * cos; c = c1; - var tx1 = tx* cos - ty* sin; - ty = tx* sin + ty* cos; + var tx1 = tx * cos - ty * sin; + ty = tx * sin + ty * cos; tx = tx1; } @@ -267,16 +262,16 @@ class GMatrix { GPoint transformInverseCoords(double x, double y, [GPoint? out]) { out ??= GPoint(); - final id = 1 / ((a* d) + (c* -b)); - out.x = (d* id * x) + (-c* id * y) + (((ty* c) - (tx* d)) * id); - out.y = (a* id * y) + (-b* id * x) + (((-ty* a) + (tx* b)) * id); + final id = 1 / ((a * d) + (c * -b)); + out.x = (d * id * x) + (-c * id * y) + (((ty * c) - (tx * d)) * id); + out.y = (a * id * y) + (-b * id * x) + (((-ty * a) + (tx * b)) * id); return out; } GPoint transformCoords(double x, double y, [GPoint? out]) { out ??= GPoint(); - out.x = a* x + c* y + tx; - out.y = d* y + b* x + ty; + out.x = a * x + c * y + tx; + out.y = d * y + b * x + ty; return out; } } diff --git a/lib/src/geom/gpoint.dart b/lib/src/geom/gpoint.dart new file mode 100644 index 0000000..9e33709 --- /dev/null +++ b/lib/src/geom/gpoint.dart @@ -0,0 +1,60 @@ +import 'dart:math' as math; +import 'dart:ui'; + +/// The GPoint object represents a location in a two-dimensional coordinate +/// system, where `x` represents the horizontal axis and `y` represents the +/// vertical axis. +/// The following code creates a point at (0,0): +/// +/// ```dart +/// var myPoint:Point = new Point(); +/// ``` + +class GPoint { + /// Returns the distance between p1 and p2. + static double distance(GPoint p1, GPoint p2) { + var dx = p2.x - p1.x; + var dy = p2.y - p1.y; + dx *= dx; + dy *= dy; + return math.sqrt(dx + dy); + } + + /// Creates a point instance from an dart `Offset`. + static GPoint fromNative(Offset nativeOffset) => + GPoint(nativeOffset.dx, nativeOffset.dy); + + /// Returns a string that contains the values of the x and y coordinates. + @override + String toString() => 'GPoint {$x,$y}'; + + /// Creates a copy of this GPoint object. + GPoint clone() => GPoint(x, y); + + /// Creates a `Offset` instance (Dart primitive) from this GPoint. + Offset toNative() => Offset(x, y); + + GPoint setEmpty() { + x = y = 0.0; + return this; + } + + /// Sets the members of GPoint to the specified values + GPoint setTo(double x, double y) { + this.x = x; + this.y = y; + return this; + } + + /// The horizontal coordinate of the point. + double x; + + /// The vertical coordinate of the point. + double y; + + /// create a new GPoint instance. + GPoint([this.x = 0, this.y = 0]); + + /// The length of the line segment from (0,0) to this point. + double get length => math.sqrt(x * x + y * y); +} diff --git a/lib/src/geom/gxrect.dart b/lib/src/geom/grect.dart similarity index 96% rename from lib/src/geom/gxrect.dart rename to lib/src/geom/grect.dart index b11c139..7d9aaea 100644 --- a/lib/src/geom/gxrect.dart +++ b/lib/src/geom/grect.dart @@ -4,15 +4,11 @@ import 'dart:ui'; import 'geom.dart'; class GRect { - static GRect fromNative(Rect nativeRect) { - return GRect( - nativeRect.left, nativeRect.top, nativeRect.width, nativeRect.height); - } + static GRect fromNative(Rect nativeRect) => GRect( + nativeRect.left, nativeRect.top, nativeRect.width, nativeRect.height); @override - String toString() { - return 'GxRect {x: $x, y: $y, w: $width, h: $height}'; - } + String toString() => 'GRect {x: $x, y: $y, w: $width, h: $height}'; Rect toNative() { return Rect.fromLTWH(x, y, width, height); @@ -182,7 +178,9 @@ class GRect { /// --- Round Rect implementation --- GxRectCornerRadius? _corners; + bool get hasCorners => _corners?.isNotEmpty ?? false; + GxRectCornerRadius? get corners { _corners ??= GxRectCornerRadius(); return _corners; @@ -211,6 +209,7 @@ class GRect { class GxRectCornerRadius { double topLeft, topRight, bottomRight, bottomLeft; + GxRectCornerRadius([ this.topLeft = 0, this.topRight = 0, diff --git a/lib/src/geom/gxpoint.dart b/lib/src/geom/gxpoint.dart deleted file mode 100644 index 62296ef..0000000 --- a/lib/src/geom/gxpoint.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'dart:math' as math; -import 'dart:ui'; - -class GPoint { - static GPoint fromNative(Offset nativeOffset) { - return GPoint(nativeOffset.dx, nativeOffset.dy); - } - - @override - String toString() { - return 'GxPoint {$x,$y}'; - } - - GPoint clone() => GPoint(x, y); - - Offset toNative() => Offset(x, y); - - GPoint setEmpty() { - x = y = 0.0; - return this; - } - - GPoint setTo(double x, double y) { - this.x = x; - this.y = y; - return this; - } - - double x, y; - GPoint([this.x = 0, this.y = 0]); - - static double distance(GPoint p1, GPoint p2) { - var dx = p2.x - p1.x; - var dy = p2.y - p1.y; - dx *= dx; - dy *= dy; - return math.sqrt(dx + dy); - } - - double get length => math.sqrt(x * x + y * y); -} diff --git a/lib/src/input/keyboard_manager.dart b/lib/src/input/keyboard_manager.dart index 06399f2..6b9a6cb 100644 --- a/lib/src/input/keyboard_manager.dart +++ b/lib/src/input/keyboard_manager.dart @@ -4,16 +4,11 @@ import 'package:flutter/services.dart'; import '../../graphx.dart'; class KeyboardManager { - FocusNode? _focusNode; - - FocusNode get focusNode => _focusNode ??= FocusNode(); + final focusNode = FocusNode(); void dispose() { - // _focusNode?.dispose(); - // _focusNode = null; _onDown?.removeAll(); _onUp?.removeAll(); - _lastEvent = null; } EventSignal get onDown => _onDown ??= EventSignal(); @@ -34,7 +29,7 @@ class KeyboardManager { bool get isControlPressed => _lastEvent?.rawEvent?.isControlPressed ?? false; - bool get isMetaPressed => _lastEvent?.rawEvent?.isMetaPressed ?? false; + bool get isMetaPressed => _lastEvent?.rawEvent?.isMetaPressed ?? false ; void $process(KeyboardEventData event) { _lastEvent = event; diff --git a/lib/src/input/mouse.dart b/lib/src/input/mouse.dart index 317337f..09ca1f5 100644 --- a/lib/src/input/mouse.dart +++ b/lib/src/input/mouse.dart @@ -6,15 +6,15 @@ export 'package:flutter/rendering.dart' show SystemMouseCursor; /// Accessible from `pointer_manager.dart` abstract class GMouse { - static SystemMouseCursor? _cursor; + static SystemMouseCursor _cursor = SystemMouseCursors.basic; static SystemMouseCursor? _lastCursor; - static SystemMouseCursor? get cursor => _cursor; + static SystemMouseCursor get cursor => _cursor; - static void setClickCursor()=> cursor = SystemMouseCursors.click; + static void setClickCursor() => cursor = SystemMouseCursors.click; - static set cursor(SystemMouseCursor? value) { - value ??= SystemMouseCursors.basic; + static set cursor(SystemMouseCursor value) { + // value ??= SystemMouseCursors.basic; if (_cursor == value) return; if (_cursor != SystemMouseCursors.none) { _lastCursor = _cursor; @@ -24,7 +24,7 @@ abstract class GMouse { 'activateSystemCursor', { 'device': 1, - 'kind': cursor!.kind, + 'kind': cursor.kind, }, ); } @@ -33,5 +33,7 @@ abstract class GMouse { static void hide() => cursor = SystemMouseCursors.none; - static void show() => cursor = _lastCursor; + static void show() => cursor = (_lastCursor ?? SystemMouseCursors.basic); + + static void basic() => cursor = SystemMouseCursors.basic; } diff --git a/lib/src/log/trace.dart b/lib/src/log/trace.dart index ca64378..187876f 100644 --- a/lib/src/log/trace.dart +++ b/lib/src/log/trace.dart @@ -127,10 +127,10 @@ String _stackCommon(String stack) { output += '↪ $callLine '; } } - const _sufixCall = '()'; + const _suffixCall = '()'; if (elements.length == 1) { /// global method. - methodName = '${elements[0]}$_sufixCall'; + methodName = '${elements[0]}$_suffixCall'; if (_showMethodname) { output += '‣ $methodName '; } @@ -138,7 +138,7 @@ String _stackCommon(String stack) { className = elements.removeAt(0); methodName = elements.join('.'); methodName = - '${methodName.replaceAll(_anonymousMethodTag, '<⁕>')}$_sufixCall'; + '${methodName.replaceAll(_anonymousMethodTag, '<⁕>')}$_suffixCall'; if (_showClassname) { output += '‣ $className '; } diff --git a/lib/src/math.dart b/lib/src/math.dart index 09346ed..bb13ce4 100644 --- a/lib/src/math.dart +++ b/lib/src/math.dart @@ -126,8 +126,7 @@ abstract class Math { /// Returns a pseudo-random element `` from the parameter `list`. /// Using the `Random()` class to compute the List index. - static E randomList(List list) => - list[randomRangeInt(0, list.length - 1)]; + static E randomList(List list) => list[randomRangeInt(0, list.length)]; /// Returns a pseudo-random `double` number between parameters `min` and /// `max`. diff --git a/lib/src/render/filters/blur_filter.dart b/lib/src/render/filters/blur_filter.dart index 16f64e6..580e98d 100644 --- a/lib/src/render/filters/blur_filter.dart +++ b/lib/src/render/filters/blur_filter.dart @@ -1,4 +1,4 @@ -import 'dart:ui' as ui ; +import 'dart:ui' as ui; import '../../../graphx.dart'; diff --git a/lib/src/render/filters/color_filter.dart b/lib/src/render/filters/color_filter.dart index 23ec3e2..a8ca1f6 100644 --- a/lib/src/render/filters/color_filter.dart +++ b/lib/src/render/filters/color_filter.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -import '../../geom/gxrect.dart'; +import '../../geom/grect.dart'; import 'blur_filter.dart'; class GColorFilters { diff --git a/lib/src/render/filters/composer_filter.dart b/lib/src/render/filters/composer_filter.dart index c93eeb6..ed3fe90 100644 --- a/lib/src/render/filters/composer_filter.dart +++ b/lib/src/render/filters/composer_filter.dart @@ -9,7 +9,7 @@ class GComposerFilter extends GBaseFilter { @override void resolvePaint(ui.Paint paint) {} - void process(ui.Canvas? canvas, Function applyPaint, [int processCount = 1]) { + void process(ui.Canvas canvas, Function applyPaint, [int processCount = 1]) { /// todo: figure the area. // canvas.saveLayer(null, paint); // canvas.translate(_dx, _dy); diff --git a/lib/src/render/filters/dropshadow_filter.dart b/lib/src/render/filters/dropshadow_filter.dart index b8e2500..c30d46a 100644 --- a/lib/src/render/filters/dropshadow_filter.dart +++ b/lib/src/render/filters/dropshadow_filter.dart @@ -9,6 +9,8 @@ class GDropShadowFilter extends GComposerFilter { double _angle = 0; double _distance = 0; Color _color = kColorBlack; + bool innerShadow = false; + // todo: find a way to define the strength of the filter. // double _strength = 0.0; @@ -71,6 +73,7 @@ class GDropShadowFilter extends GComposerFilter { double distance = 0, Color color = kColorBlack, bool hideObject = false, + this.innerShadow = false, ]) { this.blurX = blurX; this.blurY = blurY; @@ -131,13 +134,38 @@ class GDropShadowFilter extends GComposerFilter { } @override - void process(Canvas? canvas, Function applyPaint, [int processCount = 1]) { - canvas!.saveLayer(null, paint); - // final bb = layerBounds.clone(); - // bb.inflate(_strength, _strength); - canvas.translate(_dx, _dy); - applyPaint(canvas); - canvas.restore(); + void process(Canvas canvas, Function applyPaint, [int processCount = 1]) { + /// compute outer rect. + if (innerShadow) { + /// TODO: rework logic for bounds. + /// todo: too many save layer calls for inner shadows. + /// + // var rectOuter = _rect.clone(); + // rectOuter.x= rectOuter.y=0; + // var rectInner = rectOuter.clone(); + // rectInner.width = rectOuter.width-_dx; + // rectInner.height = rectOuter.height-_dy; + canvas.saveLayer(null, Paint()); + applyPaint(canvas); + final shadowPaint = Paint() + ..blendMode = BlendMode.srcATop + ..imageFilter = ImageFilter.blur(sigmaX: blurX, sigmaY: blurY) + ..colorFilter = ColorFilter.mode(color, BlendMode.srcOut); + canvas.saveLayer(null, shadowPaint); + canvas.saveLayer(null, Paint()); + canvas.translate(_dx, _dy); + applyPaint(canvas); + canvas.restore(); + canvas.restore(); + canvas.restore(); + } else { + canvas.saveLayer(null, paint); + // final bb = layerBounds.clone(); + // bb.inflate(_strength, _strength); + canvas.translate(_dx, _dy); + applyPaint(canvas); + canvas.restore(); + } if (++processCount <= iterations) { process(canvas, applyPaint, processCount); } diff --git a/lib/src/render/filters/filters.dart b/lib/src/render/filters/filters.dart index eef4df6..86bd24d 100644 --- a/lib/src/render/filters/filters.dart +++ b/lib/src/render/filters/filters.dart @@ -2,4 +2,4 @@ export 'blur_filter.dart'; export 'color_filter.dart'; export 'composer_filter.dart'; export 'dropshadow_filter.dart'; -export 'glow_filter.dart'; \ No newline at end of file +export 'glow_filter.dart'; diff --git a/lib/src/render/graphics.dart b/lib/src/render/graphics.dart index 2c2e4e5..8830534 100644 --- a/lib/src/render/graphics.dart +++ b/lib/src/render/graphics.dart @@ -127,19 +127,18 @@ class Graphics with RenderUtilMixin implements GxRenderable { texture.root!, tileMode, tileMode, - matrix.toNative()!.storage, + matrix.toNative().storage, ); _addFill(fill); _currentDrawing!.shaderTexture = texture; return this; } - Graphics beginFill(Color color) { + Graphics beginFill(Color color, [bool antiAlias = true]) { if (_holeMode) return this; final fill = Paint(); fill.style = PaintingStyle.fill; - fill.isAntiAlias = true; - // fill.color = Color(color).withOpacity(alpha.clamp(0.0, 1.0)); + fill.isAntiAlias = antiAlias; fill.color = color; _addFill(fill); return this; @@ -350,7 +349,7 @@ class Graphics with RenderUtilMixin implements GxRenderable { texture.root!, tileMode, tileMode, - matrix.toNative()!.storage, + matrix.toNative().storage, ); // _addFill(fill); return this; @@ -697,11 +696,11 @@ class Graphics with RenderUtilMixin implements GxRenderable { } @override - void paint(Canvas? canvas) { + void paint(Canvas canvas) { // TODO : add mask support. if (isMask) { for (var graph in _drawingQueue) { - canvas!.clipPath(graph!.path!, doAntiAlias: false); + canvas.clipPath(graph!.path!, doAntiAlias: false); } return; } @@ -710,7 +709,7 @@ class Graphics with RenderUtilMixin implements GxRenderable { for (var graph in _drawingQueue) { if (graph!.hasPicture) { - canvas!.drawPicture(graph.picture!); + canvas.drawPicture(graph.picture!); break; } final fill = graph.fill!; @@ -740,20 +739,20 @@ class Graphics with RenderUtilMixin implements GxRenderable { graph.vertices!.calculateUvt(graph.shaderTexture); } if (fill.style == PaintingStyle.stroke) { - canvas!.drawRawPoints( + canvas.drawRawPoints( ui.PointMode.lines, graph.vertices!.rawPoints!, fill, ); } else { - canvas!.drawVertices( + canvas.drawVertices( graph.vertices!.rawData!, graph.vertices!.blendMode!, fill, ); } } else { - canvas!.drawPath(graph.path!, fill); + canvas.drawPath(graph.path!, fill); } fill.color = baseColor; diff --git a/lib/src/render/particles/simple_particle_system.dart b/lib/src/render/particles/simple_particle_system.dart index a941b1f..5fbf54b 100644 --- a/lib/src/render/particles/simple_particle_system.dart +++ b/lib/src/render/particles/simple_particle_system.dart @@ -113,13 +113,11 @@ class GSimpleParticleSystem extends GDisplayObject { void _setInitialParticlePosition(GSimpleParticle p) { p.x = useWorldSpace ? x : 0; if (dispersionXVariance > 0) { - p.x += - dispersionXVariance * Math.random() - dispersionXVariance * .5; + p.x += dispersionXVariance * Math.random() - dispersionXVariance * .5; } p.y = useWorldSpace ? y : 0; if (dispersionYVariance > 0) { - p.y += - dispersionYVariance * Math.random() - dispersionYVariance * .5; + p.y += dispersionYVariance * Math.random() - dispersionYVariance * .5; } p.rotation = initialAngle; if (initialAngleVariance > 0) { @@ -159,8 +157,7 @@ class GSimpleParticleSystem extends GDisplayObject { late double particlePivotY; void forceBurst() { - var currentEmission = - (emission + emissionVariance * Math.random()).toInt(); + var currentEmission = (emission + emissionVariance * Math.random()).toInt(); for (var i = 0; i < currentEmission; ++i) { activateParticle(); } @@ -204,7 +201,7 @@ class GSimpleParticleSystem extends GDisplayObject { } @override - void paint(ui.Canvas? canvas) { + void paint(ui.Canvas canvas) { if (!$hasVisibleArea) return; if (useWorldSpace) { render(canvas); @@ -234,8 +231,8 @@ class GSimpleParticleSystem extends GDisplayObject { double? tx, ty, sx, sy; tx = particle.x; ty = particle.y; - sx = particle.scaleX/ texture!.scale!; - sy = particle.scaleY/ texture!.scale!; + sx = particle.scaleX / texture!.scale!; + sy = particle.scaleY / texture!.scale!; if (useWorldSpace) { sx *= scaleX; sy *= scaleY; diff --git a/lib/src/render/svg_shape.dart b/lib/src/render/svg_shape.dart index 98d896d..d71978c 100644 --- a/lib/src/render/svg_shape.dart +++ b/lib/src/render/svg_shape.dart @@ -96,7 +96,7 @@ class GSvgShape extends GDisplayObject { } @override - void paint(Canvas? canvas) { + void paint(Canvas canvas) { if (!_isValid) return; super.paint(canvas); } diff --git a/lib/src/textures/sub_texture.dart b/lib/src/textures/sub_texture.dart index 9ba852f..3512e8c 100644 --- a/lib/src/textures/sub_texture.dart +++ b/lib/src/textures/sub_texture.dart @@ -56,8 +56,8 @@ class GSubTexture extends GTexture { _parent = parent; _ownsParent = ownsParent; _rotated = rotated; - _w = (rotated ? _region!.height : _region!.width)/ scaleModifier; - _h = (rotated ? _region!.width : _region!.height)/ scaleModifier; + _w = (rotated ? _region!.height : _region!.width) / scaleModifier; + _h = (rotated ? _region!.width : _region!.height) / scaleModifier; _scale = parent.scale! * scaleModifier; _sourceRegion = _region!.clone() * scale!; diff --git a/lib/src/textures/texture.dart b/lib/src/textures/texture.dart index 831533b..14e7a18 100644 --- a/lib/src/textures/texture.dart +++ b/lib/src/textures/texture.dart @@ -89,10 +89,10 @@ class GTexture { static ui.Paint sDefaultPaint = ui.Paint(); - void render(ui.Canvas? canvas, [ui.Paint? paint]) { + void render(ui.Canvas canvas, [ui.Paint? paint]) { paint ??= sDefaultPaint; if (scale != 1) { - canvas!.save(); + canvas.save(); canvas.scale(1 / scale!); // canvas.drawImage(root, Offset.zero, paint); _drawImage(canvas, paint); @@ -102,10 +102,11 @@ class GTexture { } } - void _drawImage(ui.Canvas? canvas, ui.Paint paint) { + void _drawImage(ui.Canvas canvas, ui.Paint paint) { + if (_disposed) return; if (scale9Grid != null) { // print('src: $scale9Grid, dst: $scale9GridDest'); - canvas!.drawImageNine( + canvas.drawImageNine( root!, scale9Grid!.toNative(), scale9GridDest!.toNative(), @@ -113,7 +114,7 @@ class GTexture { paint, ); } else { - canvas!.drawImage(root!, ui.Offset.zero, paint); + canvas.drawImage(root!, ui.Offset.zero, paint); } } diff --git a/lib/src/textures/texture_atlas.dart b/lib/src/textures/texture_atlas.dart index cf95aaa..e7eaecf 100644 --- a/lib/src/textures/texture_atlas.dart +++ b/lib/src/textures/texture_atlas.dart @@ -136,7 +136,7 @@ class GTextureAtlas { List getTextures({String? prefix, List? out}) { prefix ??= ''; out ??= []; - final list = getNames(prefix: prefix, out: _names); + final list = getNames(prefix: prefix); for (var name in list) { out.add(getTexture(name)); } diff --git a/lib/src/ticker/ticker.dart b/lib/src/ticker/ticker.dart index 55c030d..ba26ede 100644 --- a/lib/src/ticker/ticker.dart +++ b/lib/src/ticker/ticker.dart @@ -1,12 +1,12 @@ import 'package:flutter/scheduler.dart'; + import '../events/events.dart'; class GTicker { GTicker(); Ticker? _ticker; - EventSignal? _onFrame; - EventSignal get onFrame => _onFrame ??= EventSignal(); + final onFrame = EventSignal(); VoidCallback? _nextFrameCallback; @@ -25,7 +25,9 @@ class GTicker { bool get isTicking => _ticker?.isTicking ?? false; bool get isActive => _ticker?.isActive ?? false; + double get currentDeltaTime => _currentDeltaTime; + double get currentDeltaRatio => _currentDeltaRatio; void resume() { @@ -43,6 +45,7 @@ class GTicker { /// process timeframe in integer MS double _currentTime = 0; double _currentDeltaTime = 0; + // 0-100% double _currentDeltaRatio = 0.0; @@ -64,32 +67,23 @@ class GTicker { _nextFrameCallback = null; callback?.call(); } - _onFrame?.dispatch(_currentDeltaTime); + onFrame.dispatch(_currentDeltaTime); // advanceTime(_currentDeltaTime); // render(); } void dispose() { - _onFrame?.removeAll(); - _onFrame = null; - + onFrame.removeAll(); + // onFrame = null; _ticker?.stop(canceled: true); _ticker?.dispose(); _ticker = null; } } -Stopwatch? _stopwatch; - -void _initTimer() { - if (_stopwatch != null) return; - _stopwatch = Stopwatch(); - _stopwatch!.start(); -} +Stopwatch _stopwatch = Stopwatch(); int getTimer() { - if (_stopwatch == null) { - _initTimer(); - } - return _stopwatch!.elapsedMilliseconds; + if (!_stopwatch.isRunning) _stopwatch.start(); + return _stopwatch.elapsedMilliseconds; } diff --git a/lib/src/tween/src/extensions/display_object.dart b/lib/src/tween/src/extensions/display_object.dart index 49d092a..0b0556f 100644 --- a/lib/src/tween/src/extensions/display_object.dart +++ b/lib/src/tween/src/extensions/display_object.dart @@ -76,7 +76,7 @@ extension GTweenDiplayObjectExt on GDisplayObject { ); } - /// Shortcut to assign multiple properties and render immeditatly. + /// Shortcut to assign multiple properties and render immediately. /// Doesn't wait for the next tick update. void setProps({ Object? x, diff --git a/lib/src/tween/src/gtween.dart b/lib/src/tween/src/gtween.dart index cf22a17..d35566a 100644 --- a/lib/src/tween/src/gtween.dart +++ b/lib/src/tween/src/gtween.dart @@ -285,7 +285,7 @@ class GTween { _inited = true; } - /// initialiazes the PropTween to be used in the target Object. + /// initializes the PropTween to be used in the target Object. void _initProps(Object? target) { if (target == null) return; for (final key in vars!.keys) { diff --git a/lib/src/tween/src/mixins/tweenable.dart b/lib/src/tween/src/mixins/tweenable.dart index 04561cf..b33c2bb 100644 --- a/lib/src/tween/src/mixins/tweenable.dart +++ b/lib/src/tween/src/mixins/tweenable.dart @@ -26,18 +26,17 @@ mixin GTweenable { /// Also used by [GTween] to reference internally the "_nativeTarget" instead /// of the [GTweenable] instance. So you can "kill" the tween by [GTweenable] /// or using the actual object that you plan to Tween. - Object? target; + late Object? target; /// override to know which properties will change. void setTweenProp(PropTween tweenProp) { final key = '${tweenProp.p}'; - if( !_lerps.containsKey(key)) return ; + if (!_lerps.containsKey(key)) return; final lerpObj = _lerps[key]!; lerpObj.to = tweenProp.cObj; tweenProp.c = 1.0; } - // final Set _lerpsProps = {}; final Map _lerps = {}; @override @@ -58,7 +57,7 @@ mixin GTweenable { void setProperty(Object prop, double value) { final key = '$prop'; - if (_lerps.containsKey(key)){ + if (_lerps.containsKey(key)) { _lerps[key]?.resolve(value); } else { if (_accessors == null) initProps(); diff --git a/lib/src/tween/src/wraps/filter_wraps.dart b/lib/src/tween/src/wraps/filter_wraps.dart index e600fc5..54a1f56 100644 --- a/lib/src/tween/src/wraps/filter_wraps.dart +++ b/lib/src/tween/src/wraps/filter_wraps.dart @@ -1,7 +1,7 @@ part of gtween; class GTweenableBlur with GTweenable { - static GTweenable? wrap(Object target) { + static GTweenable? wrap(Object? target) { if (target is! GBlurFilter) return null; return GTweenableBlur(target); } @@ -63,7 +63,7 @@ class GTweenableBlur with GTweenable { } class GTweenableDropShadowFilter with GTweenable { - static GTweenable? wrap(Object target) { + static GTweenable? wrap(Object? target) { if (target is! GDropShadowFilter) return null; return GTweenableDropShadowFilter(target); } @@ -141,7 +141,7 @@ class GTweenableDropShadowFilter with GTweenable { } class GTweenableGlowFilter with GTweenable { - static GTweenable? wrap(Object target) { + static GTweenable? wrap(Object? target) { if (target is! GlowFilter) return null; return GTweenableGlowFilter(target); } diff --git a/lib/src/utils/http/http.dart b/lib/src/utils/http/http.dart index f9c23d7..cdf4464 100644 --- a/lib/src/utils/http/http.dart +++ b/lib/src/utils/http/http.dart @@ -1 +1 @@ -export '_http_io.dart' if (dart.library.html) '_http_web.dart'; \ No newline at end of file +export '_http_io.dart' if (dart.library.html) '_http_web.dart'; diff --git a/lib/src/utils/keyboard_util.dart b/lib/src/utils/keyboard_util.dart index 214a1c3..5c01cde 100644 --- a/lib/src/utils/keyboard_util.dart +++ b/lib/src/utils/keyboard_util.dart @@ -364,7 +364,7 @@ class GKeyboard { } static void _onKey(KeyboardEventData input) { - final k = input.rawEvent!.logicalKey; + final k = input.rawEvent.logicalKey; if (input.type == KeyEventType.down) { _pressed[k] = true; } else { diff --git a/lib/src/utils/layout_utils.dart b/lib/src/utils/layout_utils.dart index 3b046e0..51fc5f2 100644 --- a/lib/src/utils/layout_utils.dart +++ b/lib/src/utils/layout_utils.dart @@ -2,7 +2,7 @@ import 'package:flutter/widgets.dart'; import '../../graphx.dart'; -/// roipeker 2021... +/// roipeker 2021 /// some utility functions to layout DisplayObjects: /// - LayoutUtils.row /// - LayoutUtils.col @@ -13,7 +13,7 @@ class LayoutUtils { static Color debugColor = kColorMagenta.withOpacity(.1); /// behaviour to image resizing in a parent container. - /// `objW` and `objH` if provided, shuold be the original size of the asset. + /// `objW` and `objH` if provided, should be the original size of the asset. /// `canvasW` and `canvasH`, are the actual target bounds where you wanna /// resize your image. /// `fit` behaves pretty much the same as in Flutter. @@ -242,7 +242,7 @@ class LayoutUtils { currentY += itm.height + gap; } } else if (axisAlign == MainAxisAlignment.spaceEvenly) { - /// calcaulte gap. + /// calculate gap. gap = (height - itemsH) / (numItems + 1); startY += gap; for (var i = 0; i < numItems; ++i) { @@ -286,6 +286,9 @@ class LayoutUtils { }) { var currentX = .0, maxH = .0, maxW = .0, itemsW = .0; final numItems = items.length; + if (numItems == 0) { + return; + } /// default to start. for (var i = 0; i < numItems; ++i) { @@ -294,6 +297,9 @@ class LayoutUtils { itm.x = startX + currentX; maxH = Math.max(maxH, itm.height); var itmW = itm.width; + if (itm is GText && itmW.isInfinite) { + itmW = itm.textWidth; + } itemsW += itmW; currentX += itmW + gap; } @@ -332,7 +338,11 @@ class LayoutUtils { for (var i = 0; i < numItems; ++i) { var itm = items[i]; itm.x = startX + currentX; - currentX += itm.width + gap; + var itmW = itm.width; + if (itm is GText && itmW.isInfinite) { + itmW = itm.textWidth; + } + currentX += itmW + gap; } } else if (axisAlign == MainAxisAlignment.end) { startX += width - maxW; @@ -342,20 +352,28 @@ class LayoutUtils { currentX += itm.width + gap; } } else if (axisAlign == MainAxisAlignment.spaceEvenly) { - /// calcaulte gap. + /// calculate gap. gap = (width - itemsW) / (numItems + 1); startX += gap; for (var i = 0; i < numItems; ++i) { var itm = items[i]; itm.x = startX + currentX; - currentX += itm.width + gap; + var itmW = itm.width; + if (itm is GText && itmW.isInfinite) { + itmW = itm.textWidth; + } + currentX += itmW + gap; } } else if (axisAlign == MainAxisAlignment.spaceBetween) { gap = (width - itemsW) / (numItems - 1); for (var i = 0; i < numItems; ++i) { var itm = items[i]; itm.x = startX + currentX; - currentX += itm.width + gap; + var itmW = itm.width; + if (itm is GText && itmW.isInfinite) { + itmW = itm.textWidth; + } + currentX += itmW + gap; } } else if (axisAlign == MainAxisAlignment.spaceAround) { gap = (width - itemsW) / (numItems); @@ -363,7 +381,11 @@ class LayoutUtils { for (var i = 0; i < numItems; ++i) { var itm = items[i]; itm.x = startX + currentX; - currentX += itm.width + gap; + var itmW = itm.width; + if (itm is GText && itmW.isInfinite) { + itmW = itm.textWidth; + } + currentX += itmW + gap; } } } diff --git a/lib/src/utils/math_utils.dart b/lib/src/utils/math_utils.dart index b783add..205396e 100644 --- a/lib/src/utils/math_utils.dart +++ b/lib/src/utils/math_utils.dart @@ -3,6 +3,7 @@ import '../../graphx.dart'; double deg2rad(double deg) => deg / 180.0 * Math.PI; + double rad2deg(double rad) => rad / Math.PI * 180.0; abstract class MathUtils { diff --git a/lib/src/utils/matrix_utils.dart b/lib/src/utils/matrix_utils.dart index 4f38be5..46ea6fa 100644 --- a/lib/src/utils/matrix_utils.dart +++ b/lib/src/utils/matrix_utils.dart @@ -9,12 +9,12 @@ abstract class MatrixUtils { var sinY = Math.sin(skewY); var cosY = Math.cos(skewY); matrix.setTo( - matrix.a* cosY - matrix.b* sinX, - matrix.a* sinY + matrix.b* cosX, - matrix.c* cosY - matrix.d* sinX, - matrix.c* sinY + matrix.d* cosX, - matrix.tx* cosY - matrix.ty* sinX, - matrix.tx* sinY + matrix.ty* cosX, + matrix.a * cosY - matrix.b * sinX, + matrix.a * sinY + matrix.b * cosX, + matrix.c * cosY - matrix.d * sinX, + matrix.c * sinY + matrix.d * cosX, + matrix.tx * cosY - matrix.ty * sinX, + matrix.tx * sinY + matrix.ty * cosX, ); } @@ -25,14 +25,14 @@ abstract class MatrixUtils { var maxX = -10000000.0; var minY = 10000000.0; var maxY = -10000000.0; - var tx1 = matrix.a* rect.x+ matrix.c* rect.y+ matrix.tx; - var ty1 = matrix.d* rect.y+ matrix.b* rect.x+ matrix.ty; - var tx2 = matrix.a* rect.x+ matrix.c* rect.bottom + matrix.tx; - var ty2 = matrix.d* rect.bottom + matrix.b* rect.x+ matrix.ty; - var tx3 = matrix.a* rect.right + matrix.c* rect.y+ matrix.tx; - var ty3 = matrix.d* rect.y+ matrix.b* rect.right + matrix.ty; - var tx4 = matrix.a* rect.right + matrix.c* rect.bottom + matrix.tx; - var ty4 = matrix.d* rect.bottom + matrix.b* rect.right + matrix.ty; + var tx1 = matrix.a * rect.x + matrix.c * rect.y + matrix.tx; + var ty1 = matrix.d * rect.y + matrix.b * rect.x + matrix.ty; + var tx2 = matrix.a * rect.x + matrix.c * rect.bottom + matrix.tx; + var ty2 = matrix.d * rect.bottom + matrix.b * rect.x + matrix.ty; + var tx3 = matrix.a * rect.right + matrix.c * rect.y + matrix.tx; + var ty3 = matrix.d * rect.y + matrix.b * rect.right + matrix.ty; + var tx4 = matrix.a * rect.right + matrix.c * rect.bottom + matrix.tx; + var ty4 = matrix.d * rect.bottom + matrix.b * rect.right + matrix.ty; if (minX > tx1) minX = tx1; if (minX > tx2) minX = tx2; if (minX > tx3) minX = tx3; diff --git a/lib/src/utils/texture_utils.dart b/lib/src/utils/texture_utils.dart index 1e6533e..ff3d2d7 100644 --- a/lib/src/utils/texture_utils.dart +++ b/lib/src/utils/texture_utils.dart @@ -77,7 +77,8 @@ mixin GTextureUtils { double rotation = 0, String? id, }) async { - _g.clear() + _g + .clear() .beginFill(color) .drawPolygonFaces(0, 0, w / 2, 3, rotation) .endFill(); @@ -109,8 +110,8 @@ mixin GTextureUtils { h ??= w; /// create SubTextures from the main Texture. - var cols = base.sourceRect!.width/ w; - var rows = base.sourceRect!.height/ h; + var cols = base.sourceRect!.width / w; + var rows = base.sourceRect!.height / h; var total = cols * rows; var output = []; final _w = w.toDouble(); diff --git a/lib/src/utils/utils.dart b/lib/src/utils/utils.dart index edaf74e..1072952 100644 --- a/lib/src/utils/utils.dart +++ b/lib/src/utils/utils.dart @@ -13,5 +13,6 @@ export 'painter_utils.dart'; export 'pools.dart'; export 'string_utils.dart'; export 'svg_utils.dart'; +export 'svg_utils.dart'; export 'system_utils.dart'; -export 'texture_utils.dart'; \ No newline at end of file +export 'texture_utils.dart'; diff --git a/lib/src/widgets/graphics_clipper.dart b/lib/src/widgets/graphics_clipper.dart index a70438d..3b62592 100644 --- a/lib/src/widgets/graphics_clipper.dart +++ b/lib/src/widgets/graphics_clipper.dart @@ -40,7 +40,7 @@ abstract class GraphicsClipper extends CustomClipper { final m = Pool.getMatrix(); m.setTransform( x, y, pivotX, pivotY, scaleX, scaleY, skewX, skewY, rotation); - final result = p.transform(m.toNative()!.storage); + final result = p.transform(m.toNative().storage); Pool.putMatrix(m); return result; } diff --git a/lib/src/widgets/graphx_widget.dart b/lib/src/widgets/graphx_widget.dart index 7e322d8..885a3d4 100644 --- a/lib/src/widgets/graphx_widget.dart +++ b/lib/src/widgets/graphx_widget.dart @@ -21,6 +21,10 @@ class SceneBuilderWidget extends StatefulWidget { /// defaults to capture translucent("empty") areas. final HitTestBehavior pointerBehaviour; + /// Wraps the [CustomPaint] in an expanded SizedBox + /// so it takes the available space in the parent. + final bool autoSize; + const SceneBuilderWidget({ Key? key, required this.builder, @@ -28,6 +32,7 @@ class SceneBuilderWidget extends StatefulWidget { this.painterIsComplex = true, this.mouseOpaque = true, this.pointerBehaviour = HitTestBehavior.translucent, + this.autoSize = true, }) : super(key: key); @override @@ -41,7 +46,6 @@ class _SceneBuilderWidgetState extends State { void initState() { super.initState(); _controller = widget.builder(); - _controller.resolveWindowBounds = _getRenderObjectWindowBounds; _controller.$init(); } @@ -76,8 +80,13 @@ class _SceneBuilderWidgetState extends State { foregroundPainter: _controller.buildFrontPainter(), isComplex: widget.painterIsComplex, willChange: _controller.config.painterMightChange(), - child: widget.child ?? Container(), + child: widget.child ?? const SizedBox(), ); + if (widget.autoSize) { + child = SizedBox.expand( + child: child, + ); + } var converter = _controller.$inputConverter; if (_controller.config.usePointer) { diff --git a/pubspec.lock b/pubspec.lock index 42ef993..1e9c8c6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,7 +7,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.5.0" + version: "2.6.1" boolean_selector: dependency: transitive description: @@ -141,7 +141,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" stack_trace: dependency: transitive description: @@ -176,7 +176,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.19" + version: "0.3.0" typed_data: dependency: transitive description: @@ -197,7 +197,7 @@ packages: name: xml url: "https://pub.dartlang.org" source: hosted - version: "5.1.0" + version: "5.1.1" sdks: dart: ">=2.12.0 <3.0.0" flutter: ">=1.24.0-7.0" diff --git a/pubspec.yaml b/pubspec.yaml index 5b76845..c68ec4a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: graphx description: Render API on top of CustomPainter to power-up your Flutter apps to the next level. -version: 1.0.0-nullsafety.0 +version: 1.0.1 homepage: https://github.com/roipeker/graphx environment: @@ -9,7 +9,7 @@ environment: dependencies: flutter: sdk: flutter - xml: ^5.1.0 + xml: ^5.1.1 http: ^0.13.3 flutter_svg: ^0.22.0