cura-termbox 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 472b032d744709d45da7575030194f28c5df1cfb
4
+ data.tar.gz: 015266ad33e99172f56361326c6649739ce67339
5
+ SHA512:
6
+ metadata.gz: 51013f0e83448fbaabf8ab11b2890b6c6e796f14ee46230d9649b962a77933294d6f66d5b06df187fb31145f85086af35f5ee7109cc05657227042d38ac019bf
7
+ data.tar.gz: 02b4c785e9e66087937f52686cdbd92b0a5907920609895ec02ffca925a80cc13b6de5f6a961bc985050fe8e2520fa75cec84043fa7153458bb87ba9213749a7
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source "https://rubygems.org"
2
+
3
+ group :development do
4
+ gem "fuubar", "~> 2.0.0"
5
+ gem "mutant-rspec", "~> 0.8.0"
6
+ gem "rake", "~> 10.4.2"
7
+ gem "reek", "~> 3.0.4"
8
+ gem "rspec", "~> 3.3.0"
9
+ gem "rubocop", "~> 0.32.1"
10
+ gem "ruby-prof", "~> 0.15.8"
11
+ gem "simplecov-json", "~> 0.2"
12
+ gem "simplecov", "~> 0.10.0"
13
+ gem "yard", "~> 0.8.7.6"
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,119 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ abstract_type (0.0.7)
5
+ adamantium (0.2.0)
6
+ ice_nine (~> 0.11.0)
7
+ memoizable (~> 0.4.0)
8
+ anima (0.2.0)
9
+ abstract_type (~> 0.0.7)
10
+ adamantium (~> 0.1)
11
+ equalizer (~> 0.0.8)
12
+ ast (2.0.0)
13
+ astrolabe (1.3.1)
14
+ parser (~> 2.2)
15
+ concord (0.1.5)
16
+ adamantium (~> 0.2.0)
17
+ equalizer (~> 0.0.9)
18
+ diff-lcs (1.2.5)
19
+ docile (1.1.5)
20
+ equalizer (0.0.11)
21
+ fuubar (2.0.0)
22
+ rspec (~> 3.0)
23
+ ruby-progressbar (~> 1.4)
24
+ ice_nine (0.11.1)
25
+ json (1.8.3)
26
+ memoizable (0.4.2)
27
+ thread_safe (~> 0.3, >= 0.3.1)
28
+ morpher (0.2.3)
29
+ abstract_type (~> 0.0.7)
30
+ adamantium (~> 0.2.0)
31
+ anima (~> 0.2.0)
32
+ ast (~> 2.0.0)
33
+ concord (~> 0.1.4)
34
+ equalizer (~> 0.0.9)
35
+ ice_nine (~> 0.11.0)
36
+ procto (~> 0.0.2)
37
+ mutant (0.8.0)
38
+ abstract_type (~> 0.0.7)
39
+ adamantium (~> 0.2.0)
40
+ anima (~> 0.2.0)
41
+ ast (~> 2.0)
42
+ concord (~> 0.1.5)
43
+ diff-lcs (~> 1.2)
44
+ equalizer (~> 0.0.9)
45
+ ice_nine (~> 0.11.1)
46
+ memoizable (~> 0.4.2)
47
+ morpher (~> 0.2.3)
48
+ parallel (~> 1.3)
49
+ parser (~> 2.2.2)
50
+ procto (~> 0.0.2)
51
+ unparser (~> 0.2.4)
52
+ mutant-rspec (0.8.0)
53
+ mutant (~> 0.8.0)
54
+ rspec-core (>= 3.2.0, < 3.4.0)
55
+ parallel (1.6.0)
56
+ parser (2.2.2.6)
57
+ ast (>= 1.1, < 3.0)
58
+ powerpack (0.1.1)
59
+ procto (0.0.2)
60
+ rainbow (2.0.0)
61
+ rake (10.4.2)
62
+ reek (3.0.4)
63
+ parser (~> 2.2.2.5)
64
+ rainbow (~> 2.0)
65
+ unparser (~> 0.2.2)
66
+ rspec (3.3.0)
67
+ rspec-core (~> 3.3.0)
68
+ rspec-expectations (~> 3.3.0)
69
+ rspec-mocks (~> 3.3.0)
70
+ rspec-core (3.3.1)
71
+ rspec-support (~> 3.3.0)
72
+ rspec-expectations (3.3.0)
73
+ diff-lcs (>= 1.2.0, < 2.0)
74
+ rspec-support (~> 3.3.0)
75
+ rspec-mocks (3.3.1)
76
+ diff-lcs (>= 1.2.0, < 2.0)
77
+ rspec-support (~> 3.3.0)
78
+ rspec-support (3.3.0)
79
+ rubocop (0.32.1)
80
+ astrolabe (~> 1.3)
81
+ parser (>= 2.2.2.5, < 3.0)
82
+ powerpack (~> 0.1)
83
+ rainbow (>= 1.99.1, < 3.0)
84
+ ruby-progressbar (~> 1.4)
85
+ ruby-prof (0.15.8)
86
+ ruby-progressbar (1.7.5)
87
+ simplecov (0.10.0)
88
+ docile (~> 1.1.0)
89
+ json (~> 1.8)
90
+ simplecov-html (~> 0.10.0)
91
+ simplecov-html (0.10.0)
92
+ simplecov-json (0.2)
93
+ json
94
+ simplecov
95
+ thread_safe (0.3.5)
96
+ unparser (0.2.4)
97
+ abstract_type (~> 0.0.7)
98
+ adamantium (~> 0.2.0)
99
+ concord (~> 0.1.5)
100
+ diff-lcs (~> 1.2.5)
101
+ equalizer (~> 0.0.9)
102
+ parser (~> 2.2.2)
103
+ procto (~> 0.0.2)
104
+ yard (0.8.7.6)
105
+
106
+ PLATFORMS
107
+ ruby
108
+
109
+ DEPENDENCIES
110
+ fuubar (~> 2.0.0)
111
+ mutant-rspec (~> 0.8.0)
112
+ rake (~> 10.4.2)
113
+ reek (~> 3.0.4)
114
+ rspec (~> 3.3.0)
115
+ rubocop (~> 0.32.1)
116
+ ruby-prof (~> 0.15.8)
117
+ simplecov (~> 0.10.0)
118
+ simplecov-json (~> 0.2)
119
+ yard (~> 0.8.7.6)
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2015 Ryan Scott Lewis <ryan@rynet.us>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # Cura Termbox FFI Adapter
2
+
3
+ [Cura][cura] adapter for [Termbox][termbox].
4
+
5
+ ## Install
6
+
7
+ ### Bundler: `gem 'cura-termbox'`
8
+
9
+ ### RubyGems: `gem install cura-termbox`
10
+
11
+ ## Usage
12
+
13
+ TODO
14
+
15
+ TODO: Note that when using MRuby, the include/mrbconf.h should define MRB_UTF8_STRING
16
+
17
+ ## Copyright
18
+
19
+ Copyright © 2015 Ryan Scott Lewis <ryan@rynet.us>.
20
+
21
+ The MIT License (MIT) - See LICENSE for further details.
22
+
23
+ [cura]: https://github.com/RyanScottLewis/cura
24
+ [termbox]: https://github.com/nsf/termbox
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require "pathname"
2
+ require "rubygems/package_task"
3
+ require "yard"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+ require "reek/rake/task"
7
+
8
+ gemspec = Pathname.glob(Pathname.new(__FILE__).join("..", "*.gemspec")).first
9
+ spec = Gem::Specification.load(gemspec.to_s)
10
+
11
+ Gem::PackageTask.new(spec) do |task|
12
+ task.need_zip = false
13
+ end
14
+
15
+ YARD::Rake::YardocTask.new
16
+
17
+ RSpec::Core::RakeTask.new(:spec)
18
+
19
+ RuboCop::RakeTask.new do |task|
20
+ task.patterns = ["lib/**/*.rb"]
21
+ task.formatters = ["fuubar"]
22
+ end
23
+
24
+ Reek::Rake::Task.new do |t|
25
+ t.fail_on_error = false
26
+ end
27
+
28
+ desc "Mutation testing"
29
+ task :mutant do
30
+ exec("mutant --include lib --require cura --use rspec Cura*")
31
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,24 @@
1
+ require 'pathname'
2
+
3
+ Gem::Specification.new do |s|
4
+
5
+ # Variables
6
+ s.author = 'Ryan Scott Lewis'
7
+ s.email = 'ryan@rynet.us'
8
+ s.summary = 'Cura Termbox adapter.'
9
+ s.license = 'MIT'
10
+
11
+ # Dependencies
12
+ s.add_dependency 'termbox-ffi', '~> 0.0.3'
13
+ s.add_development_dependency 'rake', '~> 10.1.1'
14
+
15
+ # Pragmatically set variables
16
+ s.homepage = "http://github.com/RyanScottLewis/#{s.name}"
17
+ s.version = Pathname.glob('VERSION*').first.read rescue '0.0.0'
18
+ s.description = s.summary
19
+ s.name = Pathname.new(__FILE__).basename('.gemspec').to_s
20
+ s.require_paths = ['lib']
21
+ s.files = Dir['{{Rake,Gem}file{.lock,},README*,VERSION,LICENSE,*.gemspec,{lib,bin,spec}/**/*.rb}']
22
+ s.test_files = Dir['{examples,spec,test}/**/*']
23
+
24
+ end
@@ -0,0 +1,192 @@
1
+ if Kernel.respond_to?(:require)
2
+ require "cura/adapter"
3
+
4
+ require "cura/event/key_down"
5
+ require "cura/event/mouse_button"
6
+ require "cura/event/mouse_wheel_down"
7
+ require "cura/event/mouse_wheel_up"
8
+ require "cura/event/resize"
9
+
10
+ require "cura/termbox/error/unsupported_terminal"
11
+ require "cura/termbox/error/failed_to_open_tty"
12
+ require "cura/termbox/error/pipe_trap_error"
13
+ require "cura/termbox/error/not_running"
14
+
15
+ require "cura/termbox/component/base"
16
+
17
+ require "cura/termbox/pencil"
18
+ require "cura/termbox/window"
19
+
20
+ require "termbox"
21
+ end
22
+
23
+ module Cura
24
+ module Termbox
25
+ # Cura adapter for Termbox.
26
+ class Adapter < Cura::Adapter
27
+ mixin Cura::Pencil => Termbox::Pencil
28
+ mixin Cura::Window => Termbox::Window
29
+ mixin Cura::Component::Base => Termbox::Component::Base
30
+
31
+ def setup
32
+ case ::Termbox.tb_init
33
+ when ::Termbox::TB_EUNSUPPORTED_TERMINAL then raise Termbox::Error::UnsupportedTerminal
34
+ when ::Termbox::TB_EFAILED_TO_OPEN_TTY then raise Termbox::Error::FailedToOpenTTY
35
+ when ::Termbox::TB_EPIPE_TRAP_ERROR then raise Termbox::Error::PipeTrapError
36
+ end
37
+
38
+ ::Termbox.tb_select_input_mode(::Termbox::TB_INPUT_ESC | ::Termbox::TB_INPUT_MOUSE)
39
+ # ::Termbox.tb_select_output_mode(::Termbox::TB_OUTPUT_216)
40
+ ::Termbox.tb_select_output_mode(::Termbox::TB_OUTPUT_256)
41
+
42
+ super
43
+ end
44
+
45
+ def clear
46
+ ::Termbox.tb_clear
47
+ end
48
+
49
+ def present
50
+ ::Termbox.tb_present
51
+ end
52
+
53
+ def cleanup
54
+ ::Termbox.tb_shutdown
55
+
56
+ super
57
+ end
58
+
59
+ def set_cursor(x, y)
60
+ ::Termbox.tb_set_cursor(x, y)
61
+ end
62
+
63
+ def hide_cursor
64
+ ::Termbox.tb_set_cursor(::Termbox::TB_HIDE_CURSOR, ::Termbox::TB_HIDE_CURSOR)
65
+ end
66
+
67
+ def poll_event
68
+ event = ::Termbox::Event.new
69
+ ::Termbox.tb_poll_event(event)
70
+
71
+ convert_termbox_event_to_cura_event(event)
72
+ end
73
+
74
+ def peek_event(milliseconds)
75
+ event = ::Termbox::Event.new
76
+ ::Termbox.tb_peek_event(event, milliseconds)
77
+
78
+ convert_termbox_event_to_cura_event(event)
79
+ end
80
+
81
+ protected
82
+
83
+ def convert_termbox_event_to_cura_event(event)
84
+ return nil if event.nil? # TODO: Would it even be nil? Wouldnt it be -1 on errors?
85
+
86
+ event = case event[:type]
87
+ when ::Termbox::TB_EVENT_KEY
88
+ if event[:key] != 0
89
+ name = convert_termbox_key_to_cura_key_name(event[:key])
90
+
91
+ name.nil? ? convert_termbox_control_key_to_cura_event(event[:key]) : Event::KeyDown.new(name: name)
92
+ elsif event[:ch] != 0
93
+ character = event[:ch].chr
94
+ key_name = Cura::Key.name_from_character(character)
95
+
96
+ Event::KeyDown.new(name: key_name)
97
+ end
98
+ when ::Termbox::TB_EVENT_MOUSE
99
+ case event[:key]
100
+ when ::Termbox::TB_KEY_MOUSE_LEFT then Event::MouseButton.new(name: :left, state: :down, x: event[:x], y: event[:y])
101
+ when ::Termbox::TB_KEY_MOUSE_MIDDLE then Event::MouseButton.new(name: :middle, state: :down, x: event[:x], y: event[:y])
102
+ when ::Termbox::TB_KEY_MOUSE_RIGHT then Event::MouseButton.new(name: :right, state: :down, x: event[:x], y: event[:y])
103
+ when ::Termbox::TB_KEY_MOUSE_RELEASE then Event::MouseButton.new(state: :up, x: event[:x], y: event[:y])
104
+ when ::Termbox::TB_KEY_MOUSE_WHEEL_UP then Event::MouseWheelUp.new(x: event[:x], y: event[:y])
105
+ when ::Termbox::TB_KEY_MOUSE_WHEEL_DOWN then Event::MouseWheelDown.new(x: event[:x], y: event[:y])
106
+ end
107
+ when ::Termbox::TB_EVENT_RESIZE then Event::Resize.new(width: event[:w], height: event[:h])
108
+ end
109
+
110
+ event
111
+ end
112
+
113
+ def convert_termbox_control_key_to_cura_event(key)
114
+ case key
115
+ # when ::Termbox::TB_KEY_CTRL_2 then Event::KeyDown.new( name: :"2", control: true ) # clash with 'CTRL_TILDE'
116
+ # when ::Termbox::TB_KEY_CTRL_3 then Event::KeyDown.new( name: :"3", control: true ) # clash with 'ESC'
117
+ # when ::Termbox::TB_KEY_CTRL_4 then Event::KeyDown.new( name: :"4", control: true ) # clash with 'CTRL_BACKSLASH'
118
+ # when ::Termbox::TB_KEY_CTRL_5 then Event::KeyDown.new( name: :"5", control: true ) # clash with 'CTRL_RSQ_BRACKET'
119
+ when ::Termbox::TB_KEY_CTRL_6 then Event::KeyDown.new(name: :"6", control: true)
120
+ # when ::Termbox::TB_KEY_CTRL_7 then Event::KeyDown.new( name: :"7", control: true ) # clash with 'CTRL_SLASH' # clash with 'CTRL_UNDERSCORE'
121
+ # when ::Termbox::TB_KEY_CTRL_8 then Event::KeyDown.new( name: :"8", control: true ) # clash with 'TB_KEY_BACKSPACE2'
122
+ when ::Termbox::TB_KEY_CTRL_A then Event::KeyDown.new(name: :A, control: true)
123
+ when ::Termbox::TB_KEY_CTRL_B then Event::KeyDown.new(name: :B, control: true)
124
+ when ::Termbox::TB_KEY_CTRL_C then Event::KeyDown.new(name: :C, control: true)
125
+ when ::Termbox::TB_KEY_CTRL_D then Event::KeyDown.new(name: :D, control: true)
126
+ when ::Termbox::TB_KEY_CTRL_E then Event::KeyDown.new(name: :E, control: true)
127
+ when ::Termbox::TB_KEY_CTRL_F then Event::KeyDown.new(name: :F, control: true)
128
+ when ::Termbox::TB_KEY_CTRL_G then Event::KeyDown.new(name: :G, control: true)
129
+ # when ::Termbox::TB_KEY_CTRL_H then Event::KeyDown.new( name: :H, control: true ) # clash with 'CTRL_BACKSPACE'
130
+ # when ::Termbox::TB_KEY_CTRL_I then Event::KeyDown.new( name: :I, control: true ) # clash with 'TAB'
131
+ when ::Termbox::TB_KEY_CTRL_J then Event::KeyDown.new(name: :J, control: true)
132
+ when ::Termbox::TB_KEY_CTRL_K then Event::KeyDown.new(name: :K, control: true)
133
+ when ::Termbox::TB_KEY_CTRL_L then Event::KeyDown.new(name: :L, control: true)
134
+ # when ::Termbox::TB_KEY_CTRL_M then Event::KeyDown.new( name: :M, control: true ) # clash with 'ENTER'
135
+ when ::Termbox::TB_KEY_CTRL_N then Event::KeyDown.new(name: :N, control: true)
136
+ when ::Termbox::TB_KEY_CTRL_O then Event::KeyDown.new(name: :O, control: true)
137
+ when ::Termbox::TB_KEY_CTRL_P then Event::KeyDown.new(name: :P, control: true)
138
+ when ::Termbox::TB_KEY_CTRL_Q then Event::KeyDown.new(name: :Q, control: true)
139
+ when ::Termbox::TB_KEY_CTRL_R then Event::KeyDown.new(name: :R, control: true)
140
+ when ::Termbox::TB_KEY_CTRL_S then Event::KeyDown.new(name: :S, control: true)
141
+ when ::Termbox::TB_KEY_CTRL_T then Event::KeyDown.new(name: :T, control: true)
142
+ when ::Termbox::TB_KEY_CTRL_U then Event::KeyDown.new(name: :U, control: true)
143
+ when ::Termbox::TB_KEY_CTRL_V then Event::KeyDown.new(name: :V, control: true)
144
+ when ::Termbox::TB_KEY_CTRL_W then Event::KeyDown.new(name: :W, control: true)
145
+ when ::Termbox::TB_KEY_CTRL_X then Event::KeyDown.new(name: :X, control: true)
146
+ when ::Termbox::TB_KEY_CTRL_Y then Event::KeyDown.new(name: :Y, control: true)
147
+ when ::Termbox::TB_KEY_CTRL_Z then Event::KeyDown.new(name: :Z, control: true)
148
+ when ::Termbox::TB_KEY_CTRL_BACKSLASH then Event::KeyDown.new(name: :backslash, control: true) # clash with 'CTRL_4'
149
+ when ::Termbox::TB_KEY_CTRL_LSQ_BRACKET then Event::KeyDown.new(name: :left_bracket, control: true) # clash with 'ESC'
150
+ when ::Termbox::TB_KEY_CTRL_RSQ_BRACKET then Event::KeyDown.new(name: :right_bracket, control: true) # clash with 'CTRL_5'
151
+ when ::Termbox::TB_KEY_CTRL_SLASH then Event::KeyDown.new(name: :slash, control: true) # clash with 'CTRL_7'
152
+ when ::Termbox::TB_KEY_CTRL_TILDE then Event::KeyDown.new(name: :tilde, control: true) # clash with 'CTRL_2'
153
+ when ::Termbox::TB_KEY_CTRL_UNDERSCORE then Event::KeyDown.new(name: :underscore, control: true) # clash with 'CTRL_7' # clash with 'CTRL_SLASH'
154
+ end
155
+ end
156
+
157
+ def convert_termbox_key_to_cura_key_name(key)
158
+ case key
159
+ when ::Termbox::TB_KEY_F1 then :f1
160
+ when ::Termbox::TB_KEY_F2 then :f2
161
+ when ::Termbox::TB_KEY_F3 then :f3
162
+ when ::Termbox::TB_KEY_F4 then :f4
163
+ when ::Termbox::TB_KEY_F5 then :f5
164
+ when ::Termbox::TB_KEY_F6 then :f6
165
+ when ::Termbox::TB_KEY_F7 then :f7
166
+ when ::Termbox::TB_KEY_F8 then :f8
167
+ when ::Termbox::TB_KEY_F9 then :f9
168
+ when ::Termbox::TB_KEY_F10 then :f10
169
+ when ::Termbox::TB_KEY_F11 then :f11
170
+ when ::Termbox::TB_KEY_F12 then :f12
171
+ when ::Termbox::TB_KEY_F12 then :f12
172
+ when ::Termbox::TB_KEY_INSERT then :insert
173
+ when ::Termbox::TB_KEY_DELETE then :delete
174
+ when ::Termbox::TB_KEY_HOME then :home
175
+ when ::Termbox::TB_KEY_END then :end
176
+ when ::Termbox::TB_KEY_PGUP then :page_up
177
+ when ::Termbox::TB_KEY_PGDN then :page_down
178
+ when ::Termbox::TB_KEY_ARROW_UP then :up
179
+ when ::Termbox::TB_KEY_ARROW_DOWN then :down
180
+ when ::Termbox::TB_KEY_ARROW_LEFT then :left
181
+ when ::Termbox::TB_KEY_ARROW_RIGHT then :right
182
+ when ::Termbox::TB_KEY_BACKSPACE then :backspace
183
+ when ::Termbox::TB_KEY_BACKSPACE2 then :backspace
184
+ when ::Termbox::TB_KEY_ENTER then :enter
185
+ when ::Termbox::TB_KEY_ESC then :escape
186
+ when ::Termbox::TB_KEY_SPACE then :space
187
+ when ::Termbox::TB_KEY_TAB then :tab
188
+ end
189
+ end
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,377 @@
1
+ # /* Colors (see struct tb_cell's fg and bg fields). */
2
+ # #define TB_DEFAULT 0x00
3
+ # #define TB_BLACK 0x01
4
+ # #define TB_RED 0x02
5
+ # #define TB_GREEN 0x03
6
+ # #define TB_YELLOW 0x04
7
+ # #define TB_BLUE 0x05
8
+ # #define TB_MAGENTA 0x06
9
+ # #define TB_CYAN 0x07
10
+ # #define TB_WHITE 0x08
11
+ #
12
+ # /* Attributes, it is possible to use multiple attributes by combining them
13
+ # * using bitwise OR ('|'). Although, colors cannot be combined. But you can
14
+ # * combine attributes and a single color. See also struct tb_cell's fg and bg
15
+ # * fields.
16
+ # */
17
+ # #define TB_BOLD 0x0100
18
+ # #define TB_UNDERLINE 0x0200
19
+ # #define TB_REVERSE 0x0400
20
+ #
21
+ # #define TB_OUTPUT_CURRENT 0
22
+ # #define TB_OUTPUT_NORMAL 1
23
+ # #define TB_OUTPUT_256 2
24
+ # #define TB_OUTPUT_216 3
25
+ # #define TB_OUTPUT_GRAYSCALE 4
26
+ #
27
+ # /* Sets the termbox output mode. Termbox has three output options:
28
+ # * 1. TB_OUTPUT_NORMAL => [1..8]
29
+ # * This mode provides 8 different colors:
30
+ # * black, red, green, yellow, blue, magenta, cyan, white
31
+ # * Shortcut: TB_BLACK, TB_RED, ...
32
+ # * Attributes: TB_BOLD, TB_UNDERLINE, TB_REVERSE
33
+ # *
34
+ # * Example usage:
35
+ # * tb_change_cell(x, y, '@', TB_BLACK | TB_BOLD, TB_RED);
36
+ # *
37
+ # * 2. TB_OUTPUT_256 => [0..256]
38
+ # * In this mode you can leverage the 256 terminal mode:
39
+ # * 0x00 - 0x07: the 8 colors as in TB_OUTPUT_NORMAL
40
+ # * 0x08 - 0x0f: TB_* | TB_BOLD
41
+ # * 0x10 - 0xe7: 216 different colors
42
+ # * 0xe8 - 0xff: 24 different shades of grey
43
+ # *
44
+ # * Example usage:
45
+ # * tb_change_cell(x, y, '@', 184, 240);
46
+ # * tb_change_cell(x, y, '@', 0xb8, 0xf0);
47
+ # *
48
+ # * 2. TB_OUTPUT_216 => [0..216]
49
+ # * This mode supports the 3rd range of the 256 mode only.
50
+ # * But you don't need to provide an offset.
51
+ # *
52
+ # * 3. TB_OUTPUT_GRAYSCALE => [0..23]
53
+ # * This mode supports the 4th range of the 256 mode only.
54
+ # * But you dont need to provide an offset.
55
+ # *
56
+ # * Execute build/src/demo/output to see its impact on your terminal.
57
+ # *
58
+ # * If 'mode' is TB_OUTPUT_CURRENT, it returns the current output mode.
59
+ # *
60
+ # * Default termbox output mode is TB_OUTPUT_NORMAL.
61
+ # */
62
+ # SO_IMPORT int tb_select_output_mode(int mode);
63
+
64
+ if Kernel.respond_to?(:require)
65
+ require "termbox"
66
+ require "cura/color"
67
+ end
68
+
69
+ module Cura
70
+ module Termbox
71
+ # A cached map comparing a color's rgb values with the 256 terminal color codes.
72
+ module ColorMapper
73
+ COLOR_CODES = [
74
+ Color.new(0, 0, 0),
75
+ Color.new(128, 0, 0),
76
+ Color.new(0, 128, 0),
77
+ Color.new(128, 128, 0),
78
+ Color.new(0, 0, 128),
79
+ Color.new(128, 0, 128),
80
+ Color.new(0, 128, 128),
81
+ Color.new(192, 192, 192),
82
+ Color.new(128, 128, 128),
83
+ Color.new(255, 0, 0),
84
+ Color.new(0, 255, 0),
85
+ Color.new(255, 255, 0),
86
+ Color.new(0, 0, 255),
87
+ Color.new(255, 0, 255),
88
+ Color.new(0, 255, 255),
89
+ Color.new(255, 255, 255),
90
+ Color.new(0, 0, 0),
91
+ Color.new(0, 0, 95),
92
+ Color.new(0, 0, 135),
93
+ Color.new(0, 0, 175),
94
+ Color.new(0, 0, 215),
95
+ Color.new(0, 0, 255),
96
+ Color.new(0, 95, 0),
97
+ Color.new(0, 95, 95),
98
+ Color.new(0, 95, 135),
99
+ Color.new(0, 95, 175),
100
+ Color.new(0, 95, 215),
101
+ Color.new(0, 95, 255),
102
+ Color.new(0, 135, 0),
103
+ Color.new(0, 135, 95),
104
+ Color.new(0, 135, 135),
105
+ Color.new(0, 135, 175),
106
+ Color.new(0, 135, 215),
107
+ Color.new(0, 135, 255),
108
+ Color.new(0, 175, 0),
109
+ Color.new(0, 175, 95),
110
+ Color.new(0, 175, 135),
111
+ Color.new(0, 175, 175),
112
+ Color.new(0, 175, 215),
113
+ Color.new(0, 175, 255),
114
+ Color.new(0, 215, 0),
115
+ Color.new(0, 215, 95),
116
+ Color.new(0, 215, 135),
117
+ Color.new(0, 215, 175),
118
+ Color.new(0, 215, 215),
119
+ Color.new(0, 215, 255),
120
+ Color.new(0, 255, 0),
121
+ Color.new(0, 255, 95),
122
+ Color.new(0, 255, 135),
123
+ Color.new(0, 255, 175),
124
+ Color.new(0, 255, 215),
125
+ Color.new(0, 255, 255),
126
+ Color.new(95, 0, 0),
127
+ Color.new(95, 0, 95),
128
+ Color.new(95, 0, 135),
129
+ Color.new(95, 0, 175),
130
+ Color.new(95, 0, 215),
131
+ Color.new(95, 0, 255),
132
+ Color.new(95, 95, 0),
133
+ Color.new(95, 95, 95),
134
+ Color.new(95, 95, 135),
135
+ Color.new(95, 95, 175),
136
+ Color.new(95, 95, 215),
137
+ Color.new(95, 95, 255),
138
+ Color.new(95, 135, 0),
139
+ Color.new(95, 135, 95),
140
+ Color.new(95, 135, 135),
141
+ Color.new(95, 135, 175),
142
+ Color.new(95, 135, 215),
143
+ Color.new(95, 135, 255),
144
+ Color.new(95, 175, 0),
145
+ Color.new(95, 175, 95),
146
+ Color.new(95, 175, 135),
147
+ Color.new(95, 175, 175),
148
+ Color.new(95, 175, 215),
149
+ Color.new(95, 175, 255),
150
+ Color.new(95, 215, 0),
151
+ Color.new(95, 215, 95),
152
+ Color.new(95, 215, 135),
153
+ Color.new(95, 215, 175),
154
+ Color.new(95, 215, 215),
155
+ Color.new(95, 215, 255),
156
+ Color.new(95, 255, 0),
157
+ Color.new(95, 255, 95),
158
+ Color.new(95, 255, 135),
159
+ Color.new(95, 255, 175),
160
+ Color.new(95, 255, 215),
161
+ Color.new(95, 255, 255),
162
+ Color.new(135, 0, 0),
163
+ Color.new(135, 0, 95),
164
+ Color.new(135, 0, 135),
165
+ Color.new(135, 0, 175),
166
+ Color.new(135, 0, 215),
167
+ Color.new(135, 0, 255),
168
+ Color.new(135, 95, 0),
169
+ Color.new(135, 95, 95),
170
+ Color.new(135, 95, 135),
171
+ Color.new(135, 95, 175),
172
+ Color.new(135, 95, 215),
173
+ Color.new(135, 95, 255),
174
+ Color.new(135, 135, 0),
175
+ Color.new(135, 135, 95),
176
+ Color.new(135, 135, 135),
177
+ Color.new(135, 135, 175),
178
+ Color.new(135, 135, 215),
179
+ Color.new(135, 135, 255),
180
+ Color.new(135, 175, 0),
181
+ Color.new(135, 175, 95),
182
+ Color.new(135, 175, 135),
183
+ Color.new(135, 175, 175),
184
+ Color.new(135, 175, 215),
185
+ Color.new(135, 175, 255),
186
+ Color.new(135, 215, 0),
187
+ Color.new(135, 215, 95),
188
+ Color.new(135, 215, 135),
189
+ Color.new(135, 215, 175),
190
+ Color.new(135, 215, 215),
191
+ Color.new(135, 215, 255),
192
+ Color.new(135, 255, 0),
193
+ Color.new(135, 255, 95),
194
+ Color.new(135, 255, 135),
195
+ Color.new(135, 255, 175),
196
+ Color.new(135, 255, 215),
197
+ Color.new(135, 255, 255),
198
+ Color.new(175, 0, 0),
199
+ Color.new(175, 0, 95),
200
+ Color.new(175, 0, 135),
201
+ Color.new(175, 0, 175),
202
+ Color.new(175, 0, 215),
203
+ Color.new(175, 0, 255),
204
+ Color.new(175, 95, 0),
205
+ Color.new(175, 95, 95),
206
+ Color.new(175, 95, 135),
207
+ Color.new(175, 95, 175),
208
+ Color.new(175, 95, 215),
209
+ Color.new(175, 95, 255),
210
+ Color.new(175, 135, 0),
211
+ Color.new(175, 135, 95),
212
+ Color.new(175, 135, 135),
213
+ Color.new(175, 135, 175),
214
+ Color.new(175, 135, 215),
215
+ Color.new(175, 135, 255),
216
+ Color.new(175, 175, 0),
217
+ Color.new(175, 175, 95),
218
+ Color.new(175, 175, 135),
219
+ Color.new(175, 175, 175),
220
+ Color.new(175, 175, 215),
221
+ Color.new(175, 175, 255),
222
+ Color.new(175, 215, 0),
223
+ Color.new(175, 215, 95),
224
+ Color.new(175, 215, 135),
225
+ Color.new(175, 215, 175),
226
+ Color.new(175, 215, 215),
227
+ Color.new(175, 215, 255),
228
+ Color.new(175, 255, 0),
229
+ Color.new(175, 255, 95),
230
+ Color.new(175, 255, 135),
231
+ Color.new(175, 255, 175),
232
+ Color.new(175, 255, 215),
233
+ Color.new(175, 255, 255),
234
+ Color.new(215, 0, 0),
235
+ Color.new(215, 0, 95),
236
+ Color.new(215, 0, 135),
237
+ Color.new(215, 0, 175),
238
+ Color.new(215, 0, 215),
239
+ Color.new(215, 0, 255),
240
+ Color.new(215, 95, 0),
241
+ Color.new(215, 95, 95),
242
+ Color.new(215, 95, 135),
243
+ Color.new(215, 95, 175),
244
+ Color.new(215, 95, 215),
245
+ Color.new(215, 95, 255),
246
+ Color.new(215, 135, 0),
247
+ Color.new(215, 135, 95),
248
+ Color.new(215, 135, 135),
249
+ Color.new(215, 135, 175),
250
+ Color.new(215, 135, 215),
251
+ Color.new(215, 135, 255),
252
+ Color.new(215, 175, 0),
253
+ Color.new(215, 175, 95),
254
+ Color.new(215, 175, 135),
255
+ Color.new(215, 175, 175),
256
+ Color.new(215, 175, 215),
257
+ Color.new(215, 175, 255),
258
+ Color.new(215, 215, 0),
259
+ Color.new(215, 215, 95),
260
+ Color.new(215, 215, 135),
261
+ Color.new(215, 215, 175),
262
+ Color.new(215, 215, 215),
263
+ Color.new(215, 215, 255),
264
+ Color.new(215, 255, 0),
265
+ Color.new(215, 255, 95),
266
+ Color.new(215, 255, 135),
267
+ Color.new(215, 255, 175),
268
+ Color.new(215, 255, 215),
269
+ Color.new(215, 255, 255),
270
+ Color.new(255, 0, 0),
271
+ Color.new(255, 0, 95),
272
+ Color.new(255, 0, 135),
273
+ Color.new(255, 0, 175),
274
+ Color.new(255, 0, 215),
275
+ Color.new(255, 0, 255),
276
+ Color.new(255, 95, 0),
277
+ Color.new(255, 95, 95),
278
+ Color.new(255, 95, 135),
279
+ Color.new(255, 95, 175),
280
+ Color.new(255, 95, 215),
281
+ Color.new(255, 95, 255),
282
+ Color.new(255, 135, 0),
283
+ Color.new(255, 135, 95),
284
+ Color.new(255, 135, 135),
285
+ Color.new(255, 135, 175),
286
+ Color.new(255, 135, 215),
287
+ Color.new(255, 135, 255),
288
+ Color.new(255, 175, 0),
289
+ Color.new(255, 175, 95),
290
+ Color.new(255, 175, 135),
291
+ Color.new(255, 175, 175),
292
+ Color.new(255, 175, 215),
293
+ Color.new(255, 175, 255),
294
+ Color.new(255, 215, 0),
295
+ Color.new(255, 215, 95),
296
+ Color.new(255, 215, 135),
297
+ Color.new(255, 215, 175),
298
+ Color.new(255, 215, 215),
299
+ Color.new(255, 215, 255),
300
+ Color.new(255, 255, 0),
301
+ Color.new(255, 255, 95),
302
+ Color.new(255, 255, 135),
303
+ Color.new(255, 255, 175),
304
+ Color.new(255, 255, 215),
305
+ Color.new(255, 255, 255),
306
+ Color.new(8, 8, 8),
307
+ Color.new(18, 18, 18),
308
+ Color.new(28, 28, 28),
309
+ Color.new(38, 38, 38),
310
+ Color.new(48, 48, 48),
311
+ Color.new(58, 58, 58),
312
+ Color.new(68, 68, 68),
313
+ Color.new(78, 78, 78),
314
+ Color.new(88, 88, 88),
315
+ Color.new(96, 96, 96),
316
+ Color.new(102, 102, 102),
317
+ Color.new(118, 118, 118),
318
+ Color.new(128, 128, 128),
319
+ Color.new(138, 138, 138),
320
+ Color.new(148, 148, 148),
321
+ Color.new(158, 158, 158),
322
+ Color.new(168, 168, 168),
323
+ Color.new(178, 178, 178),
324
+ Color.new(188, 188, 188),
325
+ Color.new(198, 198, 198),
326
+ Color.new(208, 208, 208),
327
+ Color.new(218, 218, 218),
328
+ Color.new(228, 228, 228),
329
+ Color.new(238, 238, 238)
330
+ ]
331
+
332
+ CACHE = {}
333
+
334
+ class << self
335
+ # Find the closest terminal color code from the given RGB values.
336
+ #
337
+ # @param [#to_i] number_of_colors The number of colors in the code list to search. 9 is Termbox without 256 colors enabled I.E. 3-bit.
338
+ # @return [Integer]
339
+ def code(color, _number_of_colors=256)
340
+ code = CACHE[color.hex]
341
+
342
+ if code.nil?
343
+ # code = find_closest_code(rgb, number_of_colors)
344
+
345
+ distances = COLOR_CODES.map { |code| code - color }
346
+ code = distances.each_with_index.min[1]
347
+
348
+ CACHE[color.hex] = code
349
+ end
350
+
351
+ code
352
+ end
353
+
354
+ protected
355
+
356
+ def find_closest_code(rgb, number_of_colors=256)
357
+ last = nil
358
+ COLOR_CODES.first(number_of_colors).each_with_index do |color, code|
359
+ difference = compare_rgb_array(rgb, color)
360
+
361
+ last = { difference: difference, code: code } if last.nil? || difference < last[:difference]
362
+ end
363
+
364
+ last.nil? ? nil : last[:code]
365
+ end
366
+
367
+ def compare_rgb_array(a1, a2)
368
+ Math.sqrt(
369
+ (a1[0] - a2[0]).abs ^ 2 +
370
+ (a1[1] - a2[1]).abs ^ 2 +
371
+ (a1[2] - a2[2]).abs ^ 2
372
+ )
373
+ end
374
+ end
375
+ end
376
+ end
377
+ end
@@ -0,0 +1,28 @@
1
+ module Cura
2
+ module Termbox
3
+ module Component
4
+ module Base
5
+ def self.included(base)
6
+ base.instance_eval do
7
+ remove_method(:foreground)
8
+ remove_method(:background)
9
+ end
10
+ end
11
+
12
+ # Get the foreground color of this component.
13
+ #
14
+ # @return [Color]
15
+ def foreground
16
+ get_or_inherit_color(:foreground, Cura::Color.white)
17
+ end
18
+
19
+ # Get the background color of this component.
20
+ #
21
+ # @return [Color]
22
+ def background
23
+ get_or_inherit_color(:background, Cura::Color.black)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ require "cura/error/base" if Kernel.respond_to?(:require)
2
+
3
+ module Cura
4
+ module Error
5
+ module Termbox
6
+ # The base class for Cura::Termbox errors.
7
+ class Base < Error::Base
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ require "cura/termbox/error/base" if Kernel.respond_to?(:require)
2
+
3
+ module Cura
4
+ module Error
5
+ module Termbox
6
+ class FailedToOpenTTY < Base
7
+ def to_s
8
+ "Could not open TTY."
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require "cura/termbox/error/base" if Kernel.respond_to?(:require)
2
+
3
+ module Cura
4
+ module Error
5
+ module Termbox
6
+ class NotRunning < Base
7
+ def to_s
8
+ "Termbox adapter is not running."
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require "cura/termbox/error/base" if Kernel.respond_to?(:require)
2
+
3
+ module Cura
4
+ module Error
5
+ module Termbox
6
+ class PipeTrapError < Base
7
+ def to_s
8
+ "Pipe trap error."
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require "cura/termbox/error/base" if Kernel.respond_to?(:require)
2
+
3
+ module Cura
4
+ module Error
5
+ module Termbox
6
+ class UnsupportedTerminal < Base
7
+ def to_s
8
+ "The current terminal is unsupported."
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,56 @@
1
+ require "cura/termbox/color_mapper" if Kernel.respond_to?(:require)
2
+
3
+ module Cura
4
+ module Termbox
5
+ # TODO: terminal_code(9) should be 9 or 256 depending on the termbox configuration
6
+ module Pencil
7
+ # Change a point relative to this component's coordinates.
8
+ def draw_point(x, y, color=Cura::Color.black)
9
+ x = x.to_i
10
+ y = y.to_i
11
+ color = ColorMapper.code(color, 256) if color.is_a?(Color)
12
+
13
+ ::Termbox.tb_change_cell(x, y, 0, color, color)
14
+ end
15
+
16
+ # Change a rectangle of points relative to this component's coordinates.
17
+ def draw_rectangle(x, y, width, height, color=Cura::Color.black)
18
+ x = x.to_i
19
+ y = y.to_i
20
+ width = width.to_i
21
+ height = height.to_i
22
+ color = ColorMapper.code(color, 256) if color.is_a?(Color)
23
+
24
+ width = 1 if width < 1
25
+ height = 1 if height < 1
26
+
27
+ width.times do |x_offset|
28
+ height.times do |y_offset|
29
+ ::Termbox.tb_change_cell(x + x_offset, y + y_offset, 0, color, color)
30
+ end
31
+ end
32
+ end
33
+
34
+ def draw_character(x, y, character, foreground=Cura::Color.black, background=Cura::Color.white, bold=false, underline=false)
35
+ x = x.to_i
36
+ y = y.to_i
37
+ foreground = ColorMapper.code(foreground, 256) if foreground.is_a?(Color)
38
+ background = ColorMapper.code(background, 256) if background.is_a?(Color)
39
+
40
+ character = character.to_s[0].codepoints.first
41
+ character ||= 0
42
+
43
+ foreground |= ::Termbox::TB_BOLD if bold
44
+ foreground |= ::Termbox::TB_UNDERLINE if underline
45
+
46
+ ::Termbox.tb_change_cell(x, y, character, foreground, background)
47
+ end
48
+
49
+ def draw_text(x, y, text, foreground=Cura::Color.black, background=Cura::Color.white, bold=false, underline=false)
50
+ text.to_s.each_char do |character|
51
+ draw_character(x, y, character, foreground, background, bold, underline)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,22 @@
1
+ require "termbox" if Kernel.respond_to?(:require)
2
+
3
+ module Cura
4
+ module Termbox
5
+ # Termbox specific mixins for Cura::Window.
6
+ module Window
7
+ # Get the width of this window.
8
+ #
9
+ # @return [Integer]
10
+ def width
11
+ ::Termbox.tb_width
12
+ end
13
+
14
+ # Get the height of this window.
15
+ #
16
+ # @return [Integer]
17
+ def height
18
+ ::Termbox.tb_height
19
+ end
20
+ end
21
+ end
22
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cura-termbox
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ryan Scott Lewis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: termbox-ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 10.1.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 10.1.1
41
+ description: Cura Termbox adapter.
42
+ email: ryan@rynet.us
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - Gemfile
48
+ - Gemfile.lock
49
+ - LICENSE
50
+ - README.md
51
+ - Rakefile
52
+ - VERSION
53
+ - cura-termbox.gemspec
54
+ - lib/cura/termbox/adapter.rb
55
+ - lib/cura/termbox/color_mapper.rb
56
+ - lib/cura/termbox/component/base.rb
57
+ - lib/cura/termbox/error/base.rb
58
+ - lib/cura/termbox/error/failed_to_open_tty.rb
59
+ - lib/cura/termbox/error/not_running.rb
60
+ - lib/cura/termbox/error/pipe_trap_error.rb
61
+ - lib/cura/termbox/error/unsupported_terminal.rb
62
+ - lib/cura/termbox/pencil.rb
63
+ - lib/cura/termbox/window.rb
64
+ homepage: http://github.com/RyanScottLewis/
65
+ licenses:
66
+ - MIT
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 2.4.5
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: Cura Termbox adapter.
88
+ test_files: []