Group.hx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package h2d.filter;
  2. /**
  3. Applies an array of Filters to a single Object with several limitations.
  4. * If all filters in the Group are disabled - `Filter.enable` will report `false` even if Group itself is enabled.
  5. * `Filter.boundsExtend` and `Filter.autoBounds` are automatically managed by Group instance.
  6. * `boundsExtend` is a sum of all filter extends and `autoBounds` enabled only when all filters have it enabled.
  7. When `autoBounds` is disabled, bounds are a result of calling `Filter.getBounds` on children filters, but most likely
  8. will contain only the bounds filled by last filter, because `Object.getBounds` clears the `Bounds` instance.
  9. Ensure that all relevant filters are added to Group prior binding it to any Object. Behavior is undefined otherwise.
  10. **/
  11. class Group extends Filter {
  12. var filters : Array<Filter>;
  13. /**
  14. Create a new filter Group.
  15. @param filters Optional list of the Filters bound to the group.
  16. **/
  17. public function new( ?filters : Array<Filter> ) {
  18. super();
  19. this.filters = filters == null ? [] : filters;
  20. }
  21. override function get_enable() {
  22. if( !enable ) return false;
  23. for( f in filters ) if( enable ) return true;
  24. return false;
  25. }
  26. /**
  27. Adds new Filter `f` to the Group.
  28. Due to implementation specifics, if Group was already bound, new filters won't receive a `bind` call.
  29. **/
  30. public function add( f : Filter ) {
  31. filters.push(f);
  32. }
  33. /**
  34. Removes the Filter `f` from the Group.
  35. Due to implementation specifics, removed filter won't receive an `unbind` call even if it was bound previously.
  36. **/
  37. public function remove( f : Filter ) {
  38. return filters.remove(f);
  39. }
  40. override function bind(s:Object) {
  41. for( f in filters )
  42. if( f.enable )
  43. f.bind(s);
  44. }
  45. override function unbind(s:Object) {
  46. for( f in filters )
  47. if( f.enable )
  48. f.unbind(s);
  49. }
  50. override function sync( ctx:RenderContext, s : Object ) {
  51. this.autoBounds = true;
  52. this.boundsExtend = 0;
  53. for( f in filters ) {
  54. if (!f.enable) continue;
  55. f.sync(ctx, s);
  56. if(f.boundsExtend > 0) {
  57. boundsExtend += f.boundsExtend;
  58. }
  59. if( !f.autoBounds ) autoBounds = false;
  60. }
  61. }
  62. override function getBounds(s:Object, bounds:h2d.col.Bounds, scale:h2d.col.Point) {
  63. for( f in filters )
  64. if( f.enable && !f.autoBounds )
  65. f.getBounds(s, bounds, scale);
  66. }
  67. override function draw( ctx : RenderContext, input : h2d.Tile ) {
  68. var xMin = input.dx;
  69. var yMin = input.dy;
  70. var start = input;
  71. for( f in filters ) {
  72. if (!f.enable) continue;
  73. var prev = input;
  74. input = f.draw(ctx, input);
  75. if( input == null )
  76. return null;
  77. if( input != prev ) {
  78. input.dx += xMin;
  79. input.dy += yMin;
  80. }
  81. }
  82. if( start != input ) {
  83. input.dx -= xMin;
  84. input.dy -= yMin;
  85. }
  86. return input;
  87. }
  88. }