Module: WindowTerminal

Defined in:
lib/accu-window.rb

Overview

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

Defined Under Namespace

Modules: Templates Classes: ColoredText, ColoredWrappedText, Line, Orientation, Text, Window, WindowManager, WrappedText

Constant Summary collapse

TIOCGNWINSZ =
0x5413
STDOUT_HANDLE =
0xFFFFFFF5
@@windows =
[]

Class Method Summary collapse

Class Method Details

.add_window(win) ⇒ Object

Adds a window to the render.



598
599
600
# File 'lib/accu-window.rb', line 598

def self.add_window(win)
  @@windows << win
end

.ask_quietly {|string| ... } ⇒ Object

Gets a string from user using the highline library ask() set to no echo.

Yields:

  • (string)


790
791
792
793
794
795
# 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_windowsObject

Returns the windows currently being rendered.



609
610
611
# File 'lib/accu-window.rb', line 609

def self.get_windows()
  @@windows
end

.getchrObject

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.



804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
# 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

.getchrsObject

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.



830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
# 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

.osObject

Returns current operating system based on the return value of ENV.



616
617
618
619
620
621
622
623
624
# 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) ⇒ Object

Remoes a window from the render.



603
604
605
# File 'lib/accu-window.rb', line 603

def self.remove_window(win)
  @@windows.delete(win)
end

.screen_renderObject

Renders the screen using current window objects.



628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
# 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_sizeObject

Gets current terminal size based on the operating system and returns the result.



575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
# 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