2
0

TileSelector.hx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. package hide.comp;
  2. class TileSelector extends Component {
  3. public var file(default,set) : String;
  4. public var size(default,set) : Int;
  5. public var value(default,set) : Null<{ x : Int, y : Int, width : Int, height : Int }>;
  6. public var allowRectSelect(default,set) : Bool;
  7. public var allowSizeSelect(default,set) : Bool;
  8. public var allowFileChange(default,set) : Bool;
  9. var valueDisp : Element;
  10. var cursor : Element;
  11. var image : Element;
  12. var movePos = { x : 0, y : 0, moving : false, moved : false };
  13. var cursorPos : { x : Int, y : Int, x2 : Int, y2 : Int, select : Bool };
  14. var width : Int;
  15. var height : Int;
  16. var zoom : Float;
  17. var imageElt : js.html.ImageElement;
  18. public function new(file,size,?parent,?el) {
  19. super(parent,el);
  20. element.addClass("hide-tileselect");
  21. this.file = file;
  22. this.size = size;
  23. }
  24. function set_file(file) {
  25. this.file = file;
  26. rebuild();
  27. return file;
  28. }
  29. function set_value(v) {
  30. value = v;
  31. if( cursorPos != null ) updateCursor();
  32. return v;
  33. }
  34. function set_size(size) {
  35. this.size = size;
  36. rebuild();
  37. return size;
  38. }
  39. function set_allowRectSelect(b) {
  40. allowRectSelect = b;
  41. rebuild();
  42. return b;
  43. }
  44. function set_allowSizeSelect(b) {
  45. allowSizeSelect = b;
  46. rebuild();
  47. return b;
  48. }
  49. function set_allowFileChange(b) {
  50. allowFileChange = b;
  51. rebuild();
  52. return b;
  53. }
  54. function updateCursor() {
  55. var k = size * zoom;
  56. var width = hxd.Math.abs(cursorPos.x2 - cursorPos.x) + 1;
  57. var height = hxd.Math.abs(cursorPos.y2 - cursorPos.y) + 1;
  58. cursor.css({left: hxd.Math.min(cursorPos.x,cursorPos.x2)*k,top:hxd.Math.min(cursorPos.y,cursorPos.y2)*k,width:width*k,height:height*k});
  59. cursor.toggle(cursorPos.x >= 0);
  60. if( value != null ) {
  61. valueDisp.show();
  62. valueDisp.css({left:value.x*k,top:value.y*k,width:value.width*k,height:value.height*k});
  63. } else
  64. valueDisp.hide();
  65. }
  66. function rescale() {
  67. image.height(height*zoom).width(width*zoom);
  68. image.css("background-size",(width*zoom)+"px "+(height*zoom)+"px");
  69. updateCursor();
  70. }
  71. function rebuild() {
  72. element.empty();
  73. element.off();
  74. element.click((e) -> e.stopPropagation());
  75. element.attr("tabindex","0");
  76. element.focus();
  77. element.on("keydown", function(e) {
  78. if( e.keyCode == 27 ) {
  79. onChange(true);
  80. }
  81. });
  82. var tool = new Toolbar(element);
  83. if( allowFileChange ) {
  84. var tex = new hide.comp.TextureSelect(tool.element);
  85. tex.path = file;
  86. tex.onChange = function() this.file = tex.path;
  87. }
  88. if( allowSizeSelect ) {
  89. var size = new Element('<span><input type="number" value="$size">px</span>').appendTo(tool.element);
  90. size.find("input").on("blur",function(e:js.jquery.Event) {
  91. var nsize = Std.parseInt(e.getThis().val());
  92. if( this.size != nsize && nsize != null && nsize > 0 )
  93. this.size = nsize;
  94. }).on("keydown", function(e:js.jquery.Event) {
  95. if( e.keyCode == 13 ) size.find("input").blur();
  96. });
  97. }
  98. if( tool.element.children().length == 0 )
  99. tool.remove();
  100. var url = ide.getUnCachedUrl(file);
  101. var scroll = new Element("<div class='flex-scroll'><div class='scroll'>").appendTo(element).find(".scroll");
  102. image = new Element('<div class="tile" style="background-image:url(\'$url\')"></div>').appendTo(scroll);
  103. valueDisp = new Element('<div class="valueDisp">').appendTo(image);
  104. cursor = new Element('<div class="cursor">').appendTo(image);
  105. cursorPos = { x : -1, y : -1, x2 : -1, y2 : -1, select : false };
  106. var i = js.Browser.document.createImageElement();
  107. this.imageElt = i;
  108. i.onload = function(_) {
  109. if( imageElt != i ) return;
  110. width = i.width;
  111. height = i.height;
  112. zoom = Math.floor(hxd.Math.min(800 / width, 580 / height));
  113. if( zoom <= 0 ) zoom = 1;
  114. scroll.on("mousewheel", function(e:js.jquery.Event) {
  115. if( untyped e.originalEvent.wheelDelta > 0 )
  116. zoom++;
  117. else if( zoom > 1 )
  118. zoom--;
  119. rescale();
  120. e.preventDefault();
  121. });
  122. scroll.parent().on("mousedown", function(e) {
  123. if( e.button == 0 ) {
  124. movePos.moving = true;
  125. movePos.x = e.offsetX;
  126. movePos.y = e.offsetY;
  127. }
  128. });
  129. scroll.parent().on("mousemove", function(e) {
  130. if( movePos.moving ) {
  131. var dx = e.offsetX - movePos.x;
  132. var dy = e.offsetY - movePos.y;
  133. scroll[0].scrollBy(-dx,-dy);
  134. movePos.moved = true;
  135. }
  136. });
  137. image.on("mousemove", function(e:js.jquery.Event) {
  138. if( movePos.moving )
  139. return;
  140. var k = zoom * size;
  141. var x = Math.floor(e.offsetX / k);
  142. var y = Math.floor(e.offsetY / k);
  143. if( (x+1) * size > i.width ) x--;
  144. if( (y+1) * size > i.height ) y--;
  145. if( cursorPos.select ) {
  146. cursorPos.x2 = x;
  147. cursorPos.y2 = y;
  148. } else {
  149. cursorPos.x = cursorPos.x2 = x;
  150. cursorPos.y = cursorPos.y2 = y;
  151. }
  152. updateCursor();
  153. });
  154. image.on("mousedown", function(e:js.jquery.Event) {
  155. if( e.button == 2 && allowRectSelect )
  156. cursorPos.select = true;
  157. });
  158. image.on("mouseup", function(e:js.jquery.Event) {
  159. e.preventDefault();
  160. var moved = movePos.moved;
  161. movePos.moved = false;
  162. movePos.moving = false;
  163. cursorPos.select = false;
  164. if( e.button == 0 && moved )
  165. return;
  166. if( cursorPos.x2 >= cursorPos.x ) {
  167. value.x = cursorPos.x;
  168. value.width = cursorPos.x2 - cursorPos.x + 1;
  169. } else {
  170. value.x = cursorPos.x2;
  171. value.width = cursorPos.x - cursorPos.x2 + 1;
  172. }
  173. if( cursorPos.y2 >= cursorPos.y ) {
  174. value.y = cursorPos.y;
  175. value.height = cursorPos.y2 - cursorPos.y + 1;
  176. } else {
  177. value.y = cursorPos.y2;
  178. value.height = cursorPos.y - cursorPos.y2 + 1;
  179. }
  180. onChange(false);
  181. });
  182. image.on("contextmenu", function(e) {
  183. e.preventDefault();
  184. });
  185. rescale();
  186. };
  187. i.src = url;
  188. }
  189. public dynamic function onChange( cancel : Bool ) {
  190. }
  191. }