console_view.vala 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * Copyright(c) 2012-2015 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/dbartolini/crown/blob/master/LICENSE-GPLv2
  4. */
  5. using Gtk;
  6. namespace Crown
  7. {
  8. public class EntryHistory
  9. {
  10. private uint _max_records;
  11. private uint _size;
  12. private uint _current;
  13. private string[] _history;
  14. // Creates a new hisory with room for max_records records.
  15. public EntryHistory(uint max_records)
  16. {
  17. _max_records = max_records;
  18. _size = 0;
  19. _current = 0;
  20. _history = new string[max_records];
  21. }
  22. // Push a new string into the history.
  23. public void push(string text)
  24. {
  25. // Add command to history
  26. _history[_size] = text;
  27. _size = (uint)Math.fmin((double)_size + 1, (double)_max_records - 1);
  28. _current = _size;
  29. }
  30. // Returns the previous entry in the history.
  31. public string previous()
  32. {
  33. _current = _current > 0 ? _current -1 : 0;
  34. return _history[_current];
  35. }
  36. // Returns the next entry in the history.
  37. public string next()
  38. {
  39. _current = (uint)Math.fmin((double)_current + 1, (double)_size - 1);
  40. return _history[_current];
  41. }
  42. }
  43. public class ConsoleView : Gtk.Box
  44. {
  45. // Data
  46. private EntryHistory _entry_history;
  47. private ConsoleClient _console_client;
  48. private Project _project;
  49. // Widgets
  50. private Gtk.ScrolledWindow _scrolled_window;
  51. private Gtk.TextView _text_view;
  52. private Gtk.Entry _entry;
  53. public ConsoleView(ConsoleClient client, Project project)
  54. {
  55. Object(orientation: Gtk.Orientation.VERTICAL, spacing: 0);
  56. // Data
  57. _entry_history = new EntryHistory(256);
  58. _console_client = client;
  59. _project = project;
  60. // Widgets
  61. Pango.FontDescription fd = new Pango.FontDescription();
  62. fd.set_family("Monospace");
  63. _text_view = new Gtk.TextView();
  64. _text_view.editable = false;
  65. _text_view.can_focus = false;
  66. _text_view.override_font(fd);
  67. // // Create tags for color-formatted text
  68. Gtk.TextTag tag_info = new Gtk.TextTag("info");
  69. tag_info.foreground_rgba = { 0.7, 0.7, 0.7, 1.0 };
  70. Gtk.TextTag tag_warning = new Gtk.TextTag("warning");
  71. tag_warning.foreground_rgba = { 1.0, 1.0, 0.4, 1.0 };
  72. Gtk.TextTag tag_error = new Gtk.TextTag("error");
  73. tag_error.foreground_rgba = { 1.0, 0.4, 0.4, 1.0 };
  74. Gtk.TextBuffer tb = _text_view.buffer;
  75. tb.tag_table.add(tag_info);
  76. tb.tag_table.add(tag_warning);
  77. tb.tag_table.add(tag_error);
  78. _scrolled_window = new Gtk.ScrolledWindow(null, null);
  79. _scrolled_window.add(_text_view);
  80. _entry = new Gtk.Entry();
  81. _entry.key_press_event.connect(on_entry_key_pressed);
  82. _entry.activate.connect(on_entry_activated);
  83. pack_start(_scrolled_window, true, true, 0);
  84. pack_start(_entry, false, true, 0);
  85. set_size_request(700, 150);
  86. show_all();
  87. }
  88. private void on_entry_activated()
  89. {
  90. string text = _entry.text;
  91. text = text.strip();
  92. if (text.length > 0)
  93. {
  94. _entry_history.push(text);
  95. if (text[0] == ':')
  96. {
  97. string[] args = text[1:text.length].split(" ");
  98. _console_client.send(DeviceApi.command(args));
  99. }
  100. else
  101. {
  102. _console_client.send_script(text);
  103. }
  104. }
  105. _entry.text = "";
  106. }
  107. private bool on_entry_key_pressed(Gdk.EventKey ev)
  108. {
  109. if (ev.keyval == Gdk.Key.Down)
  110. _entry.text = _entry_history.next();
  111. else if (ev.keyval == Gdk.Key.Up)
  112. _entry.text = _entry_history.previous();
  113. else
  114. return false;
  115. _entry.set_position(_entry.text.length);
  116. return true;
  117. }
  118. public void logi(string system, string text)
  119. {
  120. log(system, text, "info");
  121. }
  122. public void logw(string system, string text)
  123. {
  124. log(system, text, "warning");
  125. }
  126. public void loge(string system, string text)
  127. {
  128. log(system, text, "error");
  129. }
  130. public void log(string system, string text, string severity)
  131. {
  132. string msg = text;
  133. // Replace IDs with human-readable names
  134. int id_index = text.index_of("#ID(");
  135. if (id_index != -1)
  136. {
  137. string id = text.substring(id_index + 4, 33);
  138. string name = _project.id_to_name(id);
  139. msg = text.replace("#ID(%s)".printf(id), "'%s'".printf(name));
  140. }
  141. string line = system + ": " + msg + "\n";
  142. Gtk.TextBuffer buffer = _text_view.buffer;
  143. Gtk.TextIter end_iter;
  144. buffer.get_end_iter(out end_iter);
  145. buffer.insert(ref end_iter, line, line.length);
  146. end_iter.backward_chars(line.length);
  147. Gtk.TextIter start_iter = end_iter;
  148. buffer.get_end_iter(out end_iter);
  149. buffer.apply_tag(buffer.tag_table.lookup(severity), start_iter, end_iter);
  150. _text_view.scroll_to_mark(buffer.create_mark("bottom", end_iter, false), 0, true, 0.0, 1.0);
  151. }
  152. }
  153. }