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,102 +0,0 @@
1
- # taken from https://github.com/pazdera/word_wrap/blob/master/lib/word_wrap/wrapper.rb
2
- #
3
- # Copyright (c) 2014, 2015 Radek Pazdera
4
- # Distributed under the MIT License
5
- #
6
- # TODO: Refactor similar passages out of the two functions into a common one
7
- class Wrapper
8
- def initialize(text, width)
9
- @text = text
10
- @width = width
11
- end
12
-
13
- def fit
14
- lines = []
15
- next_line = ''
16
- @text.lines do |line|
17
- line.chomp! "\n"
18
- if line.empty?
19
- unless next_line.empty?
20
- lines.push next_line
21
- next_line = ''
22
- end
23
- lines.push ''
24
- end
25
-
26
- words = line.split ' '
27
-
28
- words.each do |word|
29
- word.chomp! "\n"
30
-
31
- if next_line.length + word.length < @width
32
- if !next_line.empty?
33
- next_line << ' ' << word
34
- else
35
- next_line = word
36
- end
37
- else
38
- if word.length >= @width
39
- lines.push next_line unless next_line == ''
40
- lines.push word
41
- next_line = ''
42
- else
43
- lines.push next_line
44
- next_line = word
45
- end
46
- end
47
- end
48
- end
49
-
50
- lines.push next_line
51
- if next_line.length <= 0
52
- lines.join("\n")
53
- else
54
- lines.join("\n") + "\n"
55
- end
56
- end
57
-
58
- def wrap
59
- output = []
60
-
61
- @text.lines do |line|
62
- line.chomp! "\n"
63
- if line.length > @width
64
- new_lines = split_line(line, @width)
65
- while new_lines.length > 1 && new_lines[1].length > @width
66
- output.push new_lines[0]
67
- new_lines = split_line new_lines[1], @width
68
- end
69
- output += new_lines
70
- else
71
- output.push line
72
- end
73
- end
74
- output.map(&:rstrip!)
75
- output.join("\n") + "\n"
76
- end
77
-
78
- def split_line(line, width)
79
- at = line.index(/\s/)
80
- last_at = at
81
-
82
- while !at.nil? && at < width
83
- last_at = at
84
- at = line.index(/\s/, last_at + 1)
85
- end
86
-
87
- if last_at.nil?
88
- [line]
89
- else
90
- [line[0, last_at], line[last_at + 1, line.length]]
91
- end
92
- end
93
- end
94
-
95
- def wrap_text(text, width)
96
- lines = text.split("\n")
97
- a = lines.map do |line|
98
- w = Wrapper.new(line, width).wrap
99
- w.split("\n")
100
- end
101
- a.flatten
102
- end
@@ -1,33 +0,0 @@
1
- require_relative 'label'
2
-
3
- module TermGui
4
- module Widget
5
- # A button widget. Usage:
6
- # Button.new(text: 'click me', style: {bg: 'blue'}, action: proc {|e| p 'actioned!'})
7
- class Button < Label
8
- def initialize(**args, &block)
9
- super
10
- @name = 'button'
11
- install(:action)
12
- set_attribute(:focusable, true)
13
- end
14
-
15
- def default_style
16
- s = super
17
- s.border = Border.new(fg: '#779966')
18
- s.bg = '#336688'
19
- s.fg = '#111111'
20
- s.focus&.fg = 'red'
21
- s.focus.bold = true
22
- s.focus.underline = true
23
- s.focus&.bg = 'grey'
24
- s.focus&.border = Border.new(fg: 'green')
25
- s.action&.bg = 'red'
26
- s.action&.border = Border.new(fg: 'magenta', bold: true, bg: 'white')
27
- s
28
- end
29
- end
30
- end
31
- end
32
-
33
- Button = TermGui::Widget::Button
@@ -1,47 +0,0 @@
1
- require_relative 'button'
2
- require_relative '../log'
3
- require_relative '../util'
4
- require_relative '../screen'
5
-
6
- module TermGui
7
- module Widget
8
- # Similar to HTMLInputElement type="checkbox"
9
- class CheckBox < Button
10
- def initialize(**args)
11
- super
12
- @name = 'checkbox'
13
- set_attribute('action-keys', %w[enter space])
14
- set_attribute('label', text || get_attribute('label') || unique('Option'))
15
- update_text get_attribute('value') || get_attribute('checked') || args[:value] || args[:checked] || false
16
- on(:action) do |e|
17
- update_text !get_attribute('value')
18
- render
19
- trigger(:input, TermGui::InputEvent.new(self, value, e))
20
- trigger(:change, TermGui::ChangeEvent.new(self, value, e))
21
- end
22
- end
23
-
24
- def value
25
- get_attribute('value')
26
- end
27
-
28
- def value=(v)
29
- update_text v
30
- end
31
-
32
- def update_text(v = nil)
33
- set_attribute('value', v) unless v == nil
34
- self.text = "#{get_attribute('value') ? '[x]' : '[ ]'} #{get_attribute('label')}"
35
- end
36
-
37
- def default_style
38
- s = super
39
- s.border = nil
40
- s.action = nil
41
- s
42
- end
43
- end
44
- end
45
- end
46
-
47
- CheckBox = TermGui::Widget::CheckBox
@@ -1,30 +0,0 @@
1
- require_relative '../element'
2
- module TermGui
3
- module Widget
4
- # Column container. A column child is rendered at the bottom of the previous child - all of them in one column.
5
- # By default it will have height==0.999
6
- class Col < Element
7
- attr_accessor :gap
8
- def initialize(**args)
9
- # p(({height: 0.99999}.merge(args))[:height])
10
- super({ height: 0.9999999 }.merge(args))
11
- # p height, abs_height
12
- @name = 'col'
13
- @gap = args[:gap]||0
14
- end
15
-
16
- def layout
17
- # init_y = abs_content_y
18
- last_y = abs_content_y
19
- @children.each do |c|
20
- # last_y += 1 if c.style.border
21
- c.abs_y = last_y
22
- last_y += c.abs_height + @gap
23
- # last_y += 1 if c.style.border
24
- end
25
- end
26
- end
27
- end
28
- end
29
-
30
- Col = TermGui::Widget::Col
@@ -1,106 +0,0 @@
1
- require_relative '../termgui'
2
-
3
- module TermGui
4
- module Widget
5
- # analog to HTMLImageElement. Note that the image will be loaded only on render. Also it will be resized according to abs_content
6
- # Properties:
7
- # src: file path or TermGui::Image ot load
8
- # transparent_color color to blend transparent pixels, by default style.bg
9
- # ignore_alpha. if true alpha channel is ignored (could be faster)
10
- # use_bg (true by default) will paint pixels using style.bg
11
- # use_fg (false by default) will paint using style.fg
12
- class Image < Element
13
- attr_accessor :pan_x, :pan_y, :zoom
14
- def initialize(**args)
15
- super
16
- @name = 'image'
17
- @src = args[:src]
18
- @use_bg = args[:use_bg] == nil ? true : args[:use_bg]
19
- @use_fg = args[:use_fg] == nil ? false : args[:use_fg]
20
- @transparent_color = args[:transparent_color]
21
- @ignore_alpha = args[:ignore_alpha]
22
- @zoom = args[:zoom] || 1.0
23
- @pan_x = args[:pan_x] || 0.0
24
- @pan_y = args[:pan_y] || 0.0
25
- @chs = args[:chs] || [get_attribute('ch') || ' ']
26
- @x_factor = args[:x_factor] || 2.0 # to improve non squared terminal "pixels"
27
- @y_factor = args[:y_factor] || 1.2
28
- end
29
-
30
- def image
31
- if !@image && @src
32
- @image = @src.is_a?(String) ? TermGui::Image.new(@src) : @src
33
- end
34
- factor = (@image.width * 2.0 - abs_content_width) < (@image.height - abs_content_height) ?
35
- @zoom * @x_factor * @image.width.to_f / abs_content_width.to_f :
36
- @zoom * @y_factor * @image.height.to_f / abs_content_height.to_f
37
-
38
- @resized_image = @image.scale(
39
- width: (@image.width.to_f * @x_factor / factor).to_i,
40
- height: (@image.height.to_f * @y_factor / factor).to_i
41
- )
42
- # root_screen.text(text: " #{[factor, @image.height, @image.width, @resized_image.width, @resized_image.height, abs_content_width,abs_content_height, abs_content_x, abs_content_y]}", y: 3, x: 55)
43
- if @pan_x + @pan_y > 0
44
- @resized_image = @resized_image.crop(
45
- x: (@resized_image.width.to_f * @pan_x).to_i,
46
- y: (@resized_image.height.to_f * @pan_y).to_i,
47
- width: (@resized_image.width.to_f - @resized_image.width.to_f * @pan_x).to_i,
48
- height: (@resized_image.height.to_f - @resized_image.height.to_f * @pan_y).to_i
49
- )
50
- end
51
- @image
52
- end
53
-
54
- def chs=(v)
55
- if @chs.join != v.join
56
- @chs = v
57
- self.dirty = true
58
- end
59
- end
60
-
61
- def original_image
62
- @image
63
- end
64
-
65
- def current_image
66
- @resized_image
67
- end
68
-
69
- def render_self(screen)
70
- [
71
- super,
72
- image ? screen.image(
73
- x: abs_content_x,
74
- y: abs_content_y,
75
- w: abs_content_width,
76
- h: abs_content_height,
77
- transparent_color: !@ignore_alpha ? TermGui.to_rgb(@transparent_color || final_style.bg || '#000000') : nil,
78
- image: @resized_image,
79
- bg: @use_bg,
80
- fg: @use_fg,
81
- style: final_style,
82
- ch: @chs
83
- ) : ''
84
- ].join('')
85
- end
86
-
87
- def src=(v)
88
- @src = v
89
- @image = nil
90
- refresh
91
- end
92
-
93
- def refresh(force_render = false)
94
- @resized_image = nil
95
- image
96
- if force_render
97
- self.dirty = true
98
- clear
99
- render
100
- end
101
- end
102
- end
103
- end
104
- end
105
-
106
- Image = TermGui::Widget::Image
@@ -1,40 +0,0 @@
1
- require_relative '../element'
2
- module TermGui
3
- module Widget
4
- # an inline layout - similar to HTML display: inline - so I can add arbitrary elements.
5
- # it will break when there is no more space and resize itself.
6
- # TODO: almost there...
7
- class Inline < Element
8
- attr_accessor :horizontal_gap, :vertical_gap
9
- def initialize(**args)
10
- super({ width: 0.9999999 }.merge(args))
11
- @name = 'inline'
12
- @horizontal_gap = args[:horizontal_gap]||0
13
- @vertical_gap = args[:vertical_gap]||0
14
- end
15
-
16
- def layout
17
- last_y = abs_content_y
18
- row_max_height = 1+ @vertical_gap
19
- last_x = abs_content_x
20
- total_height=0
21
- @children.each do |c|
22
- c.abs_x = last_x
23
- c.abs_y = last_y
24
- row_max_height = [row_max_height, c.abs_height].max
25
- last_x += c.abs_width + @horizontal_gap
26
- if last_x + @horizontal_gap+c.abs_width > abs_content_y + abs_content_width
27
- last_x = abs_content_x
28
- last_y += row_max_height + @vertical_gap
29
- total_height+=row_max_height+@vertical_gap
30
- row_max_height = 1+ @vertical_gap
31
- end
32
- end
33
- self.height = [total_height + abs_padding.top + abs_padding.bottom + row_max_height, self.abs_height].max ##TODO borders
34
- end
35
- end
36
- end
37
- end
38
-
39
- Inline = TermGui::Widget::Inline
40
-
@@ -1,73 +0,0 @@
1
- require_relative 'button'
2
- require_relative '../enterable'
3
- require_relative '../util'
4
- require_relative '../screen'
5
-
6
- module TermGui
7
- module Widget
8
- # analog to HTMLInputElement type="number"
9
- class InputNumber < Button
10
- include Enterable
11
- def initialize(**args)
12
- super
13
- @name = 'input-number'
14
- set_attribute('escape-on-blur', get_attribute('escape-on-blur') == nil ? true : get_attribute('escape-on-blur'))
15
- set_attribute('action-on-focus', get_attribute('action-on-focus') == nil ? true : get_attribute('action-on-focus'))
16
- end
17
-
18
- def value
19
- v = parse_float(text)
20
- v == nil ? v : (v.to_i - v == 0 ? v.to_i : v)
21
- end
22
-
23
- def value=(v)
24
- self.text = v.to_s
25
- end
26
-
27
- def handle_key(event)
28
- if !super(event)
29
- if event.key == 'up'
30
- on_input value + 1, event
31
- true
32
- elsif event.key == 'down'
33
- on_input value - 1, event
34
- true
35
- elsif numeric? event.key
36
- self.text = text + event.key
37
- if parse_float(text) == nil
38
- render
39
- else
40
- on_input value, event
41
- end
42
- true
43
- elsif event.key == 'backspace'
44
- self.text = text.slice(0, [text.length - 1, 0].max)
45
- if parse_float(text) == nil
46
- render
47
- else
48
- on_input value, event
49
- end
50
- true
51
- end
52
- else
53
- true
54
- end
55
- end
56
- end
57
- end
58
- end
59
-
60
- InputNumber = TermGui::Widget::InputNumber
61
-
62
- # # p parse_float('9.')
63
-
64
- # sb = nil
65
- # s = Screen.new(children: [
66
- # Button.new(text: 'hello', x: 0.7, y: 0.6, action: proc { |e|
67
- # e.target.text = sb.value.to_s
68
- # e.target.render
69
- # }),
70
- # (sb = InputNumber.new(x: 2, y: 1, width: 0.5, height: 0.5, value: 12))
71
- # ])
72
-
73
- # s.start
@@ -1,85 +0,0 @@
1
- require_relative 'button'
2
- require_relative '../enterable'
3
- require_relative '../log'
4
- require_relative '../cursor'
5
-
6
- module TermGui
7
- module Widget
8
- # One line text input box, analog to HTMLInputElement
9
- class InputBox < Button
10
- include Enterable
11
- def initialize(**args)
12
- super({height: 1, text: args[:value]||args[:text] }.merge(args))
13
- # super
14
- @name = 'input'
15
- if args[:dynamic_width]
16
- on(:input) do |e|
17
- update_width(e.value)
18
- cursor.x = abs_content_x + e.value.length - 2
19
- end
20
- end
21
- # set_attribute('escape-on-blur', get_attribute('escape-on-blur') == nil ? true : get_attribute('escape-on-blur'))
22
- # set_attribute('action-on-focus', get_attribute('action-on-focus') == nil ? true : get_attribute('action-on-focus'))
23
- on(:enter) do
24
- cursor.enable
25
- end
26
- on(:escape) do
27
- cursor.disable
28
- args[:change]&.call(value)
29
- end
30
- end
31
-
32
- def cursor
33
- @cursor ||= Cursor.new(x: abs_content_x + value.length - 2, y: abs_content_y, enabled: false, screen: root_screen)
34
- @cursor
35
- end
36
-
37
- def value=(value)
38
- @text = value
39
- end
40
-
41
- def value
42
- text
43
- end
44
-
45
- def between(v, min, max)
46
- [[v, min].max, max].min
47
- end
48
-
49
- def current_x
50
- cursor.x - abs_content_x
51
- end
52
-
53
- def handle_key(event)
54
- if !super(event)
55
- if event.key == 'backspace'
56
- on_input value[0..between(current_x - 1, 0, value.length - 1)] + value[between(current_x + 1, 0, value.length - 1)..(value.length - 1)], event
57
- cursor.x = [cursor.x - 1, abs_content_x - 1].max
58
- render
59
- true
60
- elsif alphanumeric? event.key
61
- on_input value[0..between(current_x, 0, value.length - 1)] + event.key + value[between(current_x + 1, 0, value.length - 1)..(value.length - 1)], event
62
- cursor.x = cursor.x + 1
63
- render
64
- true
65
- elsif ['right'].include? event.key
66
- cursor.x = [cursor.x + 1, abs_content_x + value.length - 1].min
67
- render
68
- true
69
- elsif ['left'].include? event.key
70
- cursor.x = [cursor.x - 1, abs_content_x - 1].max
71
- render
72
- true
73
- else
74
- false
75
- end
76
- else
77
- true
78
- end
79
- end
80
- end
81
- end
82
- end
83
-
84
- InputBox = TermGui::Widget::InputBox
85
-