printer.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /**
  2. * An object for managing the console where printing and plotting is outputed.
  3. *
  4. * @constructor
  5. * @this {BlockPyEditor}
  6. * @param {Object} main - The main BlockPy instance
  7. * @param {HTMLElement} tag - The HTML object this is attached to.
  8. */
  9. function BlockPyPrinter(main, tag) {
  10. this.main = main;
  11. this.tag = tag;
  12. /** Keep printer settings available for interested parties */
  13. this.printerSettings = {};
  14. this.resetPrinter();
  15. };
  16. /**
  17. * Reset the status of the printer, including removing any text in it and
  18. * fixing its size.
  19. */
  20. BlockPyPrinter.prototype.resetPrinter = function() {
  21. this.tag.empty();
  22. this.main.model.execution.output.removeAll();
  23. this.printerSettings['width'] = Math.min(500, this.tag.width()-40);
  24. this.printerSettings['height'] = Math.min(500, this.tag.height()+40);
  25. Sk.TurtleGraphics = {'target': this.tag[0],
  26. 'width': this.printerSettings['width']-40,
  27. 'height': this.printerSettings['height']-40};
  28. }
  29. /**
  30. * Update and return the current configuration of the printer. This
  31. * involves calculating its size, among other operations.
  32. *
  33. * @returns {Object} Returns an object with information about the printer.
  34. */
  35. BlockPyPrinter.prototype.getConfiguration = function() {
  36. var printer = this;
  37. this.printerSettings['printHtml']= function(html, value) { printer.printHtml(html, value);};
  38. this.printerSettings['width']= Math.min(500, this.tag.width()-40);
  39. this.printerSettings['pngMode']= true;
  40. this.printerSettings['skipDrawing']= false;
  41. this.printerSettings['height']= Math.min(500, this.tag.height()+40);
  42. this.printerSettings['container']= this.tag[0];
  43. return this.printerSettings;
  44. }
  45. /**
  46. * Update and return a static disabled configuration of the printer. This
  47. * printer will be unable to do most tasks.
  48. *
  49. * @returns {Object} Returns an object with information about the printer.
  50. */
  51. BlockPyPrinter.getDisabledConfiguration = function() {
  52. var printerSettings = {}
  53. printerSettings['printHtml']= function(html, value) { console.log(html, value);};
  54. printerSettings['width']= 500;
  55. printerSettings['pngMode']= false;
  56. printerSettings['skipDrawing']= true;
  57. printerSettings['height']= 500;
  58. printerSettings['container']= null;
  59. return printerSettings;
  60. }
  61. /**
  62. * Updates each printed element in the printer and makes it hidden
  63. * or visible, depending on what step we're on.
  64. *
  65. * @param {Number} step - The current step of the executed program that we're on; each element in the printer must be marked with a "data-step" property to resolve this.
  66. * @param {Number} page - Deprecated, not sure what this even does.
  67. */
  68. BlockPyPrinter.prototype.stepPrinter = function(step, page) {
  69. $(this.printer).find('.blockpy-printer-output').each(function() {
  70. if ($(this).attr("data-step") <= step) {
  71. $(this).show();
  72. } else {
  73. $(this).hide();
  74. }
  75. });
  76. }
  77. /**
  78. * Print a successful line to the on-screen printer.
  79. * @param {String} lineText - A line of text to be printed out.
  80. */
  81. BlockPyPrinter.prototype.print = function(lineText) {
  82. // Should probably be accessing the model instead of a component...
  83. var stepNumber = this.main.components.engine.executionBuffer.step;
  84. var lineNumber = this.main.components.engine.executionBuffer.line_number;
  85. // Perform any necessary cleaning
  86. if (lineText !== "\n") {
  87. this.main.model.execution.output.push(lineText.slice(0, -1));
  88. var encodedText = encodeHTML(lineText);
  89. if (!(this.main.model.settings.mute_printer())) {
  90. var lineContainer = $("<div class='blockpy-printer-output' >");
  91. var lineData = $("<samp></samp>", {
  92. 'data-toggle': 'tooltip',
  93. 'data-placement': 'left',
  94. 'data-step': stepNumber,
  95. "html": encodedText,
  96. 'title': "Step "+stepNumber + ", Line "+lineNumber,
  97. })
  98. lineContainer.append(lineData);
  99. // Append to the current text
  100. this.tag.append(lineContainer);
  101. // lineData.tooltip();
  102. }
  103. }
  104. }
  105. /**
  106. * Prints a successful HTML blob to the printer. This is typically charts,
  107. * but it can actually be any kind of HTML. This will probably be useful for
  108. * doing Turtle and Processing stuff down the road.
  109. *
  110. * @param {HTML} html - A blob of HTML to render in the tag
  111. * @param {Anything} value - a value to push on the outputList for comparison. For instance, on charts this is typically the data of the chart.
  112. */
  113. BlockPyPrinter.prototype.printHtml = function(chart, value) {
  114. var step = this.main.model.execution.step();
  115. var line = this.main.model.execution.line_number();
  116. this.main.model.execution.output.push(value);
  117. if (!(this.main.model.settings.mute_printer())) {
  118. var outerDiv = $(Sk.console.png_mode ? chart : chart[0]);//.parent();
  119. outerDiv.parent().show();
  120. outerDiv.attr({
  121. "data-toggle": 'tooltip',
  122. "data-placement": 'left',
  123. //"data-container": '#'+chart.attr("id"),
  124. "class": "blockpy-printer-output",
  125. "data-step": step,
  126. "title": "Step "+step+", Line "+line
  127. });
  128. // outerDiv.tooltip();
  129. }
  130. }
  131. /**
  132. * Creates an Input box for receiving input() from the user.
  133. *
  134. * @param {String} promptMessage - a message to render before the input
  135. * @returns {String} Returns the handle on the message box.
  136. */
  137. BlockPyPrinter.prototype.printInput = function(promptMessage) {
  138. // Should probably be accessing the model instead of a component...
  139. var stepNumber = this.main.components.engine.executionBuffer.step;
  140. var lineNumber = this.main.components.engine.executionBuffer.line_number;
  141. // Perform any necessary cleaning
  142. if (promptMessage !== "\n") {
  143. var encodedText = encodeHTML(promptMessage);
  144. if (!(this.main.model.settings.mute_printer())) {
  145. var inputForm = $("<input type='text' />");
  146. var inputMsg = $("<samp></samp>", {"html": encodedText})
  147. var inputBtn = $("<button></button>", {"html": "Enter"});
  148. var inputBox = $("<div></div>",
  149. {
  150. 'data-toggle': 'tooltip',
  151. 'class': 'blockpy-printer-output',
  152. 'data-placement': 'left',
  153. 'data-step': stepNumber,
  154. 'title': "Step "+stepNumber + ", Line "+lineNumber
  155. });
  156. inputBox.append(inputMsg)
  157. .append($("<br>"))
  158. .append(inputForm)
  159. .append(inputBtn);
  160. this.tag.append(inputBox);
  161. // inputBox.tooltip();
  162. return {'input': inputForm, 'button': inputBtn, 'promise': true};
  163. }
  164. }
  165. return {'promise': false}
  166. }
  167. if (typeof exports !== 'undefined') {
  168. exports.BlockPyPrinter = BlockPyPrinter;
  169. }