tui.rb 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. # Copyright 2024 Henrique Paone
  2. #
  3. # This file is part of Ruby-tui.
  4. #
  5. # Ruby-tui is free software: you can redistribute it and/or modify it under the
  6. # terms of the GNU General Public License as published by the Free Software
  7. # Foundation, either version 3 of the License, or (at your option) any later
  8. # version.
  9. #
  10. # Ruby-tui is distributed in the hope that it will be useful, but WITHOUT ANY
  11. # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  12. # PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License along with
  15. # Ruby-tui. If not, see <https://www.gnu.org/licenses/>.
  16. module Tui
  17. Ansi_regex = /\x1b\[[0-9;:]*[mGKHF]/
  18. Line_chars = {
  19. hori: "\u2500",
  20. vert: "\u2502",
  21. ulcor: "\u250c",
  22. urcor: "\u2510",
  23. llcor: "\u2514",
  24. lrcor: "\u2518",
  25. rvert: "\u251c",
  26. lvert: "\u2524"
  27. }
  28. def move_cursor(line, col)
  29. printf "\e[%d;%dH", line, col
  30. end
  31. def move_cursor_left
  32. print "\e[D"
  33. end
  34. def hide_cursor
  35. print "\e[?25l"
  36. end
  37. def show_cursor
  38. print "\e[?25h"
  39. end
  40. def save_cursor
  41. print "\e7"
  42. end
  43. def restore_cursor
  44. print "\e8"
  45. end
  46. def save_screen
  47. printf "\e[?1049h"
  48. end
  49. def restore_screen
  50. printf "\e[?1049l"
  51. end
  52. def redraw
  53. save_screen
  54. restore_screen
  55. end
  56. def clear_current_line
  57. print "\e[0K"
  58. end
  59. def erase_char
  60. printf "\e[1X"
  61. end
  62. def backspace
  63. move_cursor_left
  64. erase_char
  65. end
  66. def scroll_down(lines)
  67. print "\e[#{ lines }S"
  68. end
  69. def scroll_up(lines)
  70. print "\e[#{ lines }T"
  71. end
  72. # getch doesn't trigger signals, so we manually catch them
  73. def readc
  74. c = STDIN.getch
  75. Process.kill("INT", $$) if c == "\u0003"
  76. Process.kill("STOP", $$) if c == "\u001a"
  77. c
  78. end
  79. def print_centered(text, l, c, llim, rlim)
  80. text.split("\n").reject(&:empty?).each do |line|
  81. move_cursor(l, c)
  82. mbyte = line.chars.count do |char| char.bytesize > 1 end
  83. print line.center(rlim - llim - mbyte)
  84. l += 1
  85. end
  86. l
  87. end
  88. def print_line_before(text, line, col)
  89. text.reverse.each_char do |c|
  90. move_cursor(line, col)
  91. print c
  92. col -= 1
  93. end
  94. end
  95. def draw_vline_inbox(c1, c2, l)
  96. move_cursor(l, c1)
  97. print Line_chars[:rvert]
  98. draw_hline(c1 + 1, c2, l)
  99. print Line_chars[:lvert]
  100. end
  101. def draw_hline(c1, c2, l)
  102. move_cursor(l, c1)
  103. (c2 - c1).times do print Line_chars[:hori] end
  104. end
  105. def draw_vline(l1, l2, c)
  106. (l1..l2).each do |l|
  107. move_cursor(l, c)
  108. print Line_chars[:vert]
  109. end
  110. end
  111. def draw_box(l1, c1, l2, c2)
  112. # Draw corners
  113. move_cursor(l1, c1)
  114. print Line_chars[:ulcor]
  115. move_cursor(l1, c2)
  116. print Line_chars[:urcor]
  117. move_cursor(l2, c1)
  118. print Line_chars[:llcor]
  119. move_cursor(l2, c2)
  120. print Line_chars[:lrcor]
  121. draw_hline(c1 + 1, c2, l1)
  122. draw_hline(c1 + 1, c2, l2)
  123. draw_vline(l1 + 1, l2 - 1, c1)
  124. draw_vline(l1 + 1, l2 - 1, c2)
  125. end
  126. end