PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/nx/display/DBar.hx

http://github.com/cambiata/cx
Haxe | 979 lines | 598 code | 171 blank | 210 comment | 135 complexity | af35281cffeb7ba92f4b6b0179ed025b MD5 | raw file
  1. package nx.display;
  2. import cx.ArrayTools;
  3. import nme.geom.Rectangle;
  4. import nx.Constants;
  5. import nx.display.beam.BeamingProcessor_4dot;
  6. import nx.display.beam.IBeamingProcessor;
  7. import nx.display.type.TPartsYMeasurements;
  8. import nx.element.Bar;
  9. import nme.ObjectHash;
  10. import nx.enums.EAckolade;
  11. import nx.enums.EAllotment;
  12. import nx.enums.EAttributeDisplay;
  13. import nx.enums.EBarline;
  14. import nx.enums.EBarlineLeft;
  15. import nx.enums.EClef;
  16. import nx.enums.EKey;
  17. import nx.enums.EPartType;
  18. import nx.enums.EPartType.EPartTypeDistances;
  19. import nx.enums.ETime;
  20. import nx.enums.utils.EAllotmentCalculator;
  21. import nx.display.DPart;
  22. import nx.display.type.TPartDisplaySettings;
  23. import nx.display.type.TBarDisplaySettings;
  24. /**
  25. * ...
  26. * @author Jonas Nyström
  27. */
  28. using cx.ArrayTools;
  29. using nx.enums.utils.EAllotmentCalculator;
  30. using nx.enums.utils.EnumsTools;
  31. using nx.display.util.DBarUtil;
  32. class DBar
  33. {
  34. public var dparts (default, null) : Array<DPart>;
  35. public var bar (default, null) : Bar;
  36. public var positions (default, null) : Array<Int>;
  37. public var positionDistance (default, null) : IntHash<Float>;
  38. public var postionDistpos (default, null) : IntHash<Float>;
  39. public var columns (default, null) : Array<Column>;
  40. public var dnoteColumn (default, null) :ObjectHash<DNote, Column>;
  41. public var dnoteComplexXadjust (default, null) :ObjectHash<DNote, Float>;
  42. public var dnoteComplex (default, null) :ObjectHash<DNote, Complex>;
  43. public var columnsRectMinframe (default, null) : Rectangle;
  44. public var columnsRectCramped (default, null) : Rectangle;
  45. public var columnsRectAlloted (default, null) : Rectangle;
  46. public var columnsRectStretched (default, null) : Rectangle;
  47. public var allotment (default, null) : EAllotment;
  48. public var dTime (default, null) : ETime;
  49. public var dBarline (default, null) : EBarline;
  50. public var dBarlineLeft (default, null) : EBarlineLeft;
  51. public var dAckolade (default, null) : EAckolade;
  52. public var dIndentLeft (default, null) : Null<Float>;
  53. public var dIndentRight (default, null) : Null<Float>;
  54. //private var beamingProcessor (default, null) : IBeamingProcessor;
  55. public function new(bar:Bar=null, barDisplaySettings:TBarDisplaySettings=null, beamingProcessor:BProcessor=null) {
  56. this.bar = (bar != null) ? bar : new Bar();
  57. this.allotment = EAllotment.Logaritmic;
  58. this._value = 0;
  59. //-----------------------------------------------------------------------------------------------------
  60. this.dparts = [];
  61. for (part in this.bar.parts) {
  62. var partDisplaySettings:TPartDisplaySettings = null;
  63. if (barDisplaySettings != null) {
  64. if (barDisplaySettings.partsDisplaySettings != null) {
  65. var partIdx = this.bar.parts.index(part);
  66. if (barDisplaySettings.partsDisplaySettings[partIdx] != null) partDisplaySettings = barDisplaySettings.partsDisplaySettings[partIdx];
  67. }
  68. }
  69. if (beamingProcessor == null) {
  70. beamingProcessor = this.getDefaultBeamProcessor();
  71. }
  72. this.dparts.push(new DPart(part, partDisplaySettings, beamingProcessor));
  73. }
  74. //-----------------------------------------------------------------------------------------------------
  75. this._calcPositions();
  76. this._calcColumns();
  77. this._calcColumnValues();
  78. this._calcColumValueWeight();
  79. this._calcDnotesColumnsAndComplexes();
  80. this._calcDnotesComplexXadjust();
  81. this._calcColumnsDistancesX();
  82. this._calcColumnsPositionsX();
  83. /*
  84. this._calcColumnsSpacing();
  85. this._calcColumnsRects();
  86. */
  87. //-----------------------------------------------------------------------------------------------------
  88. this.setDisplaySettings();
  89. }
  90. public function setDisplaySettings(settings:TBarDisplaySettings = null) {
  91. //this._dpartTop = null;
  92. //----------------------------------------
  93. this._attributesRectLeft = null;
  94. this._rectLeftindent = null;
  95. this._rectLabels = null;
  96. this._rectAckolade = null;
  97. this._rectAckolademargin = null;
  98. this._rectClef = null;
  99. this._rectKey = null;
  100. this._rectTime = null;
  101. this._rectBarlineleft = null;
  102. this._rectMarginLeft = null;
  103. //----------------------------------------
  104. this._attributesRectRight = null;
  105. this._rectMarginRight = null;
  106. this._rectBarline = null;
  107. this._rectCautionaries = null;
  108. this._rectRightindent = null;
  109. //----------------------------------------
  110. if (settings == null) {
  111. settings = {
  112. dTime: null,
  113. dBarline: null,
  114. dBarlineLeft: null,
  115. dAckolade: null,
  116. dIndentLeft: null,
  117. dIndentRight: null,
  118. partsDisplaySettings: null,
  119. }
  120. }
  121. if (settings.partsDisplaySettings != null && this.dparts != null) {
  122. for (dpart in this.dparts) {
  123. var idx = this.dparts.index(dpart);
  124. if (settings.partsDisplaySettings[idx] != null) {
  125. dpart.setDisplaySettings(settings.partsDisplaySettings[idx]);
  126. }
  127. }
  128. } else {
  129. for (dpart in this.dparts) {
  130. dpart.setDisplaySettings();
  131. }
  132. }
  133. //-----------------------------------------------------------------------------------------------------
  134. this.dTime = (settings.dTime != null) ? settings.dTime : bar.time;
  135. this.dBarline = (settings.dBarline != null) ? settings.dBarline : bar.barline;
  136. this.dBarlineLeft = (settings.dBarlineLeft != null) ? settings.dBarlineLeft : bar.barlineLeft;
  137. this.dAckolade = (settings.dAckolade != null) ? settings.dAckolade : bar.ackolade;
  138. this.dIndentLeft = (settings.dIndentLeft != null) ? settings.dIndentLeft : bar.indentLeft;
  139. this.dIndentRight = (settings.dIndentRight != null) ? settings.dIndentRight : bar.indentRight;
  140. if (bar.timeDisplay == EAttributeDisplay.Always) this.dTime = bar.time;
  141. if (bar.timeDisplay == EAttributeDisplay.Never) this.dTime = null;
  142. //-----------------------------------------------------------------------------------------------------
  143. /*
  144. this._calcPositions();
  145. this._calcColumns();
  146. this._calcColumnValues();
  147. this._calcColumValueWeight();
  148. this._calcDnotesColumnsAndComplexes();
  149. this._calcDnotesComplexXadjust();
  150. this._calcColumnsDistancesX();
  151. this._calcColumnsPositionsX();
  152. */
  153. this._calcColumnsSpacing();
  154. this._calcColumnsRects();
  155. }
  156. public function getDisplaySettings():TBarDisplaySettings {
  157. var settings:TBarDisplaySettings = {
  158. dTime: this.dTime,
  159. dBarline: this.dBarline,
  160. dBarlineLeft: this.dBarlineLeft,
  161. dAckolade: this.dAckolade,
  162. dIndentLeft: (this.dIndentLeft != 0) ? this.dIndentLeft : null,
  163. dIndentRight: (this.dIndentRight != 0) ? this.dIndentRight : null,
  164. partsDisplaySettings: [],
  165. }
  166. for (dpart in this.dparts) {
  167. settings.partsDisplaySettings.push(dpart.getDisplaySettings());
  168. }
  169. return settings;
  170. }
  171. /************************************************************************
  172. * Private methods
  173. *
  174. ************************************************************************/
  175. private var _value:Int;
  176. public var value(get_value, null):Int;
  177. private function get_value():Int
  178. {
  179. if (this._value != 0) return this._value;
  180. this._value = 0;
  181. for (dpart in this.dparts) {
  182. this._value = Std.int(Math.max(this._value, dpart.value));
  183. }
  184. return this._value;
  185. }
  186. private function _calcPositions() {
  187. this.positions = [];
  188. for (dpart in this.dparts) {
  189. this.positions = this.positions.concat(dpart.positions);
  190. }
  191. this.positions = ArrayTools.unique(this.positions);
  192. this.positions.sort(function(a, b) { return Reflect.compare(a, b); } );
  193. }
  194. private function _calcColumns() {
  195. this.columns = [];
  196. for (pos in this.positions) {
  197. var column:Column = { position:pos, value:12345, complexes:[], distanceX:0.0, positionX:0.0, widthX:0.0 };
  198. for (dpart in this.dparts) {
  199. var dplex = dpart.positionComplex.get(pos);
  200. column.complexes.push(dplex);
  201. }
  202. this.columns.push(column);
  203. }
  204. }
  205. private function _calcColumnValues() {
  206. var prevColumn:Column = null;
  207. for (column in this.columns) {
  208. if (column == this.columns.first()) {
  209. prevColumn = column;
  210. continue;
  211. }
  212. var prevValue = column.position - prevColumn.position;
  213. prevColumn.value = prevValue;
  214. prevColumn = column;
  215. }
  216. var lastColumn = prevColumn;
  217. lastColumn.value = this.value - lastColumn.position;
  218. }
  219. private function _calcColumValueWeight() {
  220. var barvalue = this.value;
  221. for (column in this.columns) {
  222. column.valueWeight = column.value / barvalue;
  223. }
  224. }
  225. private function _calcDnotesColumnsAndComplexes() {
  226. this.dnoteColumn = new ObjectHash<DNote, Column>();
  227. this.dnoteComplex = new ObjectHash <DNote, Complex>();
  228. /*
  229. * 2.09 dpp ObjectHash bug workaround - seems to work in 2.10
  230. *
  231. this.dnoteguidColumnidx = new Hash<Int>();
  232. this.dnoteguidComplexidx = new Hash<Int>();
  233. */
  234. for (column in this.columns) {
  235. for (complex in column.complexes) {
  236. if (complex == null) continue;
  237. for (dnote in complex.dnotes) {
  238. this.dnoteColumn.set(dnote, column);
  239. this.dnoteComplex.set(dnote, complex);
  240. /*
  241. * 2.09 dpp ObjectHash bug workaround - seems to work in 2.10
  242. *
  243. var columnIdx = this.columns.index(column);
  244. this.dnoteguidColumnidx.set(dnote.guid, columnIdx);
  245. var complexIdx = column.complexes.index(complex);
  246. this.dnoteguidComplexidx.set(dnote.guid, complexIdx);
  247. */
  248. }
  249. }
  250. }
  251. }
  252. private function _calcDnotesComplexXadjust() {
  253. this.dnoteComplexXadjust = new ObjectHash<DNote, Float>();
  254. /*
  255. * 2.09 dpp ObjectHash bug workaround - seems to work in 2.10
  256. *
  257. this.dnoteguidComplexXadjust = new Hash<Float>();
  258. */
  259. for (column in this.columns) {
  260. for (complex in column.complexes) {
  261. if (complex == null) continue;
  262. var idx = 0;
  263. for (dnote in complex.dnotes) {
  264. var adjustX = complex.dnoteXshift(idx);
  265. this.dnoteComplexXadjust.set(dnote, adjustX);
  266. /*
  267. * 2.09 dpp ObjectHash bug workaround - seems to work in 2.10
  268. *
  269. var complexIdx = column.complexes.index(complex);
  270. this.dnoteguidComplexXadjust.set(dnote.guid, adjustX);
  271. */
  272. idx++;
  273. }
  274. }
  275. }
  276. }
  277. private function _calcColumnsDistancesX() {
  278. var testPB:TPosComplex = { position:0, rectsAll:[], rectsHeadW:[] };
  279. var firstpb = this.columns[0];
  280. for (complex in firstpb.complexes) {
  281. var dplexRectsAll = complex.rectsAll;
  282. testPB.rectsAll.push(complex.getRectsAllCopy());
  283. testPB.rectsHeadW.push(complex.rectHeads.width);
  284. }
  285. var prevColumn:Column = null;
  286. for (column in this.columns) {
  287. if (column == this.columns.first()) {
  288. prevColumn = column;
  289. continue;
  290. }
  291. //-----------------------------------------------------------------------
  292. //trace('*** pb ' + i + ' ***');
  293. //-----------------------------------------------------------------------
  294. var maxDistanceX = 0.0;
  295. for (j in 0...column.complexes.length) {
  296. var dplex = column.complexes[j];
  297. var testRectsAll = testPB.rectsAll[j];
  298. var testRectHeadW = testPB.rectsHeadW[j];
  299. if (dplex != null) {
  300. var dplexRectsAll = dplex.rectsAll;
  301. var distanceX = Complex.dplexDistanceX(testRectsAll, testRectHeadW, dplexRectsAll);
  302. maxDistanceX = Math.max(maxDistanceX, distanceX);
  303. } else {
  304. }
  305. }
  306. //-----------------------------------------------------------------------
  307. //trace('Max distanceX:' + maxDistanceX);
  308. prevColumn.widthX = maxDistanceX;
  309. column.distanceX = maxDistanceX;
  310. //-----------------------------------------------------------------------
  311. for (j in 0...column.complexes.length) {
  312. var dplex = column.complexes[j];
  313. var testRectsAll = testPB.rectsAll[j];
  314. var testRectHeadW = testPB.rectsHeadW[j];
  315. if (dplex != null) {
  316. testPB.rectsAll[j] = dplex.getRectsAllCopy();
  317. testPB.rectsHeadW[j] = dplex.rectHeads.width;
  318. } else {
  319. for (rect in testPB.rectsAll[j]) {
  320. rect.offset( -maxDistanceX, 0);
  321. }
  322. testPB.rectsHeadW[j] += -maxDistanceX;
  323. }
  324. }
  325. prevColumn = column;
  326. }
  327. }
  328. private function _calcColumnsPositionsX() {
  329. var positionX = 0.0;
  330. for (column in this.columns) {
  331. positionX += column.distanceX;
  332. column.positionX = positionX;
  333. }
  334. }
  335. private function _calcColumnsSpacing() {
  336. //trace('*****************************');
  337. //allotment = EAllotment.Logaritmic;
  338. for (column in this.columns) {
  339. column.aWidthX = this.allotment.aWidthX(column.widthX, column.value);
  340. column.aSuperX = this.allotment.aSuperX(column.widthX, column.value);
  341. }
  342. /*
  343. //-----------------------------------------------------------------------------------------------------
  344. // Test equal distance
  345. for (column in this.columns) {
  346. column.aWidthX = Math.max(column.widthX, Constants.ASPACING_NORMAL);
  347. column.aSuperX = Math.max(column.widthX - Constants.ASPACING_NORMAL, 0);
  348. }
  349. //-----------------------------------------------------------------------------------------------------
  350. // Test linear distance
  351. for (column in this.columns) {
  352. var columnWidthX = (column.value / Constants.BASE_NOTE_VALUE) * Constants.ASPACING_NORMAL;
  353. column.aWidthX = Math.max(column.widthX, columnWidthX);
  354. column.aSuperX = Math.max(column.widthX - columnWidthX, 0);
  355. }
  356. //-----------------------------------------------------------------------------------------------------
  357. // Test logaritmic distance
  358. for (column in this.columns) {
  359. var delta:Float = 0.5;
  360. var columnWidthX = (delta +(column.value / Constants.BASE_NOTE_VALUE) / 2) * Constants.ASPACING_NORMAL;
  361. column.aWidthX = Math.max(column.widthX, columnWidthX);
  362. column.aSuperX = Math.max(column.widthX - columnWidthX, 0);
  363. }
  364. */
  365. var posX = 0.0;
  366. for (column in this.columns) {
  367. column.sPositionX = column.aPositionX = posX;
  368. posX += column.aWidthX;
  369. }
  370. /*
  371. for (column in this.columns) {
  372. trace([column.widthX, column.positionX, Constants.ASPACING_NORMAL, column.aSuperX, column.aWidthX, column.aPositionX]);
  373. }
  374. */
  375. }
  376. private var firstMinX:Float;
  377. private var lastWidthIncludeValue:Float;
  378. private function _calcColumnsRects() {
  379. var firstColumn = this.columns.first();
  380. this.firstMinX = 0.0;
  381. for (complex in firstColumn.complexes) {
  382. firstMinX = Math.min(firstMinX, complex.rectFull.x);
  383. }
  384. var lastColumn = this.columns.last();
  385. var lastMaxW = 0.0;
  386. for (complex in lastColumn.complexes) {
  387. if (complex != null) {
  388. lastMaxW = Math.max(lastMaxW, complex.rectFull.x + complex.rectFull.width);
  389. }
  390. }
  391. this.lastWidthIncludeValue = Math.max(lastMaxW, lastColumn.aWidthX);
  392. //-----------------------------------------------------------------------------------------------------
  393. var columnsWidthCramped = lastColumn.positionX;
  394. this.columnsRectMinframe = new Rectangle(firstMinX, 0, -firstMinX + columnsWidthCramped + lastMaxW, 0);
  395. this.columnsRectCramped = new Rectangle(firstMinX, 0, -firstMinX + columnsWidthCramped + lastWidthIncludeValue, 0);
  396. var columnsWidthAlloted = this.columns.last().aPositionX;
  397. this.columnsRectAlloted = new Rectangle(firstMinX, 0, -firstMinX + columnsWidthAlloted + lastWidthIncludeValue, 0);
  398. var columnsWidthStretched = this.columns.last().sPositionX;
  399. this.columnsRectStretched = new Rectangle(firstMinX, 0, -firstMinX + columnsWidthStretched + lastWidthIncludeValue, 0);
  400. }
  401. public function stretchContentTo(stetchedContentWidth:Float=0.0):DBar {
  402. if (this.allotment == EAllotment.Cramped) return this;
  403. var currentContentWidth = this.columnsRectAlloted.width;
  404. var stretchAmount:Float = stetchedContentWidth - currentContentWidth;
  405. //trace([currentContentWidth, stetchedContentWidth, stretchAmount]);
  406. if (stetchedContentWidth <= currentContentWidth) return this;
  407. //-----------------------------------------------------------------------------------------------------
  408. for (column in this.columns) {
  409. column.sPositionX = column.aPositionX;
  410. column.sWidthX = column.aWidthX;
  411. }
  412. //-----------------------------------------------------------------------------------------------------
  413. var currentNormalValueWidth = new IntHash<Float>();
  414. var newNormalValueWidth = new IntHash<Float>();
  415. for (column in this.columns) {
  416. var valueWidth = this.allotment.aWidthX(0, column.value);
  417. //trace(this.allotment.aWidthX(0, column.value));
  418. if (!currentNormalValueWidth.exists(column.value)) {
  419. currentNormalValueWidth.set(column.value, valueWidth);
  420. newNormalValueWidth.set(column.value, valueWidth);
  421. }
  422. }
  423. var currentValues = ArrayTools.fromIterator(currentNormalValueWidth.keys());
  424. var pott = stretchAmount;
  425. var loopCount = 0;
  426. do {
  427. // set new width values:
  428. for (value in currentValues) {
  429. var change = 0.5 * this.allotment.valueFactor(value);
  430. newNormalValueWidth.set(value, newNormalValueWidth.get(value) + change);
  431. }
  432. for (column in this.columns) {
  433. var change = 0.5 * (column.value / Constants.BASE_NOTE_VALUE);
  434. var checkWidth = newNormalValueWidth.get(column.value);
  435. if (column.sWidthX < checkWidth) {
  436. column.sWidthX += change;
  437. pott -= change;
  438. } else {
  439. // utvidga ej!
  440. }
  441. loopCount++;
  442. if (loopCount > Constants.LOOP_COUNT_MAX) {
  443. throw "Loop check overload";
  444. pott = 0;
  445. }
  446. if (pott <= 0) break;
  447. }
  448. } while (pott > 0);
  449. //trace(loopCount);
  450. //-----------------------------------------------------------------------------------------------------
  451. // Finally set rectangle
  452. var pos = 0.0;
  453. for (column in this.columns) {
  454. column.sPositionX = pos;
  455. pos += column.sWidthX;
  456. }
  457. this.columnsRectStretched.width = stetchedContentWidth;
  458. return this;
  459. }
  460. //-----------------------------------------------------------------------------------------------------
  461. /// INDENT LEFT
  462. private var _rectLeftindent:Rectangle;
  463. public var rectLeftindent(get_rectLeftindent, null):Rectangle;
  464. private function get_rectLeftindent():Rectangle {
  465. if (this._rectLeftindent != null) return this._rectLeftindent;
  466. this._rectLeftindent = new Rectangle(0, -1, this.dIndentLeft, 2);
  467. return this._rectLeftindent;
  468. }
  469. /// PART LABELS
  470. private var _rectLabels:Rectangle;
  471. public var rectLabels(get_rectLabels, null):Rectangle;
  472. private function get_rectLabels():Rectangle {
  473. if (this._rectLabels != null) return this._rectLabels;
  474. /// Get from parts...
  475. this._rectLabels = new Rectangle(0, -1, Constants.ATTRIBUTE_NULL_WIDTH, 2);
  476. this._rectLabels.offset(this.rectLeftindent.x + this.rectLeftindent.width, 0);
  477. return this._rectLabels;
  478. }
  479. /// ACKOLADE
  480. private var _rectAckolade:Rectangle;
  481. public var rectAckolade(get_rectAckolade, null):Rectangle;
  482. private function get_rectAckolade():Rectangle {
  483. if (this._rectAckolade != null) return this._rectAckolade;
  484. this._rectAckolade = new Rectangle(0, -3, this.dAckolade.widthAckolade(), 6);
  485. this._rectAckolade.offset(this.rectLabels.x + this.rectLabels.width, 0);
  486. return this._rectAckolade;
  487. }
  488. /// ACKOLAD EMARGIN
  489. private var _rectAckolademargin:Rectangle;
  490. public var rectAckolademargin(get_rectAckolademargin, null):Rectangle;
  491. private function get_rectAckolademargin():Rectangle
  492. {
  493. if (this._rectAckolademargin != null) return this._rectAckolademargin;
  494. this._rectAckolademargin = new Rectangle(0, -4, Constants.ACKOLADE_CLEF_MARGIN, 8);
  495. this._rectAckolademargin.offset(this.rectAckolade.x + this.rectAckolade.width, 0);
  496. return this._rectAckolademargin;
  497. }
  498. /// CLEF
  499. private var _rectClef:Rectangle;
  500. public var rectClef(get_rectClef, null):Rectangle;
  501. private function get_rectClef():Rectangle {
  502. if (this._rectClef != null) return this._rectClef;
  503. this._rectClef = new Rectangle(0, -2, 0, 2);
  504. for (dpart in this.dparts) {
  505. this._rectClef = this._rectClef.union(dpart.rectClef);
  506. }
  507. this._rectClef.offset(this.rectAckolademargin.x + this.rectAckolademargin.width, 0);
  508. return this._rectClef;
  509. }
  510. /// KEY
  511. private var _rectKey:Rectangle;
  512. public var rectKey(get_rectKey, null):Rectangle;
  513. private function get_rectKey():Rectangle {
  514. if (this._rectKey != null) return this._rectKey;
  515. this._rectKey = new Rectangle(0, 0, 0, 0);
  516. for (dpart in this.dparts) {
  517. this._rectKey = this._rectKey.union(dpart.rectKey);
  518. }
  519. this._rectKey.offset(this.rectClef.x + this.rectClef.width, 0);
  520. return this._rectKey;
  521. }
  522. /// TIME
  523. private var _rectTime:Rectangle;
  524. public var rectTime(get_rectTime, null):Rectangle;
  525. private function get_rectTime():Rectangle {
  526. var rect:Rectangle = null;
  527. this._rectTime = new Rectangle(0, -2, this.dTime.widthTime(), 4);
  528. this._rectTime.offset(this.rectKey.x + this.rectKey.width, 0);
  529. return _rectTime;
  530. }
  531. /// LEFT BARLINE
  532. private var _rectBarlineleft:Rectangle;
  533. public var rectBarlineleft(get_rectBarlineleft, null):Rectangle;
  534. private function get_rectBarlineleft():Rectangle {
  535. if (this._rectBarlineleft != null) return this._rectBarlineleft;
  536. this._rectBarlineleft = new Rectangle(0, -5, this.dBarlineLeft.widthBarlineLeft(), 10);
  537. this._rectBarlineleft.offset(this.rectTime.x + this.rectTime.width, 0);
  538. return this._rectBarlineleft;
  539. }
  540. /// MARGIN LEFT
  541. private var _rectMarginLeft:Rectangle;
  542. public var rectMarginLeft(get_rectMarginLeft, null):Rectangle;
  543. private function get_rectMarginLeft():Rectangle {
  544. if (this._rectMarginLeft != null) return this._rectMarginLeft;
  545. this._rectMarginLeft = new Rectangle(0, -3, Constants.BAR_MARGIN_LEFT, 4);
  546. this._rectMarginLeft.offset(this.rectBarlineleft.x + this.rectBarlineleft.width, 0); /// CHANGE TO LEFT BARLINE
  547. return this._rectMarginLeft;
  548. }
  549. //--------------------------------------------------------------------------------------
  550. /// MARGIN RIGHT
  551. private var _rectMarginRight:Rectangle;
  552. public var rectMarginRight(get_rectMarginRight, null):Rectangle;
  553. private function get_rectMarginRight():Rectangle {
  554. if (this._rectMarginRight != null) return this._rectMarginRight;
  555. this._rectMarginRight = new Rectangle(0, -3, Constants.BAR_MARGIN_RIGHT, 6);
  556. return this._rectMarginRight;
  557. }
  558. /// BARLINE
  559. private var _rectBarline:Rectangle;
  560. public var rectBarline(get_rectBarline, null):Rectangle;
  561. private function get_rectBarline():Rectangle {
  562. if (this._rectBarline != null) return this._rectBarline;
  563. this._rectBarline = new Rectangle(0, -2, this.dBarline.widthBarline(), 4);
  564. this._rectBarline.offset(this.rectMarginRight.x + this.rectMarginRight.width, 0);
  565. return this._rectBarline;
  566. }
  567. /// CAUTIONARIES...
  568. private var _rectCautionaries:Rectangle;
  569. public var rectCautionaries(get_rectCautionaries, null):Rectangle;
  570. private function get_rectCautionaries():Rectangle {
  571. if (this._rectCautionaries != null) return this._rectCautionaries;
  572. this._rectCautionaries = new Rectangle(0, -3, 0, 6);
  573. /// Get cautionaries from part stuff (clefs, keys)!
  574. this._rectCautionaries.offset(this.rectBarline.x + this.rectBarline.width, 0);
  575. return this._rectCautionaries;
  576. }
  577. /// RIGHT INDENT
  578. private var _rectRightindent:Rectangle;
  579. public var rectRightindent(get_rectRightindent, null):Rectangle;
  580. private function get_rectRightindent():Rectangle {
  581. if (this._rectRightindent != null) return this._rectRightindent;
  582. this._rectRightindent = new Rectangle(0, -3, this.dIndentRight, 6);
  583. this._rectRightindent.offset(this.rectCautionaries.x + this.rectCautionaries.width, 0);
  584. return this._rectRightindent;
  585. }
  586. //--------------------------------------------------------------------------------------
  587. private var _attributesRectLeft:Rectangle;
  588. private function get_attributesRectLeft():Rectangle
  589. {
  590. if (this._attributesRectLeft != null) return this._attributesRectLeft;
  591. var rect = new Rectangle(0, -8, 0, 16)
  592. // left Rightindent
  593. // part labels
  594. // ackolade
  595. .union(this.rectLeftindent)
  596. .union(this.rectLabels)
  597. .union(this.rectAckolade)
  598. .union(this.rectAckolademargin)
  599. .union(this.rectClef)
  600. .union(this.rectKey)
  601. .union(this.rectTime)
  602. .union(this.rectBarlineleft)
  603. .union(this.rectMarginLeft)
  604. ;
  605. /*
  606. rect = rect.union(this.rectLabels);
  607. rect = rect.union(this.rectAckolade);
  608. rect = rect.union(this.rectClef);
  609. rect = rect.union(this.rectKey);
  610. rect = rect.union(this.rectTime);
  611. rect = rect.union(this.rectMarginLeft);
  612. */
  613. this._attributesRectLeft = rect;
  614. return this._attributesRectLeft;
  615. }
  616. public var attributesRectLeft(get_attributesRectLeft, null):Rectangle;
  617. private var _attributesRectRight:Rectangle;
  618. private function get_attributesRectRight():Rectangle
  619. {
  620. if (this._attributesRectRight != null) return this._attributesRectRight;
  621. var rect = new Rectangle(0, -8, 0, 16)
  622. .union(this.rectMarginRight)
  623. .union(this.rectBarline)
  624. .union(this.rectCautionaries)
  625. .union(this.rectRightindent)
  626. ;
  627. this._attributesRectRight = rect;
  628. return this._attributesRectRight;
  629. }
  630. public var attributesRectRight(get_attributesRectRight, null):Rectangle;
  631. //---------------------------------------------------------------------------------------------------------
  632. public function getTotalWidthCramped() {
  633. var ret:TBarMeasurement = {
  634. attribLeftWidth: this.attributesRectLeft.width,
  635. columnsWidth: this.columnsRectCramped.width,
  636. attribRightWidth: this.attributesRectRight.width,
  637. totalWidth: this.attributesRectLeft.width + this.columnsRectCramped.width + this.attributesRectRight.width,
  638. }
  639. return ret;
  640. }
  641. public function getTotalWidthAlloted() {
  642. var ret:TBarMeasurement = {
  643. attribLeftWidth: this.attributesRectLeft.width,
  644. columnsWidth: this.columnsRectAlloted.width,
  645. attribRightWidth: this.attributesRectRight.width,
  646. totalWidth: this.attributesRectLeft.width + this.columnsRectAlloted.width + this.attributesRectRight.width,
  647. }
  648. return ret;
  649. }
  650. public function getTotalWidthStretched() {
  651. var ret:TBarMeasurement = {
  652. attribLeftWidth: this.attributesRectLeft.width,
  653. columnsWidth: this.columnsRectStretched.width,
  654. attribRightWidth: this.attributesRectRight.width,
  655. totalWidth: this.attributesRectLeft.width + this.columnsRectStretched.width + this.attributesRectRight.width,
  656. }
  657. return ret;
  658. }
  659. //-----------------------------------------------------------------------------------------------------
  660. /*
  661. private var _dpartTop:ObjectHash<DPart, Float>;
  662. public var dpartTop(get_dpartTop, null):ObjectHash<DPart, Float>;
  663. private function get_dpartTop():ObjectHash<DPart, Float> {
  664. if (this._dpartTop != null) return this._dpartTop;
  665. this._dpartTop = new ObjectHash<DPart, Float>();
  666. var distance = 0.0;
  667. var prevDpart:DPart = null;
  668. for (dpart in this.dparts) {
  669. if (dpart == this.dparts.first()) {
  670. distance += -(dpart.rectDPartHeight.y);
  671. } else {
  672. var increase = (prevDpart.rectDPartHeight.height + prevDpart.rectDPartHeight.y) + -dpart.rectDPartHeight.y + Constants.PART_MIN_DISTANCE;
  673. var minDistance = EPartTypeDistances.getMinDistance(dpart.part.type);
  674. //trace([increase, minDistance]);
  675. distance += Math.max(minDistance, increase);
  676. }
  677. this._dpartTop.set(dpart, distance);
  678. prevDpart = dpart;
  679. }
  680. return this._dpartTop;
  681. }
  682. public function resetDpartTop() {
  683. this._dpartTop = null;
  684. //var dummy = this.dpartTop;
  685. }
  686. */
  687. //-------------------------------------------------------------------------------------------------
  688. private var _dpartsRects:Array<Rectangle>;
  689. public var dpartsRects(get_dpartsRects, null):Array<Rectangle>;
  690. private function get_dpartsRects():Array<Rectangle> {
  691. if (this._dpartsRects != null) return this._dpartsRects;
  692. this._dpartsRects = [];
  693. for (dpart in this.dparts) {
  694. this._dpartsRects.push(dpart.rectDPartHeight);
  695. }
  696. return this._dpartsRects;
  697. }
  698. private var _dpartTypes:Array<EPartType>;
  699. public var dpartTypes(get_dpartTypes, null):Array<EPartType>;
  700. private function get_dpartTypes():Array<EPartType> {
  701. if (this._dpartTypes != null) return this._dpartTypes;
  702. this._dpartTypes = [];
  703. for (dpart in this.dparts) {
  704. this._dpartTypes.push(dpart.part.type);
  705. }
  706. return this._dpartTypes;
  707. }
  708. private var _dpartYPositions:Array<Float>;
  709. public var dpartYPositions(get_dpartYPositions, null):Array<Float>;
  710. private function get_dpartYPositions():Array<Float> {
  711. if (this._dpartYPositions != null) return this._dpartYPositions;
  712. var meas:TPartsYMeasurements = calcPartsMeasurements(this.dpartsRects, this.dpartTypes);
  713. this._dpartYPositions = meas.partYPositions;
  714. this._dpartsHeight = meas.partsHeight;
  715. return this._dpartYPositions;
  716. }
  717. private var _dpartsHeight:Null<Float>;
  718. public var dpartsHeight(get_dpartsHeight, null):Float;
  719. private function get_dpartsHeight():Float {
  720. if (this._dpartsHeight != null) return this._dpartsHeight;
  721. this._dpartYPositions = null; // force recalculation of dpartYPositions
  722. return this._dpartsHeight;
  723. }
  724. static public function calcPartsMeasurements(partRects:Array<Rectangle>, partTypes:Array<EPartType>=null):TPartsYMeasurements{
  725. var distance = 0.0;
  726. var prevPRect:Rectangle = null;
  727. var tops:Array<Float> = [];
  728. for (pRect in partRects) {
  729. var pIdx = partRects.index(pRect);
  730. if (prevPRect == null) {
  731. distance += -(pRect.y);
  732. tops.push(distance);
  733. } else {
  734. var increase = (prevPRect.height + prevPRect.y) + -pRect.y + Constants.PART_MIN_DISTANCE;
  735. var minDistance:Float = 0.0;
  736. if (partTypes == null) {
  737. minDistance = EPartTypeDistances.getMinDistance(EPartType.Normal);
  738. } else {
  739. minDistance = EPartTypeDistances.getMinDistance(partTypes[pIdx]);
  740. }
  741. distance += Math.max(minDistance, increase);
  742. tops.push(distance);
  743. }
  744. prevPRect = pRect;
  745. }
  746. var partsHeight = distance + (prevPRect.y + prevPRect.height);
  747. return {partYPositions: tops, partsHeight:partsHeight};
  748. }
  749. /*
  750. private var _dpartTop:Array<Float>;
  751. public var dpartTop(get_dpartTop, null):Array<Float>;
  752. private function get_dpartTop():Array<Float> {
  753. if (this._dpartTop != null) return this._dpartTop;
  754. this._dpartTop = [];
  755. var distance = 0.0;
  756. var prevDpart:DPart = null;
  757. for (dpart in this.dparts) {
  758. if (dpart == this.dparts.first()) {
  759. distance += -(dpart.rectDPartHeight.y);
  760. } else {
  761. var increase = (prevDpart.rectDPartHeight.height + prevDpart.rectDPartHeight.y) + -dpart.rectDPartHeight.y + Constants.PART_MIN_DISTANCE;
  762. var minDistance = EPartTypeDistances.getMinDistance(dpart.part.type);
  763. //trace([increase, minDistance]);
  764. distance += Math.max(minDistance, increase);
  765. }
  766. this._dpartTop.push(distance);
  767. prevDpart = dpart;
  768. }
  769. return this._dpartTop;
  770. }
  771. */
  772. }
  773. typedef TBarMeasurement = {
  774. attribLeftWidth: Float,
  775. columnsWidth: Float,
  776. attribRightWidth: Float,
  777. totalWidth: Float,
  778. //columnsX: Float,
  779. //attribRightX: Float,
  780. }
  781. typedef TPosComplex = {
  782. position: Int,
  783. rectsAll: Array<Array<Rectangle>>,
  784. rectsHeadW:Array<Float>,
  785. }
  786. /*
  787. typedef TBarDisplaySettings = {
  788. dTime: ETime,
  789. //dTime: ETime,
  790. dBarline: EBarline,
  791. dBarlineLeft: EBarlineLeft,
  792. dAckolade: EAckolade,
  793. dIndentLeft: Null<Float>,
  794. dIndentRight: Null<Float>,
  795. partsDisplaySettings: Array<TPartDisplaySettings>,
  796. }
  797. */