termkit 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.ackrc +7 -0
  3. data/.editorconfig +14 -0
  4. data/.gitignore +5 -1
  5. data/.gitlab-ci.yml +70 -0
  6. data/.rdoc_options +21 -0
  7. data/.travis.yml +5 -1
  8. data/Gemfile +8 -0
  9. data/Makefile +16 -1
  10. data/Makefile.common +5 -3
  11. data/README.md +2 -1
  12. data/bin/build_info.sh +22 -0
  13. data/bin/dev +10 -0
  14. data/lib/termkit.rb +32 -0
  15. data/lib/termkit/app/app.rb +61 -0
  16. data/lib/termkit/app/app_curses.rb +159 -0
  17. data/lib/termkit/app/app_ui.rb +153 -0
  18. data/lib/termkit/controller/controller.rb +58 -0
  19. data/lib/termkit/controller/controller_app.rb +22 -0
  20. data/lib/termkit/controller/controller_view.rb +28 -0
  21. data/lib/termkit/event/event.rb +14 -0
  22. data/lib/termkit/event/event_key.rb +33 -0
  23. data/lib/termkit/event/event_later.rb +16 -0
  24. data/lib/termkit/exception/exception_event_key_unhandled.rb +11 -0
  25. data/lib/termkit/exception/exception_event_unhandled.rb +18 -0
  26. data/lib/termkit/exception/exception_initialized_not_class_parent.rb +17 -0
  27. data/lib/termkit/exception/exception_std.rb +11 -0
  28. data/lib/termkit/misc/curses_color.rb +23 -0
  29. data/lib/termkit/misc/point.rb +114 -0
  30. data/lib/termkit/misc/rect.rb +116 -0
  31. data/lib/termkit/misc/size.rb +29 -0
  32. data/lib/termkit/model/model.rb +16 -0
  33. data/lib/termkit/version.rb +5 -4
  34. data/lib/termkit/view/content_view.rb +59 -0
  35. data/lib/termkit/view/content_view_clear.rb +20 -0
  36. data/lib/termkit/view/row_grid_view.rb +12 -0
  37. data/lib/termkit/view/view.rb +825 -0
  38. data/lib/termkit/view/view_grid.rb +12 -0
  39. data/lib/termkit/view/view_table.rb +296 -0
  40. data/lib/termkit/view/view_table_cell.rb +38 -0
  41. data/lib/termkit/view/view_text.rb +63 -0
  42. data/termkit.gemspec +8 -0
  43. data/termkit.sublime-project +2 -2
  44. metadata +120 -5
  45. data/tests/ts_all.rb +0 -1
@@ -0,0 +1,153 @@
1
+
2
+ module TheFox
3
+ module TermKit
4
+
5
+ class UIApp < App
6
+
7
+ attr_accessor :app_controller
8
+ attr_accessor :active_controller
9
+
10
+ def initialize
11
+ super()
12
+
13
+ #puts 'UIApp initialize'
14
+
15
+ @render_count = 0
16
+ @app_controller = nil
17
+ @active_controller = nil
18
+
19
+ ui_init
20
+ end
21
+
22
+ ##
23
+ # See App `run_cycle()` method.
24
+ def run_cycle
25
+ super()
26
+
27
+ #puts 'UIApp->run_cycle'
28
+
29
+ render
30
+ end
31
+
32
+ def set_app_controller(app_controller)
33
+ if !app_controller.is_a?(AppController)
34
+ raise ArgumentError, "Argument is not a AppController -- #{app_controller.class} given"
35
+ end
36
+
37
+ @app_controller = app_controller
38
+ end
39
+
40
+ def set_active_controller(active_controller)
41
+ if !active_controller.is_a?(ViewController)
42
+ raise ArgumentError, "Argument is not a ViewController -- #{active_controller.class} given"
43
+ end
44
+
45
+ if !@active_controller.nil?
46
+ @active_controller.inactive
47
+ end
48
+
49
+ @active_controller = active_controller
50
+ @active_controller.active
51
+ end
52
+
53
+ ##
54
+ # Handles the actual rendering and drawing of the UI layer. Calls `draw_point()` for all points of `@active_controller`.
55
+ def render
56
+ #sleep 1 # @TODO: remove this line
57
+
58
+ area = nil # @TODO: use current terminal size as area
59
+
60
+ @render_count += 1
61
+ # @logger.debug("--- RENDER: #{@render_count} ---")
62
+ if !@active_controller.nil?
63
+ # @logger.debug("RENDER active_controller OK: #{@active_controller.inspect}")
64
+ # @logger.debug("RENDER active_controller view grid_cache: #{@active_controller.view.grid_cache.inspect}")
65
+
66
+ @active_controller.render(area).each do |y_pos, row|
67
+ row.each do |x_pos, content|
68
+ #sleep 0.1 # @TODO: remove this line
69
+
70
+ # @logger.debug("RENDER #{x_pos}:#{y_pos} '#{content}'")
71
+
72
+ draw_point(Point.new(x_pos, y_pos), content)
73
+
74
+ #ui_refresh # @TODO: remove this line
75
+ end
76
+ end
77
+ end
78
+ ui_refresh
79
+ end
80
+
81
+ def draw_line(point, row)
82
+ x_pos = point.x
83
+ y_pos = point.y
84
+
85
+ row.length.times do |n|
86
+ draw_point(Point.new(x_pos, y_pos), ViewContent.new(row[n]))
87
+ x_pos += 1
88
+ end
89
+ end
90
+
91
+ ##
92
+ # Needs to be implemented by the sub-class.
93
+ #
94
+ # For example, CursesApp is a sub-class of UIApp. CursesApp uses `Curses.setpos` and `Curses.addstr` in `draw_point()` to draw the points.
95
+ def draw_point(point, content)
96
+ raise NotImplementedError
97
+ end
98
+
99
+ def ui_refresh
100
+ raise NotImplementedError
101
+ end
102
+
103
+ def ui_max_x
104
+ -1
105
+ end
106
+
107
+ def ui_max_y
108
+ -1
109
+ end
110
+
111
+ protected
112
+
113
+ def app_will_terminate
114
+ #puts 'UIApp app_will_terminate'
115
+
116
+ ui_close
117
+ end
118
+
119
+ def ui_init
120
+ # raise NotImplementedError
121
+ end
122
+
123
+ def ui_close
124
+ # raise NotImplementedError
125
+ end
126
+
127
+ def key_down(key)
128
+ if !key.nil? && !@active_controller.nil?
129
+ event = KeyEvent.new
130
+ event.key = key
131
+
132
+ begin
133
+ @active_controller.handle_event(event)
134
+ rescue Exception::UnhandledKeyEventException => e
135
+ @logger.warn("#{self.class} UnhandledKeyEventException: #{e}")
136
+
137
+ if @app_controller.nil?
138
+ @logger.warn("#{self.class} UnhandledKeyEventException: no app controller set, raise")
139
+
140
+ raise e
141
+ end
142
+
143
+ @app_controller.handle_event(e.event)
144
+ rescue Exception::UnhandledEventException => e
145
+ @logger.warn("#{self.class} UnhandledEventException: #{e}")
146
+ end
147
+ end
148
+ end
149
+
150
+ end
151
+
152
+ end
153
+ end
@@ -0,0 +1,58 @@
1
+
2
+ module TheFox
3
+ module TermKit
4
+
5
+ class Controller
6
+
7
+ attr_reader :subcontrollers
8
+
9
+ def initialize
10
+ #puts 'Controller initialize'
11
+
12
+ @is_active = false
13
+ @subcontrollers = []
14
+ end
15
+
16
+ def active
17
+ @is_active = true
18
+
19
+ @subcontrollers.each do |subcontroller|
20
+ subcontroller.active
21
+ end
22
+ end
23
+
24
+ def inactive
25
+ @is_active = false
26
+
27
+ @subcontrollers.each do |subcontroller|
28
+ subcontroller.inactive
29
+ end
30
+ end
31
+
32
+ def is_active?
33
+ @is_active
34
+ end
35
+
36
+ def handle_event(event)
37
+ #puts "Controller handle_event: #{event.class}"
38
+ end
39
+
40
+ def add_subcontroller(subcontroller)
41
+ if !subcontroller.is_a?(Controller)
42
+ raise ArgumentError, "Argument is not a Controller -- #{subcontroller.class} given"
43
+ end
44
+ if !@subcontrollers.is_a?(Array)
45
+ raise Exception::ParentClassNotInitializedException, "@subcontrollers is not an Array -- #{@subcontrollers.class} given"
46
+ end
47
+
48
+ @subcontrollers.push(subcontroller)
49
+ end
50
+
51
+ def remove_subcontroller(subcontroller)
52
+ @subcontrollers.delete(subcontroller)
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,22 @@
1
+
2
+ module TheFox
3
+ module TermKit
4
+
5
+ ##
6
+ # Controller sub-class.
7
+ class AppController < Controller
8
+
9
+ def initialize(app)
10
+ if !app.is_a?(App)
11
+ raise ArgumentError, "Argument is not a App -- #{app.class} given"
12
+ end
13
+
14
+ super()
15
+
16
+ @app = app
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+
2
+ module TheFox
3
+ module TermKit
4
+
5
+ class ViewController < Controller
6
+
7
+ attr_accessor :app
8
+ attr_accessor :view
9
+
10
+ def initialize(view = nil)
11
+ if !view.nil? && !view.is_a?(View)
12
+ raise ArgumentError, "Argument is not a View -- #{view.class} given"
13
+ end
14
+
15
+ super()
16
+
17
+ @app = nil
18
+ @view = view
19
+ end
20
+
21
+ def render(area = nil)
22
+ @view.render(area)
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,14 @@
1
+
2
+ module TheFox
3
+ module TermKit
4
+
5
+ class Event
6
+
7
+ def initialize
8
+ #puts 'Event initialize'
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+
2
+ module TheFox
3
+ module TermKit
4
+
5
+ ##
6
+ # Typically used to handle user keystrokes.
7
+ class KeyEvent
8
+
9
+ attr_accessor :key
10
+
11
+ def initialize
12
+ super()
13
+
14
+ @key = nil
15
+ end
16
+
17
+ def to_s
18
+ @key.to_s
19
+ end
20
+
21
+ def inspect
22
+ s = "#<#{self.class}"
23
+ unless @key.nil?
24
+ s << "->#{@key.ord}[#{@key}]"
25
+ end
26
+ s << '>'
27
+ s
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+
2
+ # Cronjob
3
+
4
+ module TheFox
5
+ module TermKit
6
+
7
+ class LaterEvent
8
+
9
+ def initialize
10
+
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+
2
+ module TheFox
3
+ module TermKit
4
+ module Exception
5
+
6
+ class UnhandledKeyEventException < UnhandledEventException
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+
2
+ module TheFox
3
+ module TermKit
4
+ module Exception
5
+
6
+ class UnhandledEventException < StdException
7
+
8
+ attr_reader :event
9
+
10
+ def initialize(event)
11
+ @event = event
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+
2
+ module TheFox
3
+ module TermKit
4
+ module Exception
5
+
6
+ class ParentClassNotInitializedException < StdException
7
+
8
+ def initialize(msg = nil)
9
+ msg << ' -- Forgot to call super() for parent initialization?'
10
+ super
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+
2
+ module TheFox
3
+ module TermKit
4
+ module Exception
5
+
6
+ class StdException < ::StandardError
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+
2
+ require 'curses'
3
+
4
+ module TheFox
5
+ module TermKit
6
+
7
+ class CursesColor
8
+
9
+ COLORS = {
10
+ :color_black => Curses::COLOR_BLACK,
11
+ :color_blue => Curses::COLOR_BLUE,
12
+ :color_cyan => Curses::COLOR_CYAN,
13
+ :color_green => Curses::COLOR_GREEN,
14
+ :color_magenta => Curses::COLOR_MAGENTA,
15
+ :color_red => Curses::COLOR_RED,
16
+ :color_white => Curses::COLOR_WHITE,
17
+ :color_yellow => Curses::COLOR_YELLOW,
18
+ }
19
+
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,114 @@
1
+
2
+ module TheFox
3
+ module TermKit
4
+
5
+ ##
6
+ # A single point on a x-y-grid.
7
+ class Point
8
+
9
+ attr_accessor :x
10
+ attr_accessor :y
11
+
12
+ def initialize(x = nil, y = nil)
13
+ case x
14
+ when Array
15
+ y = x[1]
16
+ x = x[0]
17
+ when Hash
18
+ y = if x['y']
19
+ x['y']
20
+ elsif x[:y]
21
+ x[:y]
22
+ end
23
+
24
+ x = if x['x']
25
+ x['x']
26
+ elsif x[:x]
27
+ x[:x]
28
+ end
29
+ end
30
+
31
+ @x = x
32
+ @y = y
33
+ end
34
+
35
+ def ==(point)
36
+ # puts "Point == compare"
37
+ @x == point.x && @y == point.y
38
+ end
39
+
40
+ # def ===(point)
41
+ # puts "Point === compare"
42
+ # #@x == point.x && @y == point.y
43
+ # false
44
+ # end
45
+
46
+ # def eql?(point)
47
+ # puts "Point eql? compare"
48
+ # false
49
+ # end
50
+
51
+ def +(point)
52
+ x = nil
53
+ y = nil
54
+
55
+ if !@x.nil? || !point.x.nil?
56
+ x = @x.to_i + point.x.to_i
57
+ end
58
+
59
+ if !@y.nil? || !point.y.nil?
60
+ y = @y.to_i + point.y.to_i
61
+ end
62
+
63
+ self.class.new(x, y)
64
+ end
65
+
66
+ def -(point)
67
+ x = nil
68
+ y = nil
69
+
70
+ if !@x.nil? || !point.x.nil?
71
+ x = @x.to_i - point.x.to_i
72
+ end
73
+
74
+ if !@y.nil? || !point.y.nil?
75
+ y = @y.to_i - point.y.to_i
76
+ end
77
+
78
+ self.class.new(x, y)
79
+ end
80
+
81
+ def to_s
82
+ "#{@x}:#{@y}"
83
+ end
84
+
85
+ def to_a
86
+ [@x, @y]
87
+ end
88
+
89
+ def inspect
90
+ x_s = x.nil? ? 'NIL' : x
91
+ y_s = y.nil? ? 'NIL' : y
92
+
93
+ "#<Point x=#{x_s} y=#{y_s}>"
94
+ end
95
+
96
+ def missing_function
97
+
98
+ end
99
+
100
+ def self.from_s(s)
101
+ x, y =
102
+ s
103
+ .split(/[:,]/, 2)
104
+ .map{ |pos|
105
+ pos.nil? || pos == '' ? nil : pos.to_i
106
+ }
107
+
108
+ new(x, y)
109
+ end
110
+
111
+ end
112
+
113
+ end
114
+ end