cura-termbox 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []