module WindowTerminal

The primary module in-which the majority of classes and methods are bundled.

Constants

STDOUT_HANDLE
TIOCGNWINSZ

Public Class Methods

add_window(win) click to toggle source

Adds a window to the render.

# File lib/accu-window.rb, line 598
def self.add_window(win)
        @@windows << win
end
ask_quietly() { |string| ... } click to toggle source

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
get_windows() click to toggle source

Returns the windows currently being rendered.

# File lib/accu-window.rb, line 609
def self.get_windows()
        @@windows
end
getchr() { |string| ... } click to toggle source

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
getchrs() { |string,full| ... } click to toggle source

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
os() click to toggle source

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
remove_window(win) click to toggle source

Remoes a window from the render.

# File lib/accu-window.rb, line 603
def self.remove_window(win)
        @@windows.delete(win)
end
screen_render() click to toggle source

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
terminal_size() click to toggle source

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