rutui 0.7 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ # Space Invader ~ Example image format
2
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
3
+ nil|nil|nil| :0:10|nil|nil|nil| :0:10|nil|nil|nil
4
+ nil|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil|nil
5
+ nil| :0:10| :0:10|nil| :0:10| :0:10| :0:10|nil| :0:10| :0:10|nil
6
+ :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10
7
+ :0:10|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil| :0:10
8
+ :0:10|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil| :0:10
9
+ nil|nil|nil| :0:10| :0:10|nil| :0:10| :0:10|nil|nil|nil
10
+
@@ -0,0 +1,73 @@
1
+ # Space Invader SPRITE ~ Example image format
2
+ ---down---
3
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
4
+ nil|nil|nil| :0:10|nil|nil|nil| :0:10|nil|nil|nil
5
+ nil|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil|nil
6
+ nil| :0:10| :0:10| :0:12| :0:10| :0:10| :0:10| :0:12| :0:10| :0:10|nil
7
+ :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10
8
+ :0:10|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil| :0:10
9
+ :0:10|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil| :0:10
10
+ nil|nil|nil| :0:10| :0:10|nil| :0:10| :0:10|nil|nil|nil
11
+ ---down---
12
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
13
+ nil|nil|nil| :0:10|nil|nil|nil| :0:10|nil|nil|nil
14
+ :0:10|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil| :0:10
15
+ :0:10| :0:10| :0:10| :0:12| :0:10| :0:10| :0:10| :0:12| :0:10| :0:10| :0:10
16
+ :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10
17
+ nil|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil|nil
18
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
19
+ nil| :0:10|nil|nil|nil|nil|nil|nil|nil| :0:10|nil
20
+ ---up---
21
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
22
+ nil|nil|nil| :0:10|nil|nil|nil| :0:10|nil|nil|nil
23
+ nil|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil|nil
24
+ nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil
25
+ :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10
26
+ :0:10|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil| :0:10
27
+ :0:10|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil| :0:10
28
+ nil|nil|nil| :0:10| :0:10|nil| :0:10| :0:10|nil|nil|nil
29
+ ---up---
30
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
31
+ nil|nil|nil| :0:10|nil|nil|nil| :0:10|nil|nil|nil
32
+ :0:10|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil| :0:10
33
+ :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10
34
+ :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10
35
+ nil|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil|nil
36
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
37
+ nil| :0:10|nil|nil|nil|nil|nil|nil|nil| :0:10|nil
38
+ ---right---
39
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
40
+ nil|nil|nil| :0:10|nil|nil|nil| :0:10|nil|nil|nil
41
+ nil|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil|nil
42
+ nil| :0:10| :0:10| :0:10| :0:12| :0:10| :0:10| :0:10| :0:12| :0:10|nil
43
+ :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10
44
+ :0:10|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil| :0:10
45
+ :0:10|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil| :0:10
46
+ nil|nil|nil| :0:10| :0:10|nil| :0:10| :0:10|nil|nil|nil
47
+ ---right---
48
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
49
+ nil|nil|nil| :0:10|nil|nil|nil| :0:10|nil|nil|nil
50
+ :0:10|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil| :0:10
51
+ :0:10| :0:10| :0:10| :0:10| :0:12| :0:10| :0:10| :0:10| :0:12| :0:10| :0:10
52
+ :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10
53
+ nil|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil|nil
54
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
55
+ nil| :0:10|nil|nil|nil|nil|nil|nil|nil| :0:10|nil
56
+ ---left---
57
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
58
+ nil|nil|nil| :0:10|nil|nil|nil| :0:10|nil|nil|nil
59
+ nil|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil|nil
60
+ nil| :0:10| :0:12| :0:10| :0:10| :0:10| :0:12| :0:10| :0:10| :0:10|nil
61
+ :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10
62
+ :0:10|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil| :0:10
63
+ :0:10|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil| :0:10
64
+ nil|nil|nil| :0:10| :0:10|nil| :0:10| :0:10|nil|nil|nil
65
+ ---left---
66
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
67
+ nil|nil|nil| :0:10|nil|nil|nil| :0:10|nil|nil|nil
68
+ :0:10|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil| :0:10
69
+ :0:10| :0:10| :0:12| :0:10| :0:10| :0:10| :0:12| :0:10| :0:10| :0:10| :0:10
70
+ :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10
71
+ nil|nil| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10| :0:10|nil|nil
72
+ nil|nil| :0:10|nil|nil|nil|nil|nil| :0:10|nil|nil
73
+ nil| :0:10|nil|nil|nil|nil|nil|nil|nil| :0:10|nil
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib_dir = File.dirname(__FILE__) + '/../lib'
4
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
5
+
6
+ require 'rutui'
7
+
8
+ screen = RuTui::Screen.new
9
+ @table = RuTui::Table.new({
10
+ :x => 1,
11
+ :y => 1,
12
+ :highlight_direction => :horizontal, # default
13
+ :table => [
14
+ [1,"Some", "random","example"],
15
+ [2,"text", "presented", "in"],
16
+ [3,"an", "table","plus some random way to long text"]
17
+ ],
18
+ :cols => [
19
+ { :title => "ID", :color => RuTui::Pixel.random.fg, :title_color => RuTui::Pixel.random.fg, :length => 3 },
20
+ { :title => "Col 1", :color => RuTui::Pixel.random.fg, :title_color => RuTui::Pixel.random.fg },
21
+ { :title => "Col 2", :color => RuTui::Pixel.random.fg, :title_color => RuTui::Pixel.random.fg },
22
+ { :title => "Col 3", :color => RuTui::Pixel.random.fg, :title_color => RuTui::Pixel.random.fg, :max_length => 10 }
23
+ ],
24
+ :header => true,
25
+ :hover => 32,
26
+ :background => 30
27
+ })
28
+ screen.add @table
29
+ screen.add_static RuTui::Text.new( :x => 1, :y => 9, :text => "Selection: cursor keys, Sort by col: x, Exit: q or CTRL+C" )
30
+
31
+ highlight = 0
32
+ highlight2 = 0
33
+
34
+ RuTui::ScreenManager.add :default, screen
35
+ RuTui::ScreenManager.loop({ :autodraw => true }) do |key|
36
+ break if key == "q" or key == :ctrl_c # CTRL+C
37
+
38
+ (highlight += 1; @table.highlight_direction = :horizontal; @table.highlight highlight) if key == :down and highlight < @table.height-1
39
+ (highlight -= 1; @table.highlight_direction = :horizontal; @table.highlight highlight) if key == :up and highlight >= 1
40
+ (highlight2 += 1; @table.highlight_direction = :vertical; @table.highlight highlight2) if key == :right and highlight2 < @table.width-1
41
+ (highlight2 -= 1; @table.highlight_direction = :vertical; @table.highlight highlight2) if key == :left and highlight2 >= 1
42
+
43
+ if key == "x"
44
+ @table.sort highlight2
45
+ end
46
+
47
+ end
48
+
49
+ print RuTui::Ansi.clear_color + RuTui::Ansi.clear
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib_dir = File.dirname(__FILE__) + '/../lib'
4
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
5
+
6
+ require 'rutui'
7
+
8
+ screen = RuTui::Screen.new
9
+
10
+ size = RuTui::Screen.size
11
+
12
+ screen.add_static RuTui::Text.new({ :x => size[1]/2-30, :y => 2, :text => "use the cursor keys to choose the sprite or q/CTRL+C to quit" })
13
+
14
+ res_dir = File.dirname(__FILE__) + '/res/'
15
+ sprites = RuTui::Sprite.new({ :x => size[1]/2-6, :y => 5, :file => res_dir + 'space-invader_sprite.axx' })
16
+ screen.add sprites
17
+
18
+ Thread.new {
19
+ while true
20
+ sprites.update
21
+ RuTui::ScreenManager.draw
22
+ sleep 0.8
23
+ end
24
+ }
25
+
26
+ RuTui::ScreenManager.loop({ :autofit => true, :autodraw => false }) do |key|
27
+
28
+ break if key == :ctrl_c or key == "q"
29
+
30
+ # We can translate the key symbol to a string to set the sprite
31
+ if [:up, :down, :left, :right].include? key
32
+ sprites.set_current key.to_s
33
+ end
34
+ end
35
+
36
+ print RuTui::Ansi.clear_color + RuTui::Ansi.clear
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib_dir = File.dirname(__FILE__) + '/../lib'
4
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
5
+
6
+ require 'rutui'
7
+
8
+ screen = RuTui::Screen.new
9
+ @tf1 = RuTui::Textfield.new({ :x => 1, :y => 1, :pixel => RuTui::Pixel.new(12,44,"-"), :focus_pixel => RuTui::Pixel.new(15,64,"-") })
10
+ @tf2 = RuTui::Textfield.new({ :x => 1, :y => 4, :password => true })
11
+
12
+ screen.add @tf1
13
+ screen.add @tf2
14
+ screen.add_static RuTui::Text.new( :x => 1, :y => 7, :text => "Start writing, change focus with [tab]" )
15
+
16
+ @focus = 0
17
+ @tf1.set_focus
18
+
19
+ RuTui::ScreenManager.add :default, screen
20
+ RuTui::ScreenManager.loop({ :autodraw => true }) do |key|
21
+ break if key == "q" or key == :ctrl_c # CTRL+C
22
+
23
+ if @focus == 1 and key == :tab
24
+ @tf2.take_focus
25
+ @focus = 0
26
+ @tf1.set_focus
27
+ elsif @focus == 0 and key == :tab
28
+ @tf1.take_focus
29
+ @focus = 1
30
+ @tf2.set_focus
31
+ end
32
+ @tf1.write key if @tf1.focus
33
+ @tf2.write key if @tf2.focus
34
+ end
35
+
36
+ print RuTui::Ansi.clear_color + RuTui::Ansi.clear
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Tic-Tac-Toe
4
+ #
5
+ # This is the first example done in this library
6
+ # Its more a proof of concept than an read worthy example
7
+ #
8
+
9
+ lib_dir = File.dirname(__FILE__) + '/../lib'
10
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
11
+
12
+ require 'rutui'
13
+
14
+ RuTui::Theme.use :basic
15
+ screen = RuTui::Screen.new
16
+
17
+ RuTui::ScreenManager.add :default, screen
18
+ RuTui::ScreenManager.set_current :default
19
+
20
+ size = RuTui::Screen.size
21
+ map = [[0,0,0],[0,0,0],[0,0,0]]
22
+ current = "X"
23
+ pos = [0,0]
24
+
25
+ screen.add_static RuTui::Text.new({
26
+ :x => (size[1]/2)-3,
27
+ :y => 2,
28
+ :text => "Tic-Tac-Toe",
29
+ :foreground => 15 })
30
+
31
+ screen.add_static RuTui::Text.new({
32
+ :x => (size[1]/2)-2,
33
+ :y => 3,
34
+ :text => "by b1nary",
35
+ :foreground => 244 })
36
+
37
+ screen.add info = RuTui::Text.new({
38
+ :x => (size[1]/2)-3,
39
+ :y => 12,
40
+ :text => "Current: #{current}",
41
+ :foreground => 250 })
42
+
43
+ hor = RuTui::Pixel.new(RuTui::Theme.get(:border).fg, RuTui::Theme.get(:background).bg, "-")
44
+ ver = RuTui::Pixel.new(RuTui::Theme.get(:border).fg, RuTui::Theme.get(:background).bg, "|")
45
+ cor = RuTui::Pixel.new(RuTui::Theme.get(:border).fg, RuTui::Theme.get(:background).bg, "*")
46
+
47
+ xhor = RuTui::Pixel.new(RuTui::Theme.get(:textcolor), RuTui::Theme.get(:background).bg, "-")
48
+ xver = RuTui::Pixel.new(RuTui::Theme.get(:textcolor), RuTui::Theme.get(:background).bg, "|")
49
+ xcor = RuTui::Pixel.new(RuTui::Theme.get(:textcolor), RuTui::Theme.get(:background).bg, "#")
50
+
51
+ 3.times do |ir|
52
+ 3.times do |ic|
53
+ screen.add_static RuTui::Box.new({
54
+ :x => (size[1]/2)+(ic*4-4),
55
+ :y => 5+(ir*2),
56
+ :width => 5,
57
+ :height => 3,
58
+ :horizontal => hor,
59
+ :vertical => ver,
60
+ :corner => cor })
61
+ end
62
+ end
63
+
64
+ screen.add box0 = RuTui::Box.new({
65
+ :x => (size[1]/2)-4,
66
+ :y => 5,
67
+ :width => 5,
68
+ :height => 3,
69
+ :horizontal => xhor,
70
+ :vertical => xver,
71
+ :corner => xcor })
72
+
73
+
74
+ RuTui::ScreenManager.loop({ :autodraw => true }) do |key|
75
+
76
+ if key == "q" or key == :ctrl_c # CTRL+C
77
+ break
78
+
79
+ elsif key == " " # space bar
80
+ if map[pos[0]][pos[1]] == 0
81
+ color = RuTui::Theme.get(:rainbow)[1] if current == "X"
82
+ color = RuTui::Theme.get(:rainbow)[0] if current == "O"
83
+
84
+ screen.add RuTui::Text.new({
85
+ :x => (size[1]/2)+(pos[0]*4-4)+2,
86
+ :y => 5+(pos[1]*2)+1,
87
+ :text => current,
88
+ :foreground => color })
89
+
90
+ map[pos[0]][pos[1]] = current.dup
91
+
92
+ # Simple all possibilities, not that much so ....
93
+ (info.set_text "#{current} WON! yay!"; RuTui::ScreenManager.draw; break) if (map[0][0] == map[0][1] and map[0][0] == map[0][2] and map[0][2]!=0) or (map[1][0] == map[1][1] and map[1][0] == map[1][2] and map[1][2]!=0) or (map[2][0] == map[2][1] and map[2][0] == map[2][2] and map[2][2]!=0) or (map[0][0] == map[1][0] and map[1][0] == map[2][0] and map[2][0]!=0) or (map[0][1] == map[1][1] and map[1][1] == map[2][1] and map[2][1]!=0) or (map[0][2] == map[1][2] and map[1][2] == map[2][2] and map[1][2]!=0) or (map[0][0] == map[1][1] and map[1][1] == map[2][2] and map[1][1]!=0) or (map[2][0] == map[1][1] and map[2][0] == map[0][2] and map[2][0]!=0)
94
+
95
+ if current == "X"
96
+ current = "O"
97
+ else
98
+ current = "X"
99
+ end
100
+
101
+ info.set_text "Current: #{current}"
102
+ end
103
+
104
+ elsif key == 'w' or key == :up # up
105
+ (box0.move(0,-2); pos[1] -= 1) if pos[1] > 0
106
+ elsif key == 's' or key == :down # down
107
+ (box0.move(0,2); pos[1] += 1) if pos[1] < 2
108
+ elsif key == 'd' or key == :right # right
109
+ (box0.move(4,0); pos[0] += 1) if pos[0] < 2
110
+ elsif key == 'a' or key == :left # left
111
+ (box0.move(-4,0); pos[0] -= 1) if pos[0] > 0
112
+ end
113
+ end
114
+
115
+ print RuTui::Ansi.clear_color + RuTui::Ansi.clear
@@ -41,6 +41,8 @@ module RuTui
41
41
  # Goto position
42
42
  def self.position x,y; "\e[#{y};#{x}f"; end
43
43
  # Hide cursor
44
- def self.hide_cursor; "\e?25l"; end
44
+ def self.hide_cursor; "\e[?25l"; end
45
+ # Show cursor
46
+ def self.show_cursor; "\e[?25h"; end
45
47
  end
46
48
  end
@@ -0,0 +1,96 @@
1
+ module RuTui
2
+ ## Checkbox Object Class
3
+ # Creates an Checkbox element
4
+ #
5
+ # Methods:
6
+ # :set_focus Set focus to this textfield
7
+ # :take_focus Unset focus
8
+ # :toggle Toggle checkbox
9
+ # :check Check
10
+ # :uncheck Uncheck
11
+ #
12
+ # Attributes (all accessible):
13
+ # :x MUST
14
+ # :y MUST
15
+ # :pixel - pixel from which colors get inherted
16
+ # :focus_pixel - pixel used when on focus (defaults to pixel)
17
+ # :focus - has focus?
18
+ # :checked - is checked?
19
+ # :symbol_checked - symbol if checked
20
+ # :symbol_unchecked - symbol if unchecked
21
+ #
22
+ class Checkbox < BaseObject
23
+ attr_accessor :focus, :checked
24
+
25
+ def initialize options
26
+ @pixel = options[:pixel]
27
+ @pixel = Theme.get(:border) if @pixel.nil?
28
+
29
+ @focus_pixel = options[:focus_pixel]
30
+ @focus_pixel = @pixel if @focus_pixel.nil?
31
+
32
+ @symbol_checked = options[:symbol_checked]
33
+ @symbol_checked = "☑" if @symbol_checked.nil?
34
+
35
+ @symbol_unchecked = options[:symbol_unchecked]
36
+ @symbol_unchecked = "☐" if @symbol_unchecked.nil?
37
+
38
+ @x = options[:x]
39
+ @x = 1 if @x.nil?
40
+ @y = options[:y]
41
+ @y = 1 if @y.nil?
42
+
43
+ @focus = options[:focus]
44
+ @focus = false if @focus.nil?
45
+
46
+ @checked = options[:checked]
47
+ @checked = false if @checked.nil?
48
+
49
+ create
50
+ end
51
+
52
+ def set_focus
53
+ @focus = true
54
+ create
55
+ end
56
+
57
+ def take_focus
58
+ @focus = false
59
+ create
60
+ end
61
+
62
+ def toggle
63
+ if @checked
64
+ self.uncheck
65
+ else
66
+ self.check
67
+ end
68
+ end
69
+
70
+ def check
71
+ @checked = true
72
+ create
73
+ end
74
+
75
+ def uncheck
76
+ @checked = false
77
+ create
78
+ end
79
+
80
+ private
81
+
82
+ def create
83
+ if @focus
84
+ @obj = [[@focus_pixel]]
85
+ else
86
+ @obj = [[@pixel]]
87
+ end
88
+
89
+ if @checked
90
+ @obj[0][0].symbol = @symbol_checked
91
+ else
92
+ @obj[0][0].symbol = @symbol_unchecked
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,219 @@
1
+ module RuTui
2
+ ## Input class
3
+ # read and interpret keyboard input
4
+ class Input
5
+ def self.init
6
+ # Look for the current terminal in the hash of terminal scancodes and
7
+ # contruct a scancode -> key symbol lookup hash. This hash will we used
8
+ # by self.getc to translate the received key presses to symbols.
9
+ @@scancodes.keys.each { |term|
10
+ # Match the terminal name as regexp to get variants,
11
+ # e.g. xterm matches xterm-256color, too.
12
+ if /#{term}/.match(ENV["TERM"])
13
+ @@keys = Hash[@@scancodes[term].zip @@key_symbols]
14
+ break
15
+ end
16
+ }
17
+
18
+ # Special keys are currently not supported on Windows
19
+ # That needs some investigation
20
+ if RUBY_PLATFORM =~ /(win32|w32)/
21
+ @@keys = {}
22
+ end
23
+
24
+ # Exit with failure if the terminal was not found
25
+ unless defined? @@keys
26
+ STDERR.puts "Unsupported terminal '#{ENV['TERM']}'."
27
+ exit 1
28
+ end
29
+
30
+ # Add the common control key definitions
31
+ @@keys.merge!(@@control_keys)
32
+ end
33
+
34
+ # Get input char without enter
35
+ def self.getc
36
+ begin
37
+ IO.console.raw!
38
+ key = IO.console.getch
39
+
40
+ if key == "\e"
41
+ begin
42
+ char = IO.console.getch(min: 0, time: 0)
43
+ key += char unless char.nil?
44
+ end until char.nil?
45
+ end
46
+
47
+ ensure
48
+ IO.console.cooked!
49
+ end
50
+
51
+ # look up special keys
52
+ if @@keys.has_key? key
53
+ return @@keys[key]
54
+ else
55
+ return key
56
+ end
57
+ end
58
+
59
+ private
60
+ @@key_symbols = [
61
+ :f1,
62
+ :f2,
63
+ :f3,
64
+ :f4,
65
+ :f5,
66
+ :f6,
67
+ :f7,
68
+ :f8,
69
+ :f9,
70
+ :f10,
71
+ :f11,
72
+ :f12,
73
+ :insert,
74
+ :delete,
75
+ :home,
76
+ :end,
77
+ :pgup,
78
+ :pgdn,
79
+ :up,
80
+ :down,
81
+ :left,
82
+ :right,
83
+ ]
84
+
85
+ # Keyboard scancodes for some terminals.
86
+ # The order of keys must match the key symbols above.
87
+ @@scancodes = {
88
+ "linux" => [
89
+ "\e[[A", # F1
90
+ "\e[[B", # F2
91
+ "\e[[C", # F3
92
+ "\e[[D", # F4
93
+ "\e[[E", # F5
94
+ "\e[17~", # F6
95
+ "\e[18~", # F7
96
+ "\e[19~", # F8
97
+ "\e[20~", # F9
98
+ "\e[21~", # F10
99
+ "\e[23~", # F11
100
+ "\e[24~", # F12
101
+ "\e[2~", # ins
102
+ "\e[3~", # del
103
+ "\e[1~", # home
104
+ "\e[4~", # end
105
+ "\e[5~", # page up
106
+ "\e[6~", # page down
107
+ "\e[A", # up
108
+ "\e[B", # down
109
+ "\e[D", # left
110
+ "\e[C", # right
111
+ ],
112
+ "Eterm" => [
113
+ "\e[11~", # F1
114
+ "\e[12~", # F2
115
+ "\e[13~", # F3
116
+ "\e[14~", # F4
117
+ "\e[15~", # F5
118
+ "\e[17~", # F6
119
+ "\e[18~", # F7
120
+ "\e[19~", # F8
121
+ "\e[20~", # F9
122
+ "\e[21~", # F10
123
+ "\e[23~", # F11
124
+ "\e[24~", # F12
125
+ "\e[2~", # ins
126
+ "\e[3~", # del
127
+ "\e[7~", # home
128
+ "\e[8~", # end
129
+ "\e[5~", # page up
130
+ "\e[6~", # page down
131
+ "\e[A", # arrow up
132
+ "\e[B", # arrow down
133
+ "\e[D", # arrow left
134
+ "\e[C", # arrow right
135
+ ],
136
+ "rxvt" => [
137
+ "\e[11~", # F1
138
+ "\e[12~", # F2
139
+ "\e[13~", # F3
140
+ "\e[14~", # F4
141
+ "\e[15~", # F5
142
+ "\e[17~", # F6
143
+ "\e[18~", # F7
144
+ "\e[19~", # F8
145
+ "\e[20~", # F9
146
+ "\e[21~", # F10
147
+ "\e[23~", # F11
148
+ "\e[24~", # F12
149
+ "\e[2~", # ins
150
+ "\e[3~", # del
151
+ "\e[7~", # home
152
+ "\e[8~", # end
153
+ "\e[5~", # page up
154
+ "\e[6~", # page down
155
+ "\e[A", # up
156
+ "\e[B", # down
157
+ "\e[D", # left
158
+ "\e[C", # right
159
+ ],
160
+ "xterm" => [
161
+ "\eOP", # F1
162
+ "\eOQ", # F2
163
+ "\eOR", # F3
164
+ "\eOS", # F4
165
+ "\e[15~", # F5
166
+ "\e[17~", # F6
167
+ "\e[18~", # F7
168
+ "\e[19~", # F8
169
+ "\e[20~", # F9
170
+ "\e[21~", # F10
171
+ "\e[23~", # F11
172
+ "\e[24~", # F12
173
+ "\e[2~", # ins
174
+ "\e[3~", # del
175
+ "\e[H", # home
176
+ "\e[F", # end
177
+ "\e[5~", # page up
178
+ "\e[6~", # page down
179
+ "\e[A", # up
180
+ "\e[B", # down
181
+ "\e[D", # left
182
+ "\e[C", # right
183
+ ]
184
+ }
185
+
186
+ @@control_keys = {
187
+ "\x01" => :ctrl_a,
188
+ "\x02" => :ctrl_b,
189
+ "\x03" => :ctrl_c,
190
+ "\x04" => :ctrl_d,
191
+ "\x05" => :ctrl_e,
192
+ "\x06" => :ctrl_f,
193
+ "\a" => :ctrl_g,
194
+ "\b" => :ctrl_h,
195
+ "\t" => :tab, # aka CTRL+I
196
+ "\n" => :ctrl_n,
197
+ "\v" => :ctrl_k,
198
+ "\f" => :ctrl_l,
199
+ "\r" => :enter, # aka CTRL+M
200
+ "\x0e" => :ctrl_n,
201
+ "\x0f" => :ctrl_o,
202
+ "\x10" => :ctrl_p,
203
+ "\x11" => :ctrl_q,
204
+ "\x12" => :ctrl_r,
205
+ "\x13" => :ctrl_s,
206
+ "\x14" => :ctrl_t,
207
+ "\x15" => :ctrl_u,
208
+ "\x16" => :ctrl_v,
209
+ "\x17" => :ctrl_w,
210
+ "\x18" => :ctrl_x,
211
+ "\x19" => :ctrl_y,
212
+ "\x1a" => :ctrl_z,
213
+ "\e" => :esc,
214
+ "\x7f" => :backspace
215
+ }
216
+ end
217
+ end
218
+
219
+ RuTui::Input.init