TileSelector.hx 6.1 KB

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