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