curtis 0.1.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: 594a8d82f90717fc2c0afaecbf1668d922475103
4
+ data.tar.gz: 3fd56878c5bc42a8bb8bf6eceec5b9433580e918
5
+ SHA512:
6
+ metadata.gz: 03d5b63f9a503ef610595e196257cbf2ef4ed2e0686ecf6b87b2afe95f1851055f5da0e44108dee70f58f8f81e63e48c03df83ca4467bb2c2b123b7a2fc6a54a
7
+ data.tar.gz: 9b66c9911b0d3f30d172a9726d97277bd8ee19e70bd82a1e3df53ebfe625732bcee61d804ab43ebb76c31f3d0c6680c0a4364a2988807015cc0796af6fdcbda1
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.sublime*
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in curtis.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Stefan Rotariu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # Curtis
2
+
3
+ Extremely light wrapper around ncurses-ruby.
4
+
5
+ ## Installation
6
+
7
+ Use the GitHub url in your Gemfile for now. RubyGems coming soon.
8
+
9
+ ## Usage
10
+
11
+ Below is a really simple example:
12
+
13
+ ```ruby
14
+ require 'curtis'
15
+
16
+ # The #show method is the starting point.
17
+ # `screen` here is the standard screen, and is the #parent of other views.
18
+ Curtis.show do |screen|
19
+ screen.puts 'Welcome to Curtis. A simple ncurses-ruby wrapper.', h: :center
20
+ screen.render
21
+
22
+ # Initialize a new View via keyword arguments.
23
+ # All attributes are optional and can be set at a later time.
24
+ lower_left = Curtis::View.new(lines: screen.lines / 2, columns: screen.columns / 2, line: screen.lines / 2)
25
+
26
+ # Fill the lower_left view with the letter 'L'
27
+ 0.upto lower_left.lines do |line|
28
+ lower_left.move_cursor line: line
29
+ lower_left.addstr 'L' * lower_left.columns
30
+ end
31
+
32
+ # Actually show the contents of `lower_left`
33
+ lower_left.render
34
+
35
+ # Initialize a new View via block, and using fancy percentages
36
+ lower_right = Curtis::View.new do |v|
37
+ v.lines = v.parent.lines / 2
38
+ v.columns = v.parent.columns / 2
39
+ v.line = v.parent.lines / 2
40
+ v.column = v.parent.columns / 2
41
+ end
42
+
43
+ # Fill the `lower_right` view with the letter 'R'
44
+ 0.upto lower_right.lines do |line|
45
+ lower_right.move_cursor line: line
46
+ lower_right.addstr 'R' * lower_right.columns
47
+ end
48
+
49
+ # Actually show the contents of `lower_right`
50
+ lower_right.render
51
+
52
+ screen.move_cursor line: screen.lines / 4
53
+ screen.puts '[Q]uit!', h: :center
54
+
55
+ # Press 'q' to stop the input loop
56
+ Curtis::Input.get do |key|
57
+ break if key == 'q'
58
+ end
59
+ end
60
+ ```
61
+
62
+ ## Development
63
+
64
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
65
+
66
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
67
+
68
+ ## TODO
69
+
70
+ * Tests (how? srlsy)
71
+ * Add more Ncurses options
72
+ * Improve readme
73
+
74
+ ## Contributing
75
+
76
+ Bug reports and pull requests are welcome on GitHub at https://github.com/shuriu/curtis.
77
+
78
+ ## License
79
+
80
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
81
+
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "curtis"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/curtis.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'curtis/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "curtis"
8
+ spec.version = Curtis::VERSION
9
+ spec.authors = ["Stefan Rotariu"]
10
+ spec.email = ["stefan.rotariu@gmail.com"]
11
+
12
+ spec.summary = %q{Extremely light wrapper around ncurses-ruby.}
13
+ spec.homepage = "https://github.com/shuriu/curtis"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency 'ncurses-ruby', '~> 1.2.4'
22
+ spec.add_development_dependency "bundler", "~> 1.11"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "minitest", "~> 5.0"
25
+ end
data/examples/basic.rb ADDED
@@ -0,0 +1,46 @@
1
+ require 'curtis'
2
+
3
+ # The #show method is the starting point.
4
+ # `screen` here is the standard screen, and is the #parent of other views.
5
+ Curtis.show do |screen|
6
+ screen.puts 'Welcome to Curtis. A simple ncurses-ruby wrapper.', h: :center
7
+ screen.render
8
+
9
+ # Initialize a new View via keyword arguments.
10
+ # All attributes are optional and can be set at a later time.
11
+ lower_left = Curtis::View.new(lines: screen.lines / 2, columns: screen.columns / 2, line: screen.lines / 2)
12
+
13
+ # Fill the lower_left view with the letter 'L'
14
+ 0.upto lower_left.lines do |line|
15
+ lower_left.move_cursor line: line
16
+ lower_left.addstr 'L' * lower_left.columns
17
+ end
18
+
19
+ # Actually show the contents of `lower_left`
20
+ lower_left.render
21
+
22
+ # Initialize a new View via block, and using fancy percentages
23
+ lower_right = Curtis::View.new do |v|
24
+ v.lines = v.parent.lines
25
+ v.columns = v.parent.columns
26
+ v.line = v.parent.lines
27
+ v.column = v.parent.columns
28
+ end
29
+
30
+ # Fill the `lower_right` view with the letter 'R'
31
+ 0.upto lower_right.lines do |line|
32
+ lower_right.move_cursor line: line
33
+ lower_right.addstr 'R' * lower_right.columns
34
+ end
35
+
36
+ # Actually show the contents of `lower_right`
37
+ lower_right.render
38
+
39
+ screen.move_cursor line: screen.lines
40
+ screen.puts '[Q]uit!', h: :center
41
+
42
+ # Press 'q' to stop the input loop
43
+ Curtis::Input.get do |key|
44
+ break if key == 'q'
45
+ end
46
+ end
@@ -0,0 +1,43 @@
1
+ # This example shows a box centered on the screen, and an auto-updating
2
+ # timestamp. You can also resize the screen to see that the box
3
+ # remains centered.
4
+
5
+ require 'curtis'
6
+
7
+ Curtis.show do |screen|
8
+ # Use lambdas for dimensions and coordinates,
9
+ # so that subsequent calls to #resize, and #reposition
10
+ # can be done without recalculating the new size, or position.
11
+ center = Curtis::View.new do |v|
12
+ v.lines = -> { v.parent.lines / 2 }
13
+ v.columns = -> { v.parent.columns / 2 }
14
+ v.line = -> { v.parent.lines / 4 }
15
+ v.column = -> { v.parent.columns / 4 }
16
+ end
17
+
18
+ center.border
19
+ # Do the operation encolsed in the block every 100 milliseconds
20
+ # in a different thread. #close ensures that the thread is stopped.
21
+ center.render every: 0.1 do
22
+ center.puts Time.now.strftime('%H:%M:%S.%L'), h: :center, v: :center
23
+ end
24
+
25
+ # Curtis::Input.get with a block starts a loop
26
+ Curtis::Input.get do |key|
27
+ break if key != :resize
28
+
29
+ # Redraw the screen
30
+ screen.clear
31
+ screen.render
32
+
33
+ # Redraw the viewl
34
+ center.clear
35
+ center.resize
36
+ center.reposition
37
+
38
+ center.border
39
+ center.render every: 0.1 do
40
+ center.puts Time.now.strftime('%H:%M:%S.%L'), h: :center, v: :center
41
+ end
42
+ end
43
+ end
data/examples/steps.rb ADDED
@@ -0,0 +1,27 @@
1
+ # Views in this example are initialized with defaults.
2
+
3
+ require 'curtis'
4
+
5
+ Curtis.show do |screen|
6
+ first = Curtis::View.new
7
+ first.border
8
+ first.move_cursor line: first.lines / 2
9
+ first.puts 'This is step 1.', h: :center
10
+ first.cursor.newline!
11
+ first.puts 'Press any key...', h: :center
12
+ first.render
13
+
14
+ Curtis::Input.get
15
+ first.delwin
16
+ screen.clear
17
+ screen.render
18
+
19
+ second = Curtis::View.new
20
+ second.border
21
+ second.move_cursor line: second.lines / 2
22
+ second.puts 'Step 2.', h: :center
23
+ second.cursor.newline!
24
+ second.puts 'Press any key to quit.', h: :center
25
+ second.render
26
+ Curtis::Input.get
27
+ end
@@ -0,0 +1,3 @@
1
+ require 'curtis/base_view/cursor'
2
+ require 'curtis/base_view/size'
3
+ require 'curtis/base_view/position'
@@ -0,0 +1,46 @@
1
+ module Curtis
2
+ class BaseView
3
+ class Cursor
4
+ attr_reader :view
5
+
6
+ def initialize(view)
7
+ @view = view
8
+ end
9
+
10
+ def line
11
+ line_and_column.first
12
+ end
13
+
14
+ def line=(new_line, reset_column: true)
15
+ new_column = reset_column ? 0 : column
16
+ view.window.move new_line, new_column
17
+ end
18
+
19
+ def column
20
+ line_and_column.last
21
+ end
22
+
23
+ def column=(new_column)
24
+ view.move line, new_column
25
+ end
26
+
27
+ def rewind!
28
+ view.move 0, 0
29
+ end
30
+
31
+ def newline!
32
+ view.move line + 1, 0
33
+ end
34
+
35
+ def line_and_column
36
+ line, column = [], []
37
+ view.window.getyx(line, column)
38
+ [line.first, column.first]
39
+ end
40
+
41
+ def to_s
42
+ line_and_column.join(', ')
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,33 @@
1
+ module Curtis
2
+ class BaseView
3
+ class Position
4
+ attr_reader :view
5
+
6
+ def initialize(view)
7
+ @view = view
8
+ end
9
+
10
+ def line
11
+ line_and_column.first
12
+ end
13
+
14
+ def column
15
+ line_and_column.last
16
+ end
17
+
18
+ def bottom
19
+
20
+ end
21
+
22
+ def line_and_column
23
+ line, column = [], []
24
+ view.window.getbegyx(line, column)
25
+ [line.first, column.first]
26
+ end
27
+
28
+ def to_s
29
+ line_and_column.join(', ')
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,29 @@
1
+ module Curtis
2
+ class BaseView
3
+ class Size
4
+ attr_reader :view
5
+
6
+ def initialize(view)
7
+ @view = view
8
+ end
9
+
10
+ def lines
11
+ lines_and_columns.first
12
+ end
13
+
14
+ def columns
15
+ lines_and_columns.last
16
+ end
17
+
18
+ def lines_and_columns
19
+ lines, columns = [], []
20
+ view.window.getmaxyx(lines, columns)
21
+ [lines.first, columns.first]
22
+ end
23
+
24
+ def to_s
25
+ lines_and_columns.join(', ')
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ require 'forwardable'
2
+ require 'curtis/base_view/all'
3
+ require 'curtis/helpers/all'
4
+
5
+ module Curtis
6
+ class BaseView
7
+ extend Forwardable
8
+
9
+ attr_reader :cursor, :size, :position
10
+ attr_reader :window
11
+
12
+ include Helpers::Text
13
+ include Helpers::Border
14
+
15
+ def_delegators :size, :lines, :columns
16
+ def_delegators :position, :line, :column
17
+
18
+ def initialize(ncurses_window = Ncurses.stdscr)
19
+ unless ncurses_window.kind_of? Ncurses::WINDOW
20
+ fail ArgumentError, 'Only Ncurses::WINDOW instances allowed.'
21
+ end
22
+
23
+ @window = ncurses_window
24
+ @cursor = Cursor.new(self)
25
+ @size = Size.new(self)
26
+ @position = Position.new(self)
27
+ end
28
+
29
+ def method_missing(method_name, *arguments, &block)
30
+ return super unless window.respond_to?(method_name)
31
+ window.send(method_name, *arguments, &block)
32
+ end
33
+
34
+ def respond_to_missing?(method_name, include_private = false)
35
+ window.respond_to?(method_name) || super
36
+ end
37
+
38
+ def parent
39
+ window
40
+ end
41
+
42
+ def render
43
+ window.refresh
44
+ end
45
+
46
+ def move_cursor(line: 0, column: 0)
47
+ window.move(line, column)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,2 @@
1
+ require 'curtis/helpers/text'
2
+ require 'curtis/helpers/border'
@@ -0,0 +1,14 @@
1
+ module Curtis
2
+ module Helpers
3
+ module Border
4
+ def box(ns: 0, we: 0)
5
+ super ns.ord, we.ord
6
+ end
7
+
8
+ def border(n: 0, ne: 0, e: 0, se: 0, s: 0, sw: 0, w: 0, nw: 0)
9
+ borders = [w, e, n, s, nw, ne, sw, se].map(&:ord)
10
+ super *borders
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ module Curtis
2
+ module Helpers
3
+ module Text
4
+ def puts(text, h: nil, v: nil)
5
+ vertical = case v
6
+ when :top then 0
7
+ when :center then size.lines / 2
8
+ when :bottom then size.lines - 1
9
+ else cursor.line
10
+ end
11
+
12
+ horizontal = case h
13
+ when :left then 0
14
+ when :center then (size.columns - text.size) / 2
15
+ when :right then size.columns - text.size
16
+ else cursor.column
17
+ end
18
+
19
+ window.mvaddstr vertical, horizontal, text
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,105 @@
1
+ module Curtis
2
+ module Input
3
+
4
+ MAX_CHAR = 255
5
+ ENTER = 13
6
+ ESCAPE = 27
7
+ A_TO_Z = ('a'..'z').to_a.freeze
8
+
9
+ module_function
10
+
11
+ def get
12
+ return translate_key(Ncurses.getch) unless block_given?
13
+
14
+ while key = translate_key(Ncurses.getch)
15
+ yield key
16
+ end
17
+ end
18
+
19
+ # https://github.com/grosser/dispel/blob/master/lib/dispel/keyboard.rb
20
+ def translate_key(key)
21
+ case key
22
+ # Movement
23
+ when Ncurses::KEY_UP then :up
24
+ when Ncurses::KEY_DOWN then :down
25
+ when Ncurses::KEY_RIGHT then :right
26
+ when Ncurses::KEY_LEFT then :left
27
+ when Ncurses::KEY_END then :end
28
+ when Ncurses::KEY_HOME then :home
29
+ when Ncurses::KEY_NPAGE then :page_down
30
+ when Ncurses::KEY_PPAGE then :page_up
31
+
32
+ # Code, Unix, iTerm
33
+ when 337, '^[1;2A', "^[A" then :shift_up
34
+ when 336, '^[1;2B', "^[B" then :shift_down
35
+ when 402, '^[1;2C' then :shift_right
36
+ when 393, '^[1;2D' then :shift_left
37
+ when 558, '^[1;3A' then :alt_up
38
+ when 517, '^[1;3B' then :alt_down
39
+ when 552, '^[1;3C' then :alt_right
40
+ when 537, '^[1;3D' then :alt_left
41
+ when 560, '^[1;5A' then :ctrl_up
42
+ when 519, '^[1;5B' then :ctrl_down
43
+ when 554, '^[1;5C' then :ctrl_right
44
+ when 539, '^[1;5D' then :ctrl_left
45
+ when 561, '^[1;6A' then :ctrl_shift_up
46
+ when 520, '^[1;6B' then :ctrl_shift_down
47
+ when 555, '^[1;6C', "^[C" then :ctrl_shift_right
48
+ when 540, '^[1;6D', "^[D" then :ctrl_shift_left
49
+ when 562, '^[1;7A' then :alt_ctrl_up
50
+ when 521, '^[1;7B' then :alt_ctrl_down
51
+ when 556, '^[1;7C' then :alt_ctrl_right
52
+ when 541, '^[1;7D' then :alt_ctrl_left
53
+ when '^[1;8A' then :alt_ctrl_shift_up
54
+ when '^[1;8B' then :alt_ctrl_shift_down
55
+ when '^[1;8C' then :alt_ctrl_shift_right
56
+ when '^[1;8D' then :alt_ctrl_shift_left
57
+ when '^[1;10A' then :alt_shift_up
58
+ when '^[1;10B' then :alt_shift_down
59
+ when '^[1;10C' then :alt_shift_right
60
+ when '^[1;10D' then :alt_shift_left
61
+ when '^[F' then :shift_end
62
+ when '^[H' then :shift_home
63
+ when '^[1;9F' then :alt_end
64
+ when '^[1;9H' then :alt_home
65
+ when '^[1;10F' then :alt_shift_end
66
+ when '^[1;10H' then :alt_shift_home
67
+ when '^[1;13F' then :alt_ctrl_end
68
+ when '^[1;13H' then :alt_ctrl_home
69
+ when '^[1;14F' then :alt_ctrl_shift_end
70
+ when '^[1;14H' then :alt_ctrl_shift_home
71
+ when 527 then :ctrl_shift_end
72
+ when 532 then :ctrl_shift_home
73
+
74
+ when Ncurses::KEY_IC then :insert
75
+ when Ncurses::KEY_F0..Ncurses::KEY_F30 then :"f#{key - Ncurses::KEY_F0}"
76
+
77
+ # Modify
78
+ when 9 then :tab
79
+ when 353 then :shift_tab
80
+ when ENTER then :enter # shadows Ctrl_m
81
+ when 263, 127 then :backspace
82
+ when '^[3~', Ncurses::KEY_DC then :delete
83
+
84
+ # Misc
85
+ when 0 then :ctrl_space
86
+ when 1..26 then :"ctrl_#{A_TO_Z[key - 1]}"
87
+ when ESCAPE then :escape
88
+ when Ncurses::KEY_RESIZE then :resize
89
+
90
+ else
91
+ if key.is_a? Fixnum
92
+ key > MAX_CHAR ? key : key.chr
93
+ elsif alt_key_code?(key)
94
+ :"alt_#{key[1]}"
95
+ else
96
+ key
97
+ end
98
+ end
99
+ end
100
+
101
+ def alt_key_code?(sequence)
102
+ sequence.size == 2 && sequence.starts_with?('^')
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,3 @@
1
+ module Curtis
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,83 @@
1
+ require 'curtis/base_view'
2
+
3
+ module Curtis
4
+ class View < BaseView
5
+ attr_writer :lines, :line, :columns, :column
6
+
7
+ def initialize(**opts)
8
+ @lines = opts[:lines] || -> { parent.size.lines }
9
+ @columns = opts[:columns] || -> { parent.size.columns }
10
+ @line = opts[:line] || 0
11
+ @column = opts[:column] || 0
12
+
13
+ yield self if block_given?
14
+
15
+ super Ncurses::WINDOW.new(*computed_dimensions, *computed_coordinates)
16
+ end
17
+
18
+ def parent
19
+ @parent ||= self.class.superclass.new(Ncurses.stdscr)
20
+ end
21
+
22
+ def render(every: 0.04)
23
+ clear_thread!
24
+ window.refresh unless block_given?
25
+
26
+ @thread = Thread.new do
27
+ loop do
28
+ yield self
29
+ window.refresh
30
+ sleep every
31
+ end
32
+ end
33
+ end
34
+
35
+ def clear
36
+ clear_thread!
37
+ window.clear
38
+ end
39
+
40
+ def resize(lines: nil, columns: nil)
41
+ @lines = lines if lines
42
+ @columns = columns if columns
43
+ window.resize(*computed_dimensions)
44
+ end
45
+
46
+ def reposition(line: nil, column: nil)
47
+ @line = line if line
48
+ @column = column if column
49
+ window.mvwin(*computed_coordinates)
50
+ end
51
+
52
+ private
53
+
54
+ def dimensions
55
+ [@lines, @columns]
56
+ end
57
+
58
+ def coordinates
59
+ [@line, @column]
60
+ end
61
+
62
+ def computed_dimensions
63
+ dimensions.map do |d|
64
+ d.respond_to?(:call) ? d.call : d
65
+ end
66
+ end
67
+
68
+ def computed_coordinates
69
+ coordinates.map do |d|
70
+ d.respond_to?(:call) ? d.call : d
71
+ end
72
+ end
73
+
74
+ def clear_thread!
75
+ @thread.terminate if running_thread?
76
+ @thread = nil unless @thread.nil?
77
+ end
78
+
79
+ def running_thread?
80
+ !@thread.nil? && @thread.alive?
81
+ end
82
+ end
83
+ end
data/lib/curtis.rb ADDED
@@ -0,0 +1,58 @@
1
+ require 'ncurses'
2
+
3
+ require 'curtis/version'
4
+ require 'curtis/base_view'
5
+ require 'curtis/view'
6
+ require 'curtis/input'
7
+
8
+ module Curtis
9
+ class << self
10
+ def config
11
+ @config ||= Configuration.new
12
+ yield @config if block_given?
13
+ @config
14
+ end
15
+ alias_method :configure, :config
16
+
17
+ def show
18
+ initialize_ncurses
19
+ yield screen
20
+ ensure
21
+ close_ncurses
22
+ end
23
+
24
+ def screen
25
+ @screen ||= BaseView.new(Ncurses.stdscr)
26
+ end
27
+
28
+ private
29
+
30
+ def initialize_ncurses
31
+ Ncurses.initscr
32
+
33
+ if config.interactive
34
+ Ncurses.stdscr.keypad(true)
35
+ Ncurses.cbreak
36
+ Ncurses.nonl
37
+ Ncurses.noecho
38
+ end
39
+
40
+ Ncurses.curs_set(0) if config.hide_cursor
41
+ Ncurses.stdscr.refresh
42
+ end
43
+
44
+ def close_ncurses
45
+ Ncurses.endwin
46
+ end
47
+ end
48
+
49
+ class Configuration
50
+ attr_accessor :interactive
51
+ attr_accessor :hide_cursor
52
+
53
+ def initialize
54
+ @interactive = true
55
+ @hide_cursor = true
56
+ end
57
+ end
58
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: curtis
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Stefan Rotariu
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-01-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ncurses-ruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.2.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.2.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.11'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.11'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ description:
70
+ email:
71
+ - stefan.rotariu@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".travis.yml"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bin/console
83
+ - bin/setup
84
+ - curtis.gemspec
85
+ - examples/basic.rb
86
+ - examples/resize.rb
87
+ - examples/steps.rb
88
+ - lib/curtis.rb
89
+ - lib/curtis/base_view.rb
90
+ - lib/curtis/base_view/all.rb
91
+ - lib/curtis/base_view/cursor.rb
92
+ - lib/curtis/base_view/position.rb
93
+ - lib/curtis/base_view/size.rb
94
+ - lib/curtis/helpers/all.rb
95
+ - lib/curtis/helpers/border.rb
96
+ - lib/curtis/helpers/text.rb
97
+ - lib/curtis/input.rb
98
+ - lib/curtis/version.rb
99
+ - lib/curtis/view.rb
100
+ homepage: https://github.com/shuriu/curtis
101
+ licenses:
102
+ - MIT
103
+ metadata: {}
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 2.5.1
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: Extremely light wrapper around ncurses-ruby.
124
+ test_files: []