PageRenderTime 55ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/flash/Track.hx

http://github.com/brentp/gobe
Haxe | 361 lines | 295 code | 38 blank | 28 comment | 22 complexity | fef11176b7bb600d0967ffecc2b49a51 MD5 | raw file
  1. import flash.display.Sprite;
  2. import flash.events.MouseEvent;
  3. import Gobe;
  4. class SubTrack extends Sprite {
  5. public var track:Track;
  6. public var fill_color:UInt;
  7. public var other:Track;
  8. public var track_height:Float;
  9. /// other is a pointer to the other track which shares
  10. /// pairs with this one.
  11. public function new(track:Track, other:Track, track_height:Float){
  12. super();
  13. this.track = track;
  14. this.other = other;
  15. this.track_height = track_height;
  16. this.draw();
  17. this.addEventListener(MouseEvent.CLICK, onClick);
  18. this.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
  19. this.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
  20. }
  21. public override function toString(){
  22. var s = "SubTrack(" + this.track.title;
  23. if(this.track != this.other){
  24. s += ", " + this.other.title;
  25. }
  26. return s + ")";
  27. }
  28. public function clear(){
  29. var i = this.numChildren;
  30. while(i-- > 0){
  31. this.removeChildAt(i);
  32. }
  33. }
  34. public function onClick(e:MouseEvent){
  35. if(e.shiftKey){
  36. for(i in 0 ... this.numChildren){
  37. if (!Std.is(this.getChildAt(i), Annotation)) { continue; }
  38. var a = cast(this.getChildAt(i), Annotation);
  39. a.onClick(e);
  40. }
  41. }
  42. else if(e.ctrlKey){
  43. trace('ctrl');
  44. }
  45. }
  46. public function onMouseOut(e:MouseEvent){
  47. if(!e.ctrlKey){ return; }
  48. for(i in 0 ... this.numChildren){
  49. var a = cast(this.getChildAt(i), Annotation);
  50. for (ed in a.edges){
  51. Gobe.edges[ed].visible = false;
  52. }
  53. }
  54. }
  55. public function onMouseOver(e:MouseEvent){
  56. if (! e.ctrlKey ){ return; }
  57. trace('clicking');
  58. e.shiftKey = true;
  59. onClick(e);
  60. }
  61. public function draw(){
  62. var sw = flash.Lib.current.stage.stageWidth - 1;
  63. var off = 3;
  64. var g = this.graphics;
  65. g.lineStyle(0, 0, 0.0);
  66. g.beginFill(0, 0); // TODO: allow setting track background via css or csv.
  67. g.moveTo(0, -this.track_height);
  68. g.lineTo(sw, -this.track_height);
  69. g.lineTo(sw, 0);
  70. g.lineTo(0, 0);
  71. g.endFill();
  72. }
  73. }
  74. class InfoTrack extends Sprite {
  75. public var track:Track;
  76. public function new(track:Track){
  77. super();
  78. this.track = track;
  79. this.draw();
  80. }
  81. public function draw() {
  82. this.draw_ruler();
  83. var g = this.graphics;
  84. var height = Options.info_track_height;
  85. var border = Track.border_thickness / 2;
  86. /*
  87. g.moveTo(0, 0);
  88. g.beginFill(0, 0.1);
  89. var sw = flash.Lib.current.stage.stageWidth;
  90. g.lineTo(sw, 0);
  91. g.lineTo(sw, Gobe.info_track_height);
  92. g.lineTo(0, Gobe.info_track_height);
  93. g.lineTo(0, 0);
  94. g.endFill();
  95. */
  96. g.lineStyle(border, 0);
  97. g.moveTo(border, height - border);
  98. g.lineTo(flash.Lib.current.stage.stageWidth, height - border);
  99. }
  100. public function draw_ruler(){
  101. var g = this.graphics;
  102. var ymid = Track.border_thickness;
  103. var height = Options.info_track_height / 2;
  104. var border = Track.border_thickness / 2;
  105. var sw = flash.Lib.current.stage.stageWidth;
  106. var tw = track.bpmax - track.bpmin;
  107. if (tw < 0) tw = -tw; // get absolute value
  108. var baseline_lw = 2;
  109. var major_tick_lw = 2;
  110. var minor_tick_lw = 1;
  111. // baseline
  112. g.lineStyle(baseline_lw, 0x0000ff, .2);
  113. g.moveTo(border, height - border);
  114. g.lineTo(flash.Lib.current.stage.stageWidth, height - border);
  115. var stride = Util.autoscale(tw);
  116. // major ticks
  117. var xpos = stride;
  118. var xpos_px:Float;
  119. while (xpos < tw) {
  120. xpos_px = border + xpos * (sw - 2*border) / tw;
  121. g.lineStyle(major_tick_lw, 0x0000ff);
  122. g.moveTo(xpos_px, .4*height);
  123. g.lineTo(xpos_px, 1.4*height);
  124. // tick labels
  125. var t = new MTextField();
  126. t.y = ymid;
  127. t.x = xpos_px;
  128. t.styleSheet.setStyle('p', {fontSize: Gobe.fontSize - 1, display: 'inline',
  129. fontFamily: 'Arial,serif,sans-serif'});
  130. t.htmlText = '<p>' + (Util.human_readable(xpos)) + '</p>';
  131. t.autoSize = flash.text.TextFieldAutoSize.LEFT;
  132. addChild(t);
  133. xpos += stride;
  134. }
  135. // minor ticks
  136. }
  137. }
  138. class AnnoTrack extends SubTrack {
  139. public var plus:AnnoSubTrack;
  140. public var minus:AnnoSubTrack;
  141. public var both:AnnoSubTrack;
  142. public var ttf:MTextField;
  143. public var subanno_id:String;
  144. public function new(track:Track, track_height:Float, subanno_id:String=""){
  145. super(track, track, track_height);
  146. track.anno_track = this;
  147. this.subanno_id = subanno_id;
  148. plus = new AnnoSubTrack(track, track_height / 2);
  149. minus = new AnnoSubTrack(track, track_height / 2);
  150. both = new AnnoSubTrack(track, track_height);
  151. addChild(both);
  152. addChild(plus);
  153. addChild(minus);
  154. both.y = minus.y = track_height / 2;
  155. //minus.x = 19;
  156. track.subtracks.set(subanno_id + '+', plus);
  157. track.subtracks.set(subanno_id + '-', minus);
  158. track.subtracks.set(subanno_id + '0', both);
  159. track.addChildAt(this, 0);
  160. if (subanno_id == ""){
  161. this.setUpTitleTextField();
  162. }
  163. }
  164. public function setUpTitleTextField(){
  165. this.ttf = new MTextField();
  166. ttf.y = -both.y;
  167. ttf.x = 6;
  168. ttf.border = true;
  169. ttf.borderColor = 0xcccccc;
  170. ttf.opaqueBackground = 0xf4f4f4;
  171. ttf.autoSize = flash.text.TextFieldAutoSize.LEFT;
  172. ttf.styleSheet.setStyle('p', {fontSize: Gobe.fontSize, display: 'inline',
  173. fontFamily: 'Arial,serif,sans-serif'});
  174. ttf.htmlText = '<p>' + track.title + '</p>';
  175. this.addChild(ttf);
  176. }
  177. public override function draw(){
  178. var sw = flash.Lib.current.stage.stageWidth - Track.border_thickness - 1;
  179. var off = 3;
  180. var g = this.graphics;
  181. // the lines around the sub-anno tracks.
  182. g.lineStyle(0.9, 0xffffff, 1);
  183. g.beginFill(Options.anno_track_background_color); // TODO: allow setting track background via css or csv.
  184. g.moveTo(Track.border_thickness, -this.track_height/2);
  185. g.lineTo(sw, -this.track_height/2);
  186. g.lineTo(sw, this.track_height/2);
  187. g.lineTo(Track.border_thickness, this.track_height/2);
  188. g.endFill();
  189. var mid = 0;
  190. // the dotted line in the middle.
  191. g.lineStyle(1, 0x444444, 0.9, false,
  192. flash.display.LineScaleMode.NORMAL,
  193. flash.display.CapsStyle.ROUND);
  194. var dash_w:Float = 4;
  195. var gap_w:Float = 3.5;
  196. g.moveTo(gap_w / 2, mid);
  197. var dx = dash_w;
  198. while(dx < sw + dash_w) {
  199. g.lineTo(dx, mid);
  200. dx += gap_w;
  201. g.moveTo(dx, mid);
  202. dx += dash_w;
  203. }
  204. }
  205. public override function onClick(e:MouseEvent){
  206. /* since events dont get propagated to the both subtrack, here we
  207. do it manually, checking if each feature in the both subtrack contains
  208. the click.
  209. */
  210. super.onClick(e);
  211. var n:Int = both.numChildren;
  212. var i:Int;
  213. for(i in 0 ... n){
  214. var a_sprite = both.getChildAt(i);
  215. if(a_sprite.hitTestPoint(e.stageX, e.stageY)){
  216. cast(a_sprite, Annotation).onClick(e);
  217. }
  218. }
  219. }
  220. }
  221. class AnnoSubTrack extends SubTrack {
  222. public function new(track:Track, track_height:Float){
  223. super(track, track, track_height);
  224. }
  225. }
  226. class HSPTrack extends SubTrack {
  227. public var ttf:MTextField;
  228. public function new(track:Track, other:Track, track_height:Float){
  229. super(track, other, track_height);
  230. this.setUpTextField();
  231. }
  232. public override function toString(){
  233. var s = "HSPTrack(" + this.track.title;
  234. if(this.track != this.other){
  235. s += ", " + this.other.title;
  236. }
  237. return s + ")";
  238. }
  239. public function setUpTextField(){
  240. this.ttf = new MTextField();
  241. ttf.multiline = true;
  242. ttf.border = false;
  243. ttf.borderColor = 0xcccccc;
  244. //ttf.opaqueBackground = 0xf4f4f4;
  245. ttf.autoSize = flash.text.TextFieldAutoSize.LEFT;
  246. this.addChildAt(ttf, this.numChildren);
  247. ttf.styleSheet.setStyle('p', {fontSize: Gobe.fontSize - 1, display: 'inline', fontColor: '0xcccccc',
  248. fontFamily: 'arial,sans-serif'});
  249. ttf.htmlText = '<p>' + other.title + '</p>';
  250. ttf.y = -track_height; // - ttf.height;
  251. ttf.x = flash.Lib.current.stage.stageWidth - ttf.width - 10;
  252. }
  253. }
  254. class Track extends Sprite {
  255. public var title:String;
  256. public var id:String;
  257. public var i:Int; // index.
  258. public var bpmin:Int;
  259. public var bpmax:Int;
  260. public var bpp:Float;
  261. public var track_height:Int;
  262. public var info_track:InfoTrack;
  263. public var anno_track:AnnoTrack;
  264. public var extra_anno_tracks:Array<AnnoTrack>;
  265. public var extra_anno_track_ids:Array<String>;
  266. // key is id of other track.
  267. public var subtracks:Hash<SubTrack>;
  268. public static var border_thickness:Float = 3.5;
  269. public static var border_color = 0x333333;
  270. public var mouse_down:Bool;
  271. //public var ttf:MTextField;
  272. public override function toString(){
  273. return "Track(" + this.id + ", " + this.title + ")";
  274. }
  275. public function new(id:String, title:String, bpmin:Int, bpmax:Int, track_height:Int){
  276. super();
  277. subtracks = new Hash<SubTrack>();
  278. extra_anno_tracks = new Array<AnnoTrack>();
  279. extra_anno_track_ids = new Array<String>();
  280. this.id = id;
  281. this.title = title;
  282. this.track_height = track_height;
  283. this.bpmin = bpmin;
  284. this.bpmax = bpmax;
  285. this.mouse_down = false;
  286. this.set_bpp();
  287. this.add_info_track();
  288. this.draw();
  289. //trace("bpmin-bpmax(rng):" + bpmin +"-" + bpmax + "(" + (bpmax - bpmin) + "), bpp:" + this.bpp);
  290. }
  291. public inline function set_bpp(){
  292. this.bpp = (bpmax - bpmin)/(flash.Lib.current.stage.stageWidth - Track.border_thickness);
  293. }
  294. private function add_info_track(){
  295. this.info_track = new InfoTrack(this);
  296. this.addChild(info_track);
  297. info_track.y = Track.border_thickness / 2;
  298. }
  299. public function clear(){
  300. this.graphics.clear();
  301. for(st in this.subtracks.iterator()){
  302. if(Type.getClass(st) == AnnoSubTrack){ continue; }
  303. this.removeChild(st);
  304. }
  305. var i = this.numChildren;
  306. while(i-- > 0){
  307. this.removeChildAt(i);
  308. }
  309. this.subtracks = new Hash<SubTrack>();
  310. }
  311. public function draw(){
  312. var g = this.graphics;
  313. var mid = track_height/2;
  314. g.clear();
  315. var sw = flash.Lib.current.stage.stageWidth;
  316. g.lineStyle(Track.border_thickness, Track.border_color);
  317. // the border around this track.
  318. g.drawRoundRect(Track.border_thickness/2, Track.border_thickness/2, sw - Track.border_thickness, track_height, 22);
  319. }
  320. public inline function rw2pix(bp:Int){
  321. return ((bp - this.bpmin) / this.bpp) + Track.border_thickness;
  322. }
  323. }