progressbar.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /**
  2. * progressbar.js - progress bar element for blessed
  3. * Copyright (c) 2013-2015, Christopher Jeffrey and contributors (MIT License).
  4. * https://github.com/chjj/blessed
  5. */
  6. /**
  7. * Modules
  8. */
  9. var Node = require('./node');
  10. var Input = require('./input');
  11. /**
  12. * ProgressBar
  13. */
  14. function ProgressBar(options) {
  15. var self = this;
  16. if (!(this instanceof Node)) {
  17. return new ProgressBar(options);
  18. }
  19. options = options || {};
  20. Input.call(this, options);
  21. this.filled = options.filled || 0;
  22. if (typeof this.filled === 'string') {
  23. this.filled = +this.filled.slice(0, -1);
  24. }
  25. this.value = this.filled;
  26. this.pch = options.pch || ' ';
  27. // XXX Workaround that predates the usage of `el.ch`.
  28. if (options.ch) {
  29. this.pch = options.ch;
  30. this.ch = ' ';
  31. }
  32. if (options.bch) {
  33. this.ch = options.bch;
  34. }
  35. if (!this.style.bar) {
  36. this.style.bar = {};
  37. this.style.bar.fg = options.barFg;
  38. this.style.bar.bg = options.barBg;
  39. }
  40. this.orientation = options.orientation || 'horizontal';
  41. if (options.keys) {
  42. this.on('keypress', function(ch, key) {
  43. var back, forward;
  44. if (self.orientation === 'horizontal') {
  45. back = ['left', 'h'];
  46. forward = ['right', 'l'];
  47. } else if (self.orientation === 'vertical') {
  48. back = ['down', 'j'];
  49. forward = ['up', 'k'];
  50. }
  51. if (key.name === back[0] || (options.vi && key.name === back[1])) {
  52. self.progress(-5);
  53. self.screen.render();
  54. return;
  55. }
  56. if (key.name === forward[0] || (options.vi && key.name === forward[1])) {
  57. self.progress(5);
  58. self.screen.render();
  59. return;
  60. }
  61. });
  62. }
  63. if (options.mouse) {
  64. this.on('click', function(data) {
  65. var x, y, m, p;
  66. if (!self.lpos) return;
  67. if (self.orientation === 'horizontal') {
  68. x = data.x - self.lpos.xi;
  69. m = (self.lpos.xl - self.lpos.xi) - self.iwidth;
  70. p = x / m * 100 | 0;
  71. } else if (self.orientation === 'vertical') {
  72. y = data.y - self.lpos.yi;
  73. m = (self.lpos.yl - self.lpos.yi) - self.iheight;
  74. p = y / m * 100 | 0;
  75. }
  76. self.setProgress(p);
  77. });
  78. }
  79. }
  80. ProgressBar.prototype.__proto__ = Input.prototype;
  81. ProgressBar.prototype.type = 'progress-bar';
  82. ProgressBar.prototype.render = function() {
  83. var ret = this._render();
  84. if (!ret) return;
  85. var xi = ret.xi
  86. , xl = ret.xl
  87. , yi = ret.yi
  88. , yl = ret.yl
  89. , dattr;
  90. if (this.border) xi++, yi++, xl--, yl--;
  91. if (this.orientation === 'horizontal') {
  92. xl = xi + ((xl - xi) * (this.filled / 100)) | 0;
  93. } else if (this.orientation === 'vertical') {
  94. yi = yi + ((yl - yi) - (((yl - yi) * (this.filled / 100)) | 0));
  95. }
  96. dattr = this.sattr(this.style.bar);
  97. this.screen.fillRegion(dattr, this.pch, xi, xl, yi, yl);
  98. if (this.content) {
  99. var line = this.screen.lines[yi];
  100. for (var i = 0; i < this.content.length; i++) {
  101. line[xi + i][1] = this.content[i];
  102. }
  103. line.dirty = true;
  104. }
  105. return ret;
  106. };
  107. ProgressBar.prototype.progress = function(filled) {
  108. this.filled += filled;
  109. if (this.filled < 0) this.filled = 0;
  110. else if (this.filled > 100) this.filled = 100;
  111. if (this.filled === 100) {
  112. this.emit('complete');
  113. }
  114. this.value = this.filled;
  115. };
  116. ProgressBar.prototype.setProgress = function(filled) {
  117. this.filled = 0;
  118. this.progress(filled);
  119. };
  120. ProgressBar.prototype.reset = function() {
  121. this.emit('reset');
  122. this.filled = 0;
  123. this.value = this.filled;
  124. };
  125. /**
  126. * Expose
  127. */
  128. module.exports = ProgressBar;