module WindowTerminal
The primary module in-which the majority of classes and methods are bundled.
Constants
- STDOUT_HANDLE
- TIOCGNWINSZ
Public Class Methods
Adds a window to the render.
# File lib/accu-window.rb, line 598 def self.add_window(win) @@windows << win end
Gets a string from user using the highline library ask() set to no echo.
# File lib/accu-window.rb, line 790 def self.ask_quietly() string = ask("") { |q| q.echo = '' } yield(string) if block_given? self.screen_render return string end
Returns the windows currently being rendered.
# File lib/accu-window.rb, line 609 def self.get_windows() @@windows end
Gets a single character from the terminal emulator in linux, otherwise it returns an empty string.
Also yields the character to a passed block before rendering.
# File lib/accu-window.rb, line 804 def self.getchr() if self.os == :linux then string = "" begin system("stty raw -echo") string = STDIN.getc ensure system("stty -raw echo") end yield string if block_given? self.screen_render return string else "" end end
Similar to ask_quietly
but renders the screen after each character is entered.
A block may also be passed which will be executed just before a render with the current character and the full string thus far.
# File lib/accu-window.rb, line 830 def self.getchrs() if self.os == :linux then full = "" string = " " string = self.getchr() while (string.ord != 13) do if string.ord == 127 and full.length > 0 then full.slice!(full.length - 1) else full << string.ord end yield(string,full) if block_given? self.screen_render string = self.getchr() end return full else "" end end
Returns current operating system based on the return value of ENV.
# File lib/accu-window.rb, line 616 def self.os op = :blah if ENV["OS"] == nil then op = :linux else op = :windows end return op end
Remoes a window from the render.
# File lib/accu-window.rb, line 603 def self.remove_window(win) @@windows.delete(win) end
Renders the screen using current window objects.
# File lib/accu-window.rb, line 628 def self.screen_render #-- rows,cols = *WindowTerminal.terminal_size line1 = "" line2 = "" cols.times {|num| line1 << "#" line2 << " " } line2[0] = "#" line2[-1] = "#" line1 << "\n" line2 << "\n" lines = "" rows.times {|num| if num != 0 and num != rows - 1 then lines << line2 else lines << line1 end } if @@windows.length == 1 then window = @@windows[0] # Add lines for window. lines = lines.split("\n") lines.each_index { |index| #puts index if index > 1 and index < rows - 2 then lines[index][1] = "|" lines[index][-2] = "|" end } lines[1].gsub!(" ","-") #lines[3].gsub!(" ","-") lines[-2].gsub!(" ","-") # Render window objects. window.for_objects{ |object| if object.respond_to? :render_line then lines[object.y+2] = object.render_line(lines[object.y+2],cols,2) elsif object.respond_to? :render then lines = object.render(lines,rows,cols) end } lines = lines.join("\n") elsif @@windows.length == 2 then window1,window2 = @@windows[0],@@windows[1] if window1.orientation.x != window2.orientation.x then # Box-Box if window1.orientation.x > window2.orientation.x then left_window = window2 right_window = window1 else left_window = window1 right_window = window2 end lines = lines.split("\n") lines_left = [] lines_right = [] width = (cols - 1) left_dimension = (width / 2).ceil right_dimension = width - left_dimension lines.each_index {|index| #puts "iteration" lines_left[index] = lines[index].slice(0..left_dimension) lines_right[index] = lines[index].slice(right_dimension..width) } [[left_window,lines_left],[right_window,lines_right]].each { |array| window = array[0] current_lines = array[1] current_lines.each_index { |index| if index > 1 and index < rows - 2 then current_lines[index][0] = "#" current_lines[index][-1] = "#" current_lines[index][1] = "|" current_lines[index][-2] = "|" end } local_cols = current_lines[0].length current_lines[1].gsub!(" ","-") current_lines[-2].gsub!(" ","-") window.for_objects{ |object| if object.respond_to? :render_line then current_lines[object.y+2] = object.render_line(current_lines[object.y+2],local_cols,2) end } } lines = [] lines_left.each_index { |index| lines[index] = lines_left[index] + lines_right[index] } lines_left = [] lines_right = [] lines = lines.join("\n") else # Box / Box if window1.orientation.y > window2.orientation.y then up_window = window2 down_window = window1 else up_window = window1 down_window = window2 end lines = lines.split("\n") up_lines = [] down_lines = [] height = (rows - 1) up_dimension = (height / 2).ceil down_dimension = height - up_dimension lines.each_index {|index| #puts "iteration" if index <= up_dimension then up_lines << lines[index] else down_lines << lines[index] end } [[up_window,up_lines],[down_window,down_lines]].each { |array| window = array[0] current_lines = array[1] current_lines[1].gsub!(" ","-") old = current_lines[-1].dup current_lines[-1].gsub!(" ","-") if current_lines[-1] == old then current_lines[-2].gsub!(" ","-") end current_lines.each_index { |index| if index == 0 or index == rows - 1 then current_lines[index] = line1.dup.gsub("\n","") # elsif index == 1 or index == rows - 2 then # current_lines[index].gsub!(" ","-") else #current_lines[index][0] = "#" #current_lines[index][-1] = "#" if current_lines[index][1] != "#" then current_lines[index][1] = "|" current_lines[index][-2] = "|" end end } window.for_objects{ |object| if object.respond_to? :render_line then current_lines[object.y+2] = object.render_line(current_lines[object.y+2],cols,2) end } } lines = [] up_lines.each { |line| lines << line } up_lines = [] down_lines.each {|line| lines << line } down_lines = [] lines = lines.join("\n") end end print lines #++ end
Gets current terminal size based on the operating system and returns the result.
# File lib/accu-window.rb, line 575 def self.terminal_size if self.os == :windows then m_GetStdHAndle = Win32Api.new("kernel32","GetStdHandle",["L"],"L") m_GetConsoleScreenBufferInfo = Win32Api.new("kernel32","GetConsoleScreenBufferInfo",["L","P"],"L") format = "SSSSSssssSS" buf = ([0] * format.size).pack(format) stdout_handle = m_GetStdHandle.call(STDOUT_HANDLE) m_GetConsoleScreenBufferInfo.call(stdout_handle, buf) (bufx, bufy, curx, cury, wattr, left, top, right, bottom, maxx, maxy) = buf.unpack(format) return bottom - top + 1, right - left + 1 else rows, cols = 25, 80 buf = [ 0, 0, 0, 0 ].pack("SSSS") if STDOUT.ioctl(TIOCGNWINSZ, buf) >= 0 then rows, cols, row_pixels, col_pixels = buf.unpack("SSSS")[0..1] end return rows,cols end end