whirled_peas 0.3.0 → 0.7.0

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 (221) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +38 -0
  4. data/README.md +549 -85
  5. data/Rakefile +28 -3
  6. data/examples/intro.rb +52 -0
  7. data/examples/scrolling.rb +53 -0
  8. data/exe/whirled_peas +7 -0
  9. data/lib/whirled_peas.rb +12 -36
  10. data/lib/whirled_peas/command_line.rb +255 -0
  11. data/lib/whirled_peas/config.rb +21 -0
  12. data/lib/whirled_peas/errors.rb +7 -0
  13. data/lib/whirled_peas/frame.rb +0 -5
  14. data/lib/whirled_peas/frame/consumer.rb +30 -0
  15. data/lib/whirled_peas/frame/debug_consumer.rb +30 -0
  16. data/lib/whirled_peas/frame/event_loop.rb +69 -38
  17. data/lib/whirled_peas/frame/producer.rb +36 -19
  18. data/lib/whirled_peas/graphics.rb +19 -0
  19. data/lib/whirled_peas/graphics/box_painter.rb +101 -0
  20. data/lib/whirled_peas/graphics/canvas.rb +118 -0
  21. data/lib/whirled_peas/graphics/composer.rb +80 -0
  22. data/lib/whirled_peas/graphics/container_coords.rb +72 -0
  23. data/lib/whirled_peas/graphics/container_dimensions.rb +93 -0
  24. data/lib/whirled_peas/graphics/container_painter.rb +272 -0
  25. data/lib/whirled_peas/graphics/debugger.rb +52 -0
  26. data/lib/whirled_peas/graphics/grid_painter.rb +69 -0
  27. data/lib/whirled_peas/graphics/mock_screen.rb +26 -0
  28. data/lib/whirled_peas/graphics/painter.rb +23 -0
  29. data/lib/whirled_peas/graphics/renderer.rb +26 -0
  30. data/lib/whirled_peas/graphics/screen.rb +70 -0
  31. data/lib/whirled_peas/graphics/text_dimensions.rb +15 -0
  32. data/lib/whirled_peas/graphics/text_painter.rb +40 -0
  33. data/lib/whirled_peas/settings.rb +5 -0
  34. data/lib/whirled_peas/settings/alignment.rb +24 -0
  35. data/lib/whirled_peas/settings/bg_color.rb +24 -0
  36. data/lib/whirled_peas/settings/border.rb +101 -0
  37. data/lib/whirled_peas/settings/box_settings.rb +8 -0
  38. data/lib/whirled_peas/settings/color.rb +68 -0
  39. data/lib/whirled_peas/settings/container_settings.rb +223 -0
  40. data/lib/whirled_peas/settings/debugger.rb +96 -0
  41. data/lib/whirled_peas/settings/display_flow.rb +27 -0
  42. data/lib/whirled_peas/settings/element_settings.rb +61 -0
  43. data/lib/whirled_peas/settings/grid_settings.rb +19 -0
  44. data/lib/whirled_peas/settings/margin.rb +8 -0
  45. data/lib/whirled_peas/settings/padding.rb +8 -0
  46. data/lib/whirled_peas/settings/position.rb +15 -0
  47. data/lib/whirled_peas/settings/scrollbar.rb +15 -0
  48. data/lib/whirled_peas/settings/sizing.rb +19 -0
  49. data/lib/whirled_peas/settings/spacing.rb +58 -0
  50. data/lib/whirled_peas/settings/text_color.rb +21 -0
  51. data/lib/whirled_peas/settings/text_settings.rb +15 -0
  52. data/lib/whirled_peas/settings/vert_alignment.rb +24 -0
  53. data/lib/whirled_peas/utils.rb +5 -0
  54. data/lib/whirled_peas/utils/ansi.rb +53 -0
  55. data/lib/whirled_peas/utils/formatted_string.rb +64 -0
  56. data/lib/whirled_peas/utils/title_font.rb +75 -0
  57. data/lib/whirled_peas/version.rb +1 -1
  58. data/screen_test/elements/box.frame +1 -0
  59. data/screen_test/elements/box.rb +20 -0
  60. data/screen_test/elements/grid.frame +1 -0
  61. data/screen_test/elements/grid.rb +13 -0
  62. data/screen_test/elements/screen_overflow_x.frame +1 -0
  63. data/screen_test/elements/screen_overflow_x.rb +9 -0
  64. data/screen_test/elements/screen_overflow_y.frame +1 -0
  65. data/screen_test/elements/screen_overflow_y.rb +9 -0
  66. data/screen_test/elements/text.frame +1 -0
  67. data/screen_test/elements/text.rb +9 -0
  68. data/screen_test/elements/text_multiline.frame +1 -0
  69. data/screen_test/elements/text_multiline.rb +9 -0
  70. data/screen_test/settings/align/box_around.frame +1 -0
  71. data/screen_test/settings/align/box_around.rb +16 -0
  72. data/screen_test/settings/align/box_between.frame +1 -0
  73. data/screen_test/settings/align/box_between.rb +16 -0
  74. data/screen_test/settings/align/box_center.frame +1 -0
  75. data/screen_test/settings/align/box_center.rb +21 -0
  76. data/screen_test/settings/align/box_default.frame +1 -0
  77. data/screen_test/settings/align/box_default.rb +20 -0
  78. data/screen_test/settings/align/box_evenly.frame +1 -0
  79. data/screen_test/settings/align/box_evenly.rb +16 -0
  80. data/screen_test/settings/align/box_left.frame +1 -0
  81. data/screen_test/settings/align/box_left.rb +21 -0
  82. data/screen_test/settings/align/box_right.frame +1 -0
  83. data/screen_test/settings/align/box_right.rb +21 -0
  84. data/screen_test/settings/align/children_center.frame +1 -0
  85. data/screen_test/settings/align/children_center.rb +15 -0
  86. data/screen_test/settings/align/children_left.frame +1 -0
  87. data/screen_test/settings/align/children_left.rb +15 -0
  88. data/screen_test/settings/align/children_right.frame +1 -0
  89. data/screen_test/settings/align/children_right.rb +15 -0
  90. data/screen_test/settings/align/grid_center.frame +1 -0
  91. data/screen_test/settings/align/grid_center.rb +18 -0
  92. data/screen_test/settings/align/grid_default.frame +1 -0
  93. data/screen_test/settings/align/grid_default.rb +17 -0
  94. data/screen_test/settings/align/grid_left.frame +1 -0
  95. data/screen_test/settings/align/grid_left.rb +18 -0
  96. data/screen_test/settings/align/grid_right.frame +1 -0
  97. data/screen_test/settings/align/grid_right.rb +18 -0
  98. data/screen_test/settings/ansi/bold.frame +1 -0
  99. data/screen_test/settings/ansi/bold.rb +14 -0
  100. data/screen_test/settings/ansi/color.frame +1 -0
  101. data/screen_test/settings/ansi/color.rb +37 -0
  102. data/screen_test/settings/ansi/underline.frame +1 -0
  103. data/screen_test/settings/ansi/underline.rb +14 -0
  104. data/screen_test/settings/border.frame +1 -0
  105. data/screen_test/settings/border.rb +13 -0
  106. data/screen_test/settings/flow/box_b2t.frame +1 -0
  107. data/screen_test/settings/flow/box_b2t.rb +26 -0
  108. data/screen_test/settings/flow/box_l2r.frame +1 -0
  109. data/screen_test/settings/flow/box_l2r.rb +26 -0
  110. data/screen_test/settings/flow/box_r2l.frame +1 -0
  111. data/screen_test/settings/flow/box_r2l.rb +26 -0
  112. data/screen_test/settings/flow/box_t2b.frame +1 -0
  113. data/screen_test/settings/flow/box_t2b.rb +26 -0
  114. data/screen_test/settings/flow/grid_b2t.frame +1 -0
  115. data/screen_test/settings/flow/grid_b2t.rb +14 -0
  116. data/screen_test/settings/flow/grid_l2r.frame +1 -0
  117. data/screen_test/settings/flow/grid_l2r.rb +14 -0
  118. data/screen_test/settings/flow/grid_r2l.frame +1 -0
  119. data/screen_test/settings/flow/grid_r2l.rb +14 -0
  120. data/screen_test/settings/flow/grid_t2b.frame +1 -0
  121. data/screen_test/settings/flow/grid_t2b.rb +14 -0
  122. data/screen_test/settings/height/box.frame +1 -0
  123. data/screen_test/settings/height/box.rb +13 -0
  124. data/screen_test/settings/height/box_border_sizing.frame +1 -0
  125. data/screen_test/settings/height/box_border_sizing.rb +15 -0
  126. data/screen_test/settings/height/grid.frame +1 -0
  127. data/screen_test/settings/height/grid.rb +14 -0
  128. data/screen_test/settings/height/overflow_box.frame +1 -0
  129. data/screen_test/settings/height/overflow_box.rb +13 -0
  130. data/screen_test/settings/height/overflow_box_l2r.frame +1 -0
  131. data/screen_test/settings/height/overflow_box_l2r.rb +17 -0
  132. data/screen_test/settings/height/overflow_box_t2b.frame +1 -0
  133. data/screen_test/settings/height/overflow_box_t2b.rb +16 -0
  134. data/screen_test/settings/height/overflow_grid.frame +1 -0
  135. data/screen_test/settings/height/overflow_grid.rb +16 -0
  136. data/screen_test/settings/margin.frame +1 -0
  137. data/screen_test/settings/margin.rb +16 -0
  138. data/screen_test/settings/padding.frame +1 -0
  139. data/screen_test/settings/padding.rb +13 -0
  140. data/screen_test/settings/position/box_left.frame +1 -0
  141. data/screen_test/settings/position/box_left.rb +17 -0
  142. data/screen_test/settings/position/box_left_negative.frame +1 -0
  143. data/screen_test/settings/position/box_left_negative.rb +17 -0
  144. data/screen_test/settings/position/box_top.frame +1 -0
  145. data/screen_test/settings/position/box_top.rb +17 -0
  146. data/screen_test/settings/position/box_top_negative.frame +1 -0
  147. data/screen_test/settings/position/box_top_negative.rb +17 -0
  148. data/screen_test/settings/position/grid_left.frame +1 -0
  149. data/screen_test/settings/position/grid_left.rb +18 -0
  150. data/screen_test/settings/position/grid_left_negative.frame +1 -0
  151. data/screen_test/settings/position/grid_left_negative.rb +18 -0
  152. data/screen_test/settings/position/grid_top.frame +1 -0
  153. data/screen_test/settings/position/grid_top.rb +18 -0
  154. data/screen_test/settings/position/grid_top_negative.frame +1 -0
  155. data/screen_test/settings/position/grid_top_negative.rb +18 -0
  156. data/screen_test/settings/scroll/horiz_box.frame +1 -0
  157. data/screen_test/settings/scroll/horiz_box.rb +17 -0
  158. data/screen_test/settings/scroll/horiz_box_align_center.rb +18 -0
  159. data/screen_test/settings/scroll/horiz_box_align_right.rb +18 -0
  160. data/screen_test/settings/scroll/vert_box.frame +1 -0
  161. data/screen_test/settings/scroll/vert_box.rb +20 -0
  162. data/screen_test/settings/title_font.frame +1 -0
  163. data/screen_test/settings/title_font.rb +12 -0
  164. data/screen_test/settings/valign/box_around.frame +1 -0
  165. data/screen_test/settings/valign/box_around.rb +17 -0
  166. data/screen_test/settings/valign/box_between.frame +1 -0
  167. data/screen_test/settings/valign/box_between.rb +17 -0
  168. data/screen_test/settings/valign/box_bottom.frame +1 -0
  169. data/screen_test/settings/valign/box_bottom.rb +17 -0
  170. data/screen_test/settings/valign/box_default.frame +1 -0
  171. data/screen_test/settings/valign/box_default.rb +16 -0
  172. data/screen_test/settings/valign/box_evenly.frame +1 -0
  173. data/screen_test/settings/valign/box_evenly.rb +17 -0
  174. data/screen_test/settings/valign/box_middle.frame +1 -0
  175. data/screen_test/settings/valign/box_middle.rb +17 -0
  176. data/screen_test/settings/valign/box_top.frame +1 -0
  177. data/screen_test/settings/valign/box_top.rb +17 -0
  178. data/screen_test/settings/valign/grid_bottom.frame +1 -0
  179. data/screen_test/settings/valign/grid_bottom.rb +15 -0
  180. data/screen_test/settings/valign/grid_default.frame +1 -0
  181. data/screen_test/settings/valign/grid_default.rb +14 -0
  182. data/screen_test/settings/valign/grid_middle.frame +1 -0
  183. data/screen_test/settings/valign/grid_middle.rb +15 -0
  184. data/screen_test/settings/valign/grid_top.frame +1 -0
  185. data/screen_test/settings/valign/grid_top.rb +15 -0
  186. data/screen_test/settings/width/box_border_sizing.frame +1 -0
  187. data/screen_test/settings/width/box_border_sizing.rb +15 -0
  188. data/screen_test/settings/width/box_content.frame +1 -0
  189. data/screen_test/settings/width/box_content.rb +15 -0
  190. data/screen_test/settings/width/box_default.frame +1 -0
  191. data/screen_test/settings/width/box_default.rb +14 -0
  192. data/screen_test/settings/width/grid.frame +1 -0
  193. data/screen_test/settings/width/grid.rb +14 -0
  194. data/screen_test/settings/width/overflow_align_center.frame +1 -0
  195. data/screen_test/settings/width/overflow_align_center.rb +14 -0
  196. data/screen_test/settings/width/overflow_align_right.frame +1 -0
  197. data/screen_test/settings/width/overflow_align_right.rb +14 -0
  198. data/screen_test/settings/width/overflow_box.frame +1 -0
  199. data/screen_test/settings/width/overflow_box.rb +13 -0
  200. data/screen_test/settings/width/overflow_box_l2r.frame +1 -0
  201. data/screen_test/settings/width/overflow_box_l2r.rb +16 -0
  202. data/screen_test/settings/width/overflow_box_t2b.frame +1 -0
  203. data/screen_test/settings/width/overflow_box_t2b.rb +17 -0
  204. data/screen_test/settings/width/overflow_grid.frame +1 -0
  205. data/screen_test/settings/width/overflow_grid.rb +14 -0
  206. data/tools/whirled_peas/tools/screen_tester.rb +233 -0
  207. data/whirled_peas.gemspec +4 -1
  208. metadata +215 -17
  209. data/lib/whirled_peas/ui.rb +0 -7
  210. data/lib/whirled_peas/ui/ansi.rb +0 -103
  211. data/lib/whirled_peas/ui/canvas.rb +0 -68
  212. data/lib/whirled_peas/ui/color.rb +0 -101
  213. data/lib/whirled_peas/ui/element.rb +0 -224
  214. data/lib/whirled_peas/ui/painter.rb +0 -283
  215. data/lib/whirled_peas/ui/screen.rb +0 -60
  216. data/lib/whirled_peas/ui/settings.rb +0 -523
  217. data/sandbox/auto.rb +0 -13
  218. data/sandbox/box.rb +0 -19
  219. data/sandbox/grid.rb +0 -13
  220. data/sandbox/sandbox.rb +0 -17
  221. data/sandbox/text.rb +0 -33
@@ -0,0 +1,8 @@
1
+ require_relative 'container_settings'
2
+
3
+ module WhirledPeas
4
+ module Settings
5
+ class BoxSettings < ContainerSettings
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,68 @@
1
+ require 'whirled_peas/utils/ansi'
2
+
3
+ module WhirledPeas
4
+ module Settings
5
+ # An abstract class that encapsulates colors for a specific use case
6
+ class Color
7
+ # Validate the `color` argument is either (1) nil, (2) a valid Color constant in
8
+ # this class or (3) a symbol that maps to valid Color constant. E.g. if there
9
+ # is a RED constant in an implementing class, then :red or :bright_red are
10
+ # valid values for `color`
11
+ #
12
+ # @param color [Color|Symbol]
13
+ # @return [Color|Symbol] the value passed in if valid, otherwise an ArgumentError
14
+ # is raised.
15
+ def self.validate!(color)
16
+ return if color.nil?
17
+ return color if color.is_a?(self)
18
+ if color.is_a?(Symbol)
19
+ match = color.to_s.match(/^(bright_)?(\w+)$/)
20
+ color_class = self.const_get(match[2].upcase)
21
+ if color_class.is_a?(self)
22
+ if !match[1]
23
+ return color_class
24
+ elsif !color_class.bright?
25
+ return color_class.bright
26
+ end
27
+ end
28
+ end
29
+ error_message = "Unsupported #{self.name.split('::').last}: #{color.inspect}"
30
+ raise ArgumentError, error_message
31
+ rescue NameError
32
+ error_message = "Unsupported #{self.name.split('::').last}: #{color.inspect}"
33
+ raise ArgumentError, error_message
34
+ end
35
+
36
+ def initialize(code, bright=false)
37
+ @code = code
38
+ @bright = bright
39
+ end
40
+
41
+ def bright?
42
+ @bright
43
+ end
44
+
45
+ def bright
46
+ bright? ? self : self.class.new(@code + Utils::Ansi::BRIGHT_OFFSET, true)
47
+ end
48
+
49
+ def hash
50
+ [@code, @bright].hash
51
+ end
52
+
53
+ def ==(other)
54
+ other.is_a?(self.class) && self.hash == other.hash
55
+ end
56
+ alias_method :eq?, :==
57
+
58
+ def to_s
59
+ @code.to_s
60
+ end
61
+
62
+ def inspect
63
+ "#{self.class.name.split('::').last}(code=#{@code}, bright=#{@bright})"
64
+ end
65
+ end
66
+ private_constant :Color
67
+ end
68
+ end
@@ -0,0 +1,223 @@
1
+ require_relative 'alignment'
2
+ require_relative 'border'
3
+ require_relative 'display_flow'
4
+ require_relative 'element_settings'
5
+ require_relative 'margin'
6
+ require_relative 'padding'
7
+ require_relative 'position'
8
+ require_relative 'scrollbar'
9
+ require_relative 'sizing'
10
+ require_relative 'vert_alignment'
11
+
12
+ module WhirledPeas
13
+ module Settings
14
+ class ContainerSettings < ElementSettings
15
+ attr_accessor :width, :height
16
+
17
+ def align
18
+ @_align || Alignment::DEFAULT
19
+ end
20
+
21
+ def align_left?
22
+ align == Alignment::LEFT
23
+ end
24
+
25
+ def align_center?
26
+ align == Alignment::CENTER
27
+ end
28
+
29
+ def align_right?
30
+ align == Alignment::RIGHT
31
+ end
32
+
33
+ def align_between?
34
+ align == Alignment::BETWEEN
35
+ end
36
+
37
+ def align_around?
38
+ align == Alignment::AROUND
39
+ end
40
+
41
+ def align_evenly?
42
+ align == Alignment::EVENLY
43
+ end
44
+
45
+ def align=(align)
46
+ @_align = Alignment.validate!(align)
47
+ end
48
+
49
+ def valign
50
+ @_valign || VertAlignment::DEFAULT
51
+ end
52
+
53
+ def valign_top?
54
+ valign == VertAlignment::TOP
55
+ end
56
+
57
+ def valign_middle?
58
+ valign == VertAlignment::MIDDLE
59
+ end
60
+
61
+ def valign_bottom?
62
+ valign == VertAlignment::BOTTOM
63
+ end
64
+
65
+ def valign_between?
66
+ valign == VertAlignment::BETWEEN
67
+ end
68
+
69
+ def valign_around?
70
+ valign == VertAlignment::AROUND
71
+ end
72
+
73
+ def valign_evenly?
74
+ valign == VertAlignment::EVENLY
75
+ end
76
+
77
+ def valign=(valign)
78
+ @_valign = VertAlignment.validate!(valign)
79
+ end
80
+
81
+ def set_border(
82
+ left: nil, top: nil, right: nil, bottom: nil, inner_horiz: nil, inner_vert: nil, style: nil, color: nil
83
+ )
84
+ border.left = left unless left.nil?
85
+ border.top = top unless top.nil?
86
+ border.right = right unless right.nil?
87
+ border.bottom = bottom unless bottom.nil?
88
+ border.inner_horiz = inner_horiz unless inner_horiz.nil?
89
+ border.inner_vert = inner_vert unless inner_vert.nil?
90
+ border.style = style unless style.nil?
91
+ border.color = color unless color.nil?
92
+ end
93
+
94
+ def full_border(style: nil, color: nil)
95
+ set_border(
96
+ left: true, top: true, right: true, bottom: true, inner_horiz: true, inner_vert: true, style: style, color: color
97
+ )
98
+ end
99
+
100
+ def border
101
+ @_border ||= Border.new
102
+ end
103
+
104
+ def flow=(flow)
105
+ @_flow = DisplayFlow.validate!(flow)
106
+ end
107
+
108
+ def flow
109
+ @_flow || DisplayFlow::DEFAULT
110
+ end
111
+
112
+ def horizontal_flow?
113
+ %i[l2r r2l].include?(flow)
114
+ end
115
+
116
+ def vertical_flow?
117
+ !horizontal_flow?
118
+ end
119
+
120
+ def forward_flow?
121
+ %i[l2r t2b].include?(flow)
122
+ end
123
+
124
+ def reverse_flow?
125
+ !forward_flow?
126
+ end
127
+
128
+ def set_margin(left: nil, top: nil, right: nil, bottom: nil, horiz: nil, vert: nil)
129
+ if horiz && (left || right)
130
+ raise ArgumentError, 'Cannot set horizontal margin when setting left/right'
131
+ elsif vert && (top || bottom)
132
+ raise ArgumentError, 'Cannot set vertical margin when setting top/bottom'
133
+ end
134
+
135
+ if horiz
136
+ margin.horiz = horiz
137
+ else
138
+ margin.left = left if left
139
+ margin.right = right if right
140
+ end
141
+
142
+ if vert
143
+ margin.vert = vert
144
+ else
145
+ margin.top = top if top
146
+ margin.bottom = bottom if bottom
147
+ end
148
+ end
149
+
150
+ def margin
151
+ @_margin ||= Margin.new
152
+ end
153
+
154
+ def set_padding(left: nil, top: nil, right: nil, bottom: nil, horiz: nil, vert: nil)
155
+ if horiz && (left || right)
156
+ raise ArgumentError, 'Cannot set horizontal padding when setting left/right'
157
+ elsif vert && (top || bottom)
158
+ raise ArgumentError, 'Cannot set vertical padding when setting top/bottom'
159
+ end
160
+
161
+ if horiz
162
+ padding.horiz = horiz
163
+ else
164
+ padding.left = left if left
165
+ padding.right = right if right
166
+ end
167
+
168
+ if vert
169
+ padding.vert = vert
170
+ else
171
+ padding.top = top if top
172
+ padding.bottom = bottom if bottom
173
+ end
174
+ end
175
+
176
+ def padding
177
+ @_padding ||= Padding.new
178
+ end
179
+
180
+ def set_position(left: nil, top: nil)
181
+ position.left = left if left
182
+ position.top = top if top
183
+ end
184
+
185
+ def position
186
+ @_position ||= Position.new
187
+ end
188
+
189
+ def set_scrollbar(horiz: nil, vert: nil)
190
+ scrollbar.horiz = horiz unless horiz.nil?
191
+ scrollbar.vert = vert unless vert.nil?
192
+ end
193
+
194
+ def scrollbar
195
+ @_scrollbar ||= Scrollbar.new
196
+ end
197
+
198
+ def sizing
199
+ @_sizing || Sizing::DEFAULT
200
+ end
201
+
202
+ def border_sizing?
203
+ @_sizing == Sizing::BORDER
204
+ end
205
+
206
+ def content_sizing?
207
+ @_sizing == Sizing::CONTENT
208
+ end
209
+
210
+ def sizing=(sizing)
211
+ @_sizing = Sizing.validate!(sizing)
212
+ end
213
+
214
+ def inherit(parent)
215
+ super
216
+ return unless parent.is_a?(ContainerSettings)
217
+ set_border(color: parent.border.color, style: parent.border.style)
218
+ end
219
+
220
+ protected
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,96 @@
1
+ require_relative 'border'
2
+ require_relative 'container_settings'
3
+ require_relative 'margin'
4
+ require_relative 'padding'
5
+ require_relative 'position'
6
+ require_relative 'scrollbar'
7
+
8
+ module WhirledPeas
9
+ module Settings
10
+ class Debugger
11
+ def initialize(settings)
12
+ @settings = settings
13
+ end
14
+
15
+ def debug(indent='')
16
+ values = non_default_values(indent + ' ')
17
+ details = values.length > 0 ? values.join("\n") : "#{indent} <default>"
18
+ "#{indent}#{settings.class}\n#{details}"
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :settings
24
+
25
+ def non_default_values(indent)
26
+ settings.instance_variables.map do |ivar, values|
27
+ value = settings.instance_variable_get(ivar)
28
+ next if value.nil?
29
+ printable_value = debug_value(value)
30
+ "#{indent}#{ivar.to_s.sub(/^@?_?/, '')}: #{printable_value}" unless printable_value.nil?
31
+ end.compact
32
+ end
33
+
34
+ def debug_value(value)
35
+ return if value.nil?
36
+ case value
37
+ when Position
38
+ position_value(value)
39
+ when Margin
40
+ margin_value(value)
41
+ when Border
42
+ border_value(value)
43
+ when Padding
44
+ padding_value(value)
45
+ when Scrollbar
46
+ scrollbar_value(value)
47
+ else
48
+ value.inspect
49
+ end
50
+ end
51
+
52
+ def non_defaults(object, default_object, keys)
53
+ values = keys.map.with_object({}) do |key, hash|
54
+ unless object.send(key) == default_object.send(key)
55
+ hash[key] = object.send(key)
56
+ end
57
+ end
58
+ values.keys.map { |k| "#{k}: #{values[k]}"}.join(', ')
59
+ end
60
+
61
+ def position_value(position)
62
+ values = non_defaults(position, Position.new, %i[left top])
63
+ return if values == ''
64
+ "Position(#{values})"
65
+ end
66
+
67
+ def margin_value(margin)
68
+ values = non_defaults(margin, Margin.new, %i[left top right bottom])
69
+ return if values == ''
70
+ "Margin(#{values})"
71
+ end
72
+
73
+ def border_value(border)
74
+ values = non_defaults(
75
+ border,
76
+ Border.new,
77
+ %i[left? top? right? bottom? inner_horiz? inner_vert? style color]
78
+ )
79
+ return if values == ''
80
+ "Border(#{values})"
81
+ end
82
+
83
+ def padding_value(padding)
84
+ values = non_defaults(padding, Padding.new, %i[left top right bottom])
85
+ return if values == ''
86
+ "Padding(#{values})"
87
+ end
88
+
89
+ def scrollbar_value(scrollbar)
90
+ values = non_defaults(scrollbar, Scrollbar.new, %i[horiz? vert?])
91
+ return if values == ''
92
+ "Scrollbar(#{values})"
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,27 @@
1
+ module WhirledPeas
2
+ module Settings
3
+ module DisplayFlow
4
+ LEFT_TO_RIGHT = :l2r
5
+ RIGHT_TO_LEFT = :r2l
6
+ TOP_TO_BOTTOM = :t2b
7
+ BOTTOM_TO_TOP = :b2t
8
+
9
+ DEFAULT = LEFT_TO_RIGHT
10
+
11
+ VALID = [
12
+ DisplayFlow::LEFT_TO_RIGHT,
13
+ DisplayFlow::RIGHT_TO_LEFT,
14
+ DisplayFlow::TOP_TO_BOTTOM,
15
+ DisplayFlow::BOTTOM_TO_TOP
16
+ ]
17
+ private_constant :VALID
18
+
19
+ def self.validate!(flow)
20
+ return if flow.nil?
21
+ return flow if VALID.include?(flow)
22
+ raise ArgumentError, "Unsupported display flow: #{flow.inspect}"
23
+ end
24
+ end
25
+ private_constant :DisplayFlow
26
+ end
27
+ end
@@ -0,0 +1,61 @@
1
+ require 'json'
2
+
3
+ require_relative 'alignment'
4
+ require_relative 'bg_color'
5
+ require_relative 'text_color'
6
+
7
+ module WhirledPeas
8
+ module Settings
9
+ class ElementSettings
10
+ def self.inherit(parent)
11
+ child = self.new
12
+ child.inherit(parent)
13
+ child
14
+ end
15
+
16
+ def bg_color
17
+ @_bg_color || BgColor::DEFAULT
18
+ end
19
+
20
+ def bg_color=(color)
21
+ @_bg_color = BgColor.validate!(color)
22
+ end
23
+
24
+ def bold?
25
+ @_bold || false
26
+ end
27
+
28
+ def bold=(val)
29
+ @_bold = val
30
+ end
31
+
32
+ def color
33
+ @_color || TextColor::DEFAULT
34
+ end
35
+
36
+ def color=(color)
37
+ @_color = TextColor.validate!(color)
38
+ end
39
+
40
+ def underline?
41
+ @_underline || false
42
+ end
43
+
44
+ def underline=(val)
45
+ @_underline = val
46
+ end
47
+
48
+ def inherit(parent)
49
+ @_bg_color = parent._bg_color
50
+ @_bold = parent._bold
51
+ @_color = parent._color
52
+ @_underline = parent._underline
53
+ end
54
+
55
+ protected
56
+
57
+ attr_accessor :_bg_color, :_bold, :_color, :_underline
58
+ end
59
+ private_constant :ElementSettings
60
+ end
61
+ end