termgui 0.0.4 → 0.0.5

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.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/lib/termgui.rb +1 -1
  3. metadata +40 -107
  4. data/Gemfile +0 -14
  5. data/README.md +0 -321
  6. data/src/action.rb +0 -58
  7. data/src/box.rb +0 -90
  8. data/src/color.rb +0 -174
  9. data/src/cursor.rb +0 -69
  10. data/src/editor/editor_base.rb +0 -152
  11. data/src/editor/editor_base_handlers.rb +0 -116
  12. data/src/element.rb +0 -61
  13. data/src/element_bounds.rb +0 -111
  14. data/src/element_box.rb +0 -64
  15. data/src/element_render.rb +0 -102
  16. data/src/element_style.rb +0 -51
  17. data/src/emitter.rb +0 -102
  18. data/src/emitter_state.rb +0 -19
  19. data/src/enterable.rb +0 -93
  20. data/src/event.rb +0 -92
  21. data/src/focus.rb +0 -102
  22. data/src/geometry.rb +0 -53
  23. data/src/image.rb +0 -60
  24. data/src/input.rb +0 -85
  25. data/src/input_grab.rb +0 -17
  26. data/src/input_time.rb +0 -97
  27. data/src/key.rb +0 -114
  28. data/src/log.rb +0 -24
  29. data/src/node.rb +0 -117
  30. data/src/node_attributes.rb +0 -27
  31. data/src/node_visit.rb +0 -52
  32. data/src/renderer.rb +0 -119
  33. data/src/renderer_cursor.rb +0 -18
  34. data/src/renderer_draw.rb +0 -28
  35. data/src/renderer_image.rb +0 -31
  36. data/src/renderer_print.rb +0 -40
  37. data/src/screen.rb +0 -96
  38. data/src/screen_element.rb +0 -59
  39. data/src/screen_input.rb +0 -43
  40. data/src/screen_renderer.rb +0 -53
  41. data/src/style.rb +0 -149
  42. data/src/tco/colouring.rb +0 -248
  43. data/src/tco/config.rb +0 -57
  44. data/src/tco/palette.rb +0 -603
  45. data/src/tco/tco_termgui.rb +0 -30
  46. data/src/termgui.rb +0 -29
  47. data/src/util.rb +0 -110
  48. data/src/util/css.rb +0 -98
  49. data/src/util/css_query.rb +0 -23
  50. data/src/util/easing.rb +0 -364
  51. data/src/util/hash_object.rb +0 -131
  52. data/src/util/imagemagick.rb +0 -27
  53. data/src/util/justify.rb +0 -20
  54. data/src/util/unicode-categories.rb +0 -572
  55. data/src/util/wrap.rb +0 -102
  56. data/src/widget/button.rb +0 -33
  57. data/src/widget/checkbox.rb +0 -47
  58. data/src/widget/col.rb +0 -30
  59. data/src/widget/image.rb +0 -106
  60. data/src/widget/inline.rb +0 -40
  61. data/src/widget/input_number.rb +0 -73
  62. data/src/widget/inputbox.rb +0 -85
  63. data/src/widget/label.rb +0 -33
  64. data/src/widget/modal.rb +0 -69
  65. data/src/widget/row.rb +0 -26
  66. data/src/widget/selectbox.rb +0 -100
  67. data/src/widget/textarea.rb +0 -54
  68. data/src/xml/xml.rb +0 -80
  69. data/test/action_test.rb +0 -34
  70. data/test/box_test.rb +0 -15
  71. data/test/css_test.rb +0 -39
  72. data/test/editor/editor_base_test.rb +0 -201
  73. data/test/element_bounds_test.rb +0 -77
  74. data/test/element_box_test.rb +0 -8
  75. data/test/element_render_test.rb +0 -124
  76. data/test/element_style_test.rb +0 -85
  77. data/test/element_test.rb +0 -10
  78. data/test/emitter_test.rb +0 -108
  79. data/test/event_test.rb +0 -19
  80. data/test/focus_test.rb +0 -37
  81. data/test/geometry_test.rb +0 -12
  82. data/test/input_test.rb +0 -47
  83. data/test/key_test.rb +0 -14
  84. data/test/log_test.rb +0 -21
  85. data/test/node_test.rb +0 -105
  86. data/test/performance/performance1.rb +0 -48
  87. data/test/renderer_test.rb +0 -74
  88. data/test/renderer_test_rect.rb +0 -4
  89. data/test/screen_test.rb +0 -58
  90. data/test/style_test.rb +0 -18
  91. data/test/termgui_test.rb +0 -10
  92. data/test/test_all.rb +0 -30
  93. data/test/util_hash_object_test.rb +0 -93
  94. data/test/util_test.rb +0 -26
  95. data/test/widget/checkbox_test.rb +0 -99
  96. data/test/widget/col_test.rb +0 -87
  97. data/test/widget/inline_test.rb +0 -40
  98. data/test/widget/label_test.rb +0 -94
  99. data/test/widget/row_test.rb +0 -40
  100. data/test/wrap_test.rb +0 -11
  101. data/test/xml_test.rb +0 -77
@@ -1,33 +0,0 @@
1
- require_relative '../element'
2
- module TermGui
3
- module Widget
4
- # A label widget. It's size, if not given, will be computed according to its text.
5
- class Label < Element
6
- def initialize(**args)
7
- super
8
- @name = 'label'
9
- # sets width and height according to size rendering:
10
- w = args[:width] || 0
11
- update_width if !w || w.zero?
12
- h = args[:height] || 0
13
- update_height if !h || h.zero?
14
- end
15
-
16
- def text=(t)
17
- super
18
- update_width
19
- update_height
20
- end
21
-
22
- def update_width(text = @text)
23
- self.width = render_text_size(text)[:width]
24
- end
25
-
26
- def update_height(text = @text)
27
- self.height = render_text_size(text)[:height]
28
- end
29
- end
30
- end
31
- end
32
-
33
- Label = TermGui::Widget::Label
@@ -1,69 +0,0 @@
1
- # temporary modal window solution.
2
- # TODO: reimplement this using actual screen children elements and remove it for closing
3
-
4
- require_relative '../screen'
5
- require_relative '../util'
6
- require_relative '../element'
7
- require_relative '../style'
8
- require_relative '../log'
9
- require_relative '../widget/button'
10
- require_relative '../widget/col'
11
- require_relative '../widget/label'
12
-
13
- def open_modal(
14
- screen: nil,
15
- title: Label.new(text: 'Modal'),
16
- content: Label.new(text: 'Content'),
17
- on_close: nil
18
- )
19
- modal = screen.query_one_by_attribute('modal-widget', true)
20
- return if modal
21
-
22
- screen.set_timeout(0.3) do
23
- focused = screen.focus.focused
24
- focusables = screen.focus.focusables
25
- focusables.each { |e| e.set_attribute('focusable', false) }
26
- title = title.is_a?(String) ? Label.new(text: title, style: { bold: true, fg: '#001119', underline: true }, x: 1, y: 1) : title
27
- content = content.is_a?(String) ? Label.new(text: content, style: { wrap: true, fg: '#77aa33' }, x: 1, y: 3, height: 0.8, width: 0.9) : content
28
- close = Button.new(text: 'close', y: 1, x: 0.9, action: proc {
29
- modal.remove
30
- screen.clear
31
- screen.render
32
- on_close&.call
33
- focusables.each { |e| e.set_attribute('focusable', true) }
34
- focused&.focus
35
- })
36
- modal = screen.append_child Element.new(
37
- x: 0.2, y: 0.1,
38
- height: 0.9,
39
- width: 0.6,
40
- attributes: { 'modal-widget': true },
41
- padding: Bounds.new(top: 1, left: 2),
42
- style: { bg: 'white', fg: 'blue', wrap: true, border: Border.new(bg: 'red', style: 'double') },
43
- children: [
44
- title,
45
- close,
46
- content
47
- ]
48
- )
49
- close.focus
50
- modal.render
51
- end
52
- end
53
-
54
- def clode_modal(screen)
55
- modals = screen.query_by_attribute('modal-widget', true)
56
- # return unless modals.length>0
57
- modals.each{|modal|modal.remove}
58
- screen.render if modals.length>0
59
- end
60
-
61
- module TermGui
62
- module Widget
63
- class Modal
64
- def self.open(**args)
65
- open_modal(args)
66
- end
67
- end
68
- end
69
- end
@@ -1,26 +0,0 @@
1
- require_relative '../element'
2
- module TermGui
3
- module Widget
4
- # Row container. A row child is rendered at the right of the previous child - all of them in one row.
5
- # By default it will have width==0.999
6
- class Row < Element
7
- attr_accessor :gap
8
- def initialize(**args)
9
- super({ width: 0.9999999 }.merge(args))
10
- @name = 'row'
11
- @gap = args[:gap]||0
12
- end
13
-
14
- def layout
15
- # init_x = abs_content_x
16
- last_x = abs_content_x
17
- @children.each do |c|
18
- c.abs_x = last_x
19
- last_x += c.abs_width + @gap
20
- end
21
- end
22
- end
23
- end
24
- end
25
-
26
- Row = TermGui::Widget::Row
@@ -1,100 +0,0 @@
1
- require_relative 'button'
2
- require_relative '../enterable'
3
- require_relative '../log'
4
- require_relative 'checkbox'
5
-
6
- module TermGui
7
- module Widget
8
- class SelectOption < CheckBox
9
- def initialize(**args)
10
- super
11
- @name = 'select-option'
12
- set_attribute('focusable', false)
13
- end
14
- # def default_style
15
- # Style.new(fg: 'white', bg: 'yellow')
16
- # end
17
- end
18
-
19
- # One line text input box, analog to HTMLInputElement
20
- class SelectBox < Button
21
- include Enterable
22
- def initialize(**args)
23
- super
24
- @name = 'select'
25
- set_attribute('escape-on-blur', get_attribute('escape-on-blur') == nil ? true : get_attribute('escape-on-blur'))
26
- set_attribute('action-on-focus', get_attribute('action-on-focus') == nil ? true : get_attribute('action-on-focus'))
27
- @options = (args[:options] || [])
28
- @option_elements = @options.map.with_index do |o, i|
29
- SelectOption.new(
30
- text: o[:text] || o[:value],
31
- value: o[:selected] || false,
32
- parent: self,
33
- y: i + 1,
34
- x: 0
35
- )
36
- end
37
- render_options 0
38
- end
39
-
40
- def render_options(c = nil)
41
- @current = c unless c == nil
42
- @option_elements.each_with_index do |e, i|
43
- e.style.bg = 'red' if i == @current
44
- e.style.bg = 'black' if i != @current
45
- e.render
46
- end
47
- end
48
-
49
- def value
50
- @option_elements.map.with_index { |e, i| e.value ? @options[i][:value] : nil }.reject { |v| v == nil }
51
- end
52
-
53
- def value=(v)
54
- # todo
55
- # throw 'todo'
56
- end
57
- def handle_key(event)
58
- if !super(event)
59
- if event.key == 'up'
60
- render_options [@current - 1, 0].max
61
- true
62
- elsif event.key == 'down'
63
- render_options [@current + 1, @option_elements.length - 1].min
64
- true
65
- elsif ['space'].include? event.key
66
- @option_elements[@current].value = !@option_elements[@current].value
67
- on_input value, event
68
- true
69
- else
70
- false
71
- end
72
- else
73
- true
74
- end
75
- end
76
- end
77
- end
78
- end
79
-
80
- SelectBox = TermGui::Widget::SelectBox
81
-
82
- # sb=nil
83
- # s = Screen.new(children: [
84
- # Button.new(text: 'hello', x: 0.7, y: 0.6, action: proc {|e|
85
- # e.target.text = sb.value.join(', ')
86
- # e.target.render
87
- # }),
88
- # (sb = SelectBox.new(x: 2, y: 1, width: 0.5, height: 0.5, options:
89
- # [
90
- # {
91
- # text: '1', value: 1, selected: true
92
- # }, {
93
- # text: '2', value: 2
94
- # }, {
95
- # text: '3', value: 3
96
- # }
97
- # ]))
98
- # ])
99
-
100
- # s.start
@@ -1,54 +0,0 @@
1
- # require_relative 'button'
2
- # require_relative '../event'
3
-
4
- # module TermGui
5
- # module Widget
6
- # # One line text input box, analog to HTMLInputElement
7
- # class TextArea < Button
8
- # attr_accessor :value
9
-
10
- # def initialize(**args)
11
- # super
12
- # @value = args[:value] || ''
13
- # @key_listener = nil
14
- # install(:input)
15
- # install(:change)
16
- # install(:escape)
17
- # on(:action) do
18
- # @key_listener = proc { |e| on_key e }
19
- # root_screen.event.add_any_key_listener @key_listener
20
- # on('change', args[:change]) if args[:change]
21
- # on('input', args[:input]) if args[:input]
22
- # on('escape', args[:escape]) if args[:escape]
23
- # end
24
- # end
25
-
26
- # def on_key(event)
27
- # if !get_attribute('focused')
28
- # trigger('change', ChangeEvent.new(self, @value, event))
29
- # root_screen.event.remove_any_key_listener @key_listener
30
- # elsif event.key == 'escape'
31
- # trigger('escape', EscapeEvent.new(self, event))
32
- # root_screen.event.remove_any_key_listener @key_listener
33
- # elsif event.key == 'backspace'
34
- # on_input @value.slice(0, @value.length - 1), event
35
- # elsif alphanumeric? event.key
36
- # on_input @value + event.key, event
37
- # end
38
- # end
39
-
40
- # protected
41
-
42
- # def on_input(value, event = nil)
43
- # @value = value
44
- # self.text = @value
45
- # update_width
46
- # root_screen.clear
47
- # root_screen.render
48
- # trigger('input', ChangeEvent.new(self, @value, event))
49
- # end
50
- # end
51
- # end
52
- # end
53
-
54
- # InputBox = TermGui::Widget::InputBox
@@ -1,80 +0,0 @@
1
- require 'rexml/document'
2
- require 'erb'
3
- require_relative '../element'
4
- require_relative '../screen'
5
- require_relative '../log'
6
- require_relative '../util'
7
- require_relative '../style'
8
- require_relative '../widget/col'
9
- require_relative '../widget/button'
10
- require_relative '../widget/label'
11
-
12
- def process_attrs(e, b, attrs = default_attrs)
13
- a = {}
14
- e.attributes.each_attribute do |attr|
15
- value = attr.value
16
- name = attr.expanded_name
17
- if attrs[:number].include? name
18
- a[name.to_sym] = is_percent(value.to_f) ? value.to_f : value.to_i
19
- elsif attrs[:code].include? name
20
- a[name.to_sym] = eval(value, b)
21
- elsif name == 'style'
22
- a[name.to_sym] = Style.from_hash(eval(value))
23
- else
24
- a[name.to_sym] = value
25
- end
26
- end
27
- a
28
- end
29
-
30
- def percent_bounds_hack(result, parent)
31
- result.set_attribute('xml', true)
32
- if parent && !parent.get_attribute('xml')
33
- result.set_attribute('x', 0)
34
- result.set_attribute('y', 0)
35
- result.set_attribute('width', parent.width)
36
- result.set_attribute('height', parent.height)
37
- end
38
- end
39
-
40
- def process_node(node, parent = nil, bindings = nil, builders = default_builders, attrs = default_attrs)
41
- if node.is_a?(REXML::Text)
42
- parent.text += node.to_s.strip if parent
43
- else
44
- c = (builders[node.name.to_sym] || Element)
45
- a = process_attrs(node, bindings, attrs).merge(parent: parent)
46
- result = c.new(a.merge(builders[node.name.to_sym] ? {} : { name: node.name }))
47
- percent_bounds_hack(result, parent)
48
- node.each do |e|
49
- c = process_node(e, result, bindings, builders, attrs)
50
- end
51
- end
52
- result
53
- end
54
-
55
- def default_attrs
56
- {
57
- number: %w[width height x y],
58
- code: ['action']
59
- }
60
- end
61
-
62
- def default_builders
63
- {
64
- col: Col,
65
- button: Button,
66
- label: Label
67
- }
68
- end
69
-
70
- def render_xml(xml: nil, parent: nil, binding: nil, custom_builders: {}, custom_attrs: {})
71
- builders = default_builders.merge(custom_builders)
72
- attrs = default_attrs.merge(custom_attrs)
73
- doc = REXML::Document.new xml
74
- process_node(doc, parent, binding, builders, attrs)
75
- end
76
-
77
- def render_erb(template: nil, parent: nil, binding: nil, erb_binding: binding, custom_builders: {}, custom_attrs: {})
78
- xml = ERB.new(template).result(erb_binding).strip
79
- render_xml(xml: xml, parent: parent, binding: binding, custom_builders: custom_builders, custom_attrs: custom_attrs)
80
- end
@@ -1,34 +0,0 @@
1
- require 'test/unit'
2
- include Test::Unit::Assertions
3
- require_relative '../src/element'
4
- require_relative '../src/screen'
5
- require_relative '../src/log'
6
-
7
- class ActionTest < Test::Unit::TestCase
8
- def test_global_action
9
- screen = Screen.new_for_testing width: 5, height: 6
10
- s = ''
11
- global = ''
12
- e1 = screen.append_child Element.new(text: '1', attributes: { focusable: true })
13
- screen.append_child Element.new(text: '2', attributes: { focusable: true, action: proc { |_e| s = 'e2' } })
14
- e1.set_attribute('action', proc { s = 'e1' })
15
- screen.action.on('action') do |e|
16
- global = 'e' + e.target.text
17
- end
18
- screen.input.emit_key 'enter'
19
- assert_equal '', s
20
- assert_equal '', global
21
- screen.focus.focus_next
22
- assert_equal '', s
23
- assert_equal '', global
24
- screen.input.emit_key 'enter'
25
- assert_equal 'e2', s
26
- assert_equal 'e2', global
27
- screen.focus.focus_next
28
- assert_equal 'e2', s
29
- assert_equal 'e2', global
30
- screen.input.emit_key 'enter'
31
- assert_equal 'e1', s
32
- assert_equal 'e1', global
33
- end
34
- end
@@ -1,15 +0,0 @@
1
- require 'test/unit'
2
- include Test::Unit::Assertions
3
- require_relative '../src/box'
4
-
5
- class BoxTest < Test::Unit::TestCase
6
- def test_simple
7
- b = draw_box(width: 8, height: 3)
8
- assert_equal "box\n#{b.join('\n')}\nbox",
9
- "box\n" \
10
- '┌──────┐\\n' \
11
- '│ │\\n' \
12
- "└──────┘\n" \
13
- 'box'
14
- end
15
- end
@@ -1,39 +0,0 @@
1
- require 'test/unit'
2
- include Test::Unit::Assertions
3
- require_relative '../src/util/css'
4
-
5
- class CssTest < Test::Unit::TestCase
6
- def test_parse_rules
7
- p = CSSParser.new
8
- expected = '[{:selector=>"foo", :body=>"bg: red; padding-top: 3"}, {:selector=>".bar .primary", :body=>"border: double black"}, {:selector=>"; .sidebar .container", :body=>"padding: 1"}]'
9
- actual = p.parse_rules('foo {bg: red; padding-top: 3} .bar .primary {border: double black}; .sidebar .container { padding: 1}').to_s
10
- assert_equal expected, actual
11
- end
12
-
13
- def test_parse_rules_properties
14
- p = CSSParser.new
15
- expected = '[{:selector=>"foo", :properties=>[{:name=>"bg", :value=>"red"}, {:name=>"padding-top", :value=>"3"}]}, {:selector=>".bar .primary", :properties=>[{:name=>"border", :value=>"double black"}]}, {:selector=>"; .sidebar .container", :properties=>[{:name=>"padding", :value=>"1"}]}]'
16
- actual = p.parse_rules_properties(p.parse_rules('foo {bg: red; padding-top: 3} .bar .primary {border: double black}; .sidebar .container { padding: 1}')).to_s
17
- assert_equal expected, actual
18
- end
19
-
20
- def test_parse_rules_selectors
21
- p = CSSParser.new
22
- expected = '[{:selectors=>[[{:name=>"foo", :operator=>nil}]], :properies=>[{:name=>"bg", :value=>"red"}, {:name=>"padding-top", :value=>"3"}]}, {:selectors=>[[{:name=>".bar", :operator=>" "}, {:name=>".primary", :operator=>nil}]], :properies=>[{:name=>"border", :value=>"double black"}]}, {:selectors=>[[{:name=>";", :operator=>" "}, {:name=>".sidebar", :operator=>" "}, {:name=>".container", :operator=>nil}]], :properies=>[{:name=>"padding", :value=>"1"}]}]'
23
- rules = p.parse_rules_properties(p.parse_rules('foo {bg: red; padding-top: 3} .bar .primary {border: double black}; .sidebar .container { padding: 1}'))
24
- actual = p.parse_rules_selectors(rules).to_s
25
- assert_equal expected, actual
26
- end
27
-
28
- def test_parse
29
- p = CSSParser.new
30
- expected = '[{:selectors=>[[{:name=>"foo", :operator=>nil}]], :properies=>[{:name=>"bg", :value=>"red"}, {:name=>"padding-top", :value=>"3"}]}, {:selectors=>[[{:name=>".bar", :operator=>" "}, {:name=>".primary", :operator=>nil}]], :properies=>[{:name=>"border", :value=>"double black"}]}, {:selectors=>[[{:name=>";", :operator=>" "}, {:name=>".sidebar", :operator=>" "}, {:name=>".container", :operator=>nil}]], :properies=>[{:name=>"padding", :value=>"1"}]}]'
31
- actual = p.parse('foo {bg: red; padding-top: 3} .bar .primary {border: double black}; .sidebar .container { padding: 1}').to_s
32
- assert_equal expected, actual
33
- end
34
-
35
- def test_parse_selector
36
- expected = '[{:name=>"a", :operator=>">"}, {:name=>"b", :operator=>" "}, {:name=>"c", :operator=>">"}, {:name=>"d", :operator=>" "}, {:name=>"f", :operator=>nil}]'
37
- assert_equal expected, CSSParser.new.parse_selector('a> b c>d f').to_s
38
- end
39
- end