cura 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +45 -21
  3. data/cura.gemspec +1 -1
  4. data/examples/hello_world/lib/hello_world.rb +10 -10
  5. data/examples/mruby-examples/mrbgem.rake +5 -6
  6. data/examples/todo_list/data.db +0 -0
  7. data/examples/todo_list/lib/todo_list/application.rb +24 -18
  8. data/lib/cura/adapter.rb +13 -20
  9. data/lib/cura/application.rb +47 -51
  10. data/lib/cura/attributes/has_ancestry.rb +4 -8
  11. data/lib/cura/attributes/has_application.rb +3 -7
  12. data/lib/cura/attributes/has_attributes.rb +1 -9
  13. data/lib/cura/attributes/has_children.rb +14 -20
  14. data/lib/cura/attributes/has_colors.rb +14 -18
  15. data/lib/cura/attributes/has_coordinates.rb +9 -15
  16. data/lib/cura/attributes/has_dimensions.rb +12 -18
  17. data/lib/cura/attributes/has_events.rb +10 -18
  18. data/lib/cura/attributes/has_focusability.rb +5 -11
  19. data/lib/cura/attributes/has_initialize.rb +1 -5
  20. data/lib/cura/attributes/has_offsets.rb +16 -20
  21. data/lib/cura/attributes/has_orientation.rb +12 -18
  22. data/lib/cura/attributes/has_relative_coordinates.rb +4 -8
  23. data/lib/cura/attributes/has_root.rb +18 -22
  24. data/lib/cura/attributes/has_side_attributes.rb +18 -24
  25. data/lib/cura/attributes/has_windows.rb +13 -19
  26. data/lib/cura/borders.rb +0 -4
  27. data/lib/cura/color.rb +84 -91
  28. data/lib/cura/component/base.rb +29 -33
  29. data/lib/cura/component/button.rb +10 -16
  30. data/lib/cura/component/group.rb +14 -18
  31. data/lib/cura/component/label.rb +44 -48
  32. data/lib/cura/component/listbox.rb +24 -28
  33. data/lib/cura/component/pack.rb +14 -18
  34. data/lib/cura/component/scrollbar.rb +41 -45
  35. data/lib/cura/component/textbox.rb +21 -25
  36. data/lib/cura/cursor.rb +15 -23
  37. data/lib/cura/error/base.rb +0 -3
  38. data/lib/cura/error/invalid_adapter.rb +1 -7
  39. data/lib/cura/error/invalid_application.rb +1 -7
  40. data/lib/cura/error/invalid_color.rb +1 -7
  41. data/lib/cura/error/invalid_component.rb +1 -7
  42. data/lib/cura/error/invalid_middleware.rb +1 -7
  43. data/lib/cura/event.rb +4 -8
  44. data/lib/cura/event/base.rb +17 -24
  45. data/lib/cura/event/click.rb +1 -6
  46. data/lib/cura/event/dispatcher.rb +20 -26
  47. data/lib/cura/event/focus.rb +1 -6
  48. data/lib/cura/event/handler.rb +16 -24
  49. data/lib/cura/event/key_down.rb +11 -17
  50. data/lib/cura/event/middleware/aimer/base.rb +4 -10
  51. data/lib/cura/event/middleware/aimer/dispatcher_target.rb +2 -8
  52. data/lib/cura/event/middleware/aimer/mouse_focus.rb +6 -11
  53. data/lib/cura/event/middleware/aimer/target_option.rb +4 -10
  54. data/lib/cura/event/middleware/base.rb +0 -4
  55. data/lib/cura/event/middleware/dispatch.rb +0 -4
  56. data/lib/cura/event/middleware/translator/base.rb +4 -10
  57. data/lib/cura/event/middleware/translator/mouse_click.rb +4 -8
  58. data/lib/cura/event/mouse.rb +5 -11
  59. data/lib/cura/event/mouse_button.rb +21 -27
  60. data/lib/cura/event/mouse_wheel_down.rb +1 -6
  61. data/lib/cura/event/mouse_wheel_up.rb +1 -6
  62. data/lib/cura/event/resize.rb +0 -4
  63. data/lib/cura/event/selected.rb +1 -6
  64. data/lib/cura/event/unfocus.rb +1 -6
  65. data/lib/cura/focus_controller.rb +19 -23
  66. data/lib/cura/key.rb +277 -283
  67. data/lib/cura/margins.rb +0 -4
  68. data/lib/cura/offsets.rb +14 -18
  69. data/lib/cura/padding.rb +0 -4
  70. data/lib/cura/pencil.rb +3 -7
  71. data/lib/cura/version.rb +1 -3
  72. data/lib/cura/window.rb +11 -16
  73. data/spec/cura/attributes/has_ancestry_spec.rb +39 -39
  74. data/spec/cura/attributes/has_application_spec.rb +20 -20
  75. data/spec/cura/attributes/has_attributes_spec.rb +26 -26
  76. data/spec/cura/attributes/has_children_spec.rb +54 -54
  77. data/spec/cura/attributes/has_colors_spec.rb +4 -4
  78. data/spec/cura/attributes/has_coordinates_spec.rb +4 -4
  79. data/spec/cura/attributes/has_dimensions_spec.rb +4 -4
  80. data/spec/cura/attributes/has_events_spec.rb +4 -4
  81. data/spec/cura/attributes/has_focusability_spec.rb +18 -18
  82. data/spec/cura/attributes/has_offsets_spec.rb +4 -4
  83. data/spec/cura/attributes/has_orientation_spec.rb +38 -38
  84. data/spec/cura/attributes/has_relative_coordinates_spec.rb +4 -4
  85. data/spec/cura/attributes/has_side_attributes_spec.rb +4 -4
  86. data/spec/spec_helper.rb +1 -1
  87. data/spec/support/shared_examples_for_attributes.rb +41 -41
  88. metadata +1 -1
@@ -10,13 +10,11 @@ end
10
10
 
11
11
  module Cura
12
12
  module Component
13
-
14
13
  # The base class for all components.
15
14
  #
16
15
  # All components use a box model similar to CSS.
17
16
  # Margins, borders, paddings, then content.
18
17
  class Base
19
-
20
18
  include Attributes::HasInitialize
21
19
  include Attributes::HasAttributes
22
20
  include Attributes::HasDimensions
@@ -25,7 +23,7 @@ module Cura
25
23
  include Attributes::HasColors
26
24
  include Attributes::HasOffsets
27
25
  include Attributes::HasRelativeCoordinates
28
-
26
+
29
27
  # Get the cursor for this application.
30
28
  # TODO: Delegate something like: def_delegate(:cursor) { application }
31
29
  #
@@ -33,7 +31,7 @@ module Cura
33
31
  def cursor
34
32
  application.cursor
35
33
  end
36
-
34
+
37
35
  # Get the pencil for this application.
38
36
  # TODO: Delegate
39
37
  #
@@ -41,30 +39,30 @@ module Cura
41
39
  def pencil
42
40
  application.pencil
43
41
  end
44
-
42
+
45
43
  # Get the application of this object.
46
44
  #
47
45
  # @return [Application]
48
46
  def application
49
47
  return nil if parent.nil?
50
-
48
+
51
49
  parent.application
52
50
  end
53
-
51
+
54
52
  # Focus on this component.
55
53
  #
56
54
  # @return [Component]
57
55
  def focus
58
56
  application.dispatcher.target = self
59
57
  end
60
-
58
+
61
59
  # Check whether this component is focused.
62
60
  #
63
61
  # @return [Boolean]
64
62
  def focused?
65
63
  application.dispatcher.target == self
66
64
  end
67
-
65
+
68
66
  # Determine if the given absolute coordinates are within the bounds of this component.
69
67
  #
70
68
  # @param [#to_h] options
@@ -73,83 +71,83 @@ module Cura
73
71
  # @return [Boolean]
74
72
  def contains_coordinates?(options={})
75
73
  options = options.to_h
76
-
74
+
77
75
  (absolute_x..absolute_x + width).include?(options[:x].to_i) && (absolute_y..absolute_y + width).include?(options[:y].to_i)
78
76
  end
79
-
77
+
80
78
  # Get the foreground color of this object.
81
79
  #
82
80
  # @return [Color]
83
81
  def foreground
84
82
  get_or_inherit_color(:foreground, Color.black)
85
83
  end
86
-
84
+
87
85
  # Get the background color of this object.
88
86
  #
89
87
  # @return [Color]
90
88
  def background
91
89
  get_or_inherit_color(:background, Color.white)
92
90
  end
93
-
91
+
94
92
  # Instance inspection.
95
93
  #
96
94
  # @return [String]
97
95
  def inspect
98
96
  "#<#{self.class}:0x#{__id__.to_s(16)} x=#{x} y=#{y} absolute_x=#{absolute_x} absolute_y=#{absolute_y} w=#{width} h=#{height} parent=#{@parent.class}:0x#{@parent.__id__.to_s(16)}>"
99
97
  end
100
-
98
+
101
99
  # Update this component.
102
100
  #
103
101
  # @return [Component]
104
102
  def update
105
103
  self
106
104
  end
107
-
105
+
108
106
  # Draw this component.
109
107
  #
110
108
  # @return [Component]
111
109
  def draw
112
110
  draw_background
113
111
  draw_border
114
-
112
+
115
113
  self
116
114
  end
117
-
115
+
118
116
  protected
119
-
117
+
120
118
  # Draw a point.
121
119
  def draw_point(x, y, color=Cura::Color.black)
122
120
  x = absolute_x + @offsets.left + x
123
121
  y = absolute_y + @offsets.top + y
124
-
122
+
125
123
  pencil.draw_point(x, y, color)
126
124
  end
127
-
125
+
128
126
  # Draw a rectangle.
129
127
  # TODO: filled argument
130
128
  def draw_rectangle(x, y, width, height, color=Cura::Color.black)
131
129
  x = absolute_x + @offsets.left + x
132
130
  y = absolute_y + @offsets.top + y
133
-
131
+
134
132
  pencil.draw_rectangle(x, y, width, height, color)
135
133
  end
136
-
134
+
137
135
  # Draw a single character.
138
136
  def draw_character(x, y, character, foreground=Cura::Color.black, background=Cura::Color.white, bold=false, underline=false)
139
137
  x = absolute_x + @offsets.left + x
140
138
  y = absolute_y + @offsets.top + y
141
-
139
+
142
140
  pencil.draw_character(x, y, character, foreground, background, bold, underline)
143
141
  end
144
-
142
+
145
143
  # Draw text.
146
144
  def draw_text(x, y, text, foreground=Cura::Color.black, background=Cura::Color.white, bold=false, underline=false)
147
145
  x = absolute_x + @offsets.left + x
148
146
  y = absolute_y + @offsets.top + y
149
-
147
+
150
148
  pencil.draw_text(x, y, text, foreground, background, bold, underline)
151
149
  end
152
-
150
+
153
151
  # Draw the background of this component.
154
152
  def draw_background
155
153
  x = absolute_x + @margin.left + @border.left
@@ -157,24 +155,22 @@ module Cura
157
155
  width = self.width + @padding.width
158
156
  height = self.height + @padding.height
159
157
  color = background
160
-
158
+
161
159
  pencil.draw_rectangle(x, y, width, height, color)
162
160
  end
163
-
161
+
164
162
  # Draw the border of this component.
165
163
  def draw_border # TODO
166
164
  end
167
-
165
+
168
166
  def get_or_inherit_color(name, default)
169
167
  value = instance_variable_get("@#{name}")
170
-
168
+
171
169
  return value unless value == :inherit
172
170
  return default unless respond_to?(:parent) && parent.respond_to?(name)
173
-
171
+
174
172
  parent.send(name)
175
173
  end
176
-
177
174
  end
178
-
179
175
  end
180
176
  end
@@ -1,57 +1,51 @@
1
- if Kernel.respond_to?(:require)
2
- require "cura/component/label"
3
- end
1
+ require "cura/component/label" if Kernel.respond_to?(:require)
4
2
 
5
3
  module Cura
6
4
  module Component
7
-
8
5
  # A button component.
9
6
  class Button < Label
10
-
11
7
  on_event(:key_down) do |event|
12
8
  click if event.target == self && event.name == :enter
13
9
  end
14
-
10
+
15
11
  on_event(:mouse_button) do |event|
16
12
  click if event.target == self && event.up? && contains_coordinates?(x: event.x, y: event.y)
17
13
  end
18
-
14
+
19
15
  # @method focused_background
20
16
  # Get the focused background color of this object.
21
17
  #
22
18
  # @return [Color]
23
-
19
+
24
20
  # @method focused_background=(value)
25
21
  # Set the focused background color of this object.
26
22
  #
27
23
  # @param [Color] value
28
24
  # @return [Color]
29
-
25
+
30
26
  attribute(:focused_background) { |value| validate_color_attribute(value) }
31
-
27
+
32
28
  def initialize(attributes={})
33
29
  @focusable = true
34
30
  @foreground = Cura::Color.black
35
31
  @background = Cura::Color.white
36
32
  @focused_background = Color.new(78, 78, 78)
37
-
33
+
38
34
  super
39
35
  end
40
-
36
+
41
37
  def background
42
38
  focused? ? @focused_background : get_or_inherit_color(:background, Color.black)
43
39
  end
44
-
40
+
45
41
  # Click this button.
46
42
  #
47
43
  # @return [Button]
48
44
  def click
49
45
  application.dispatch_event(:click, target: self)
50
-
46
+
51
47
  self
52
48
  end
53
-
54
49
  end
55
-
56
50
  end
57
51
  end
@@ -5,73 +5,69 @@ end
5
5
 
6
6
  module Cura
7
7
  module Component
8
-
9
8
  # A component with children.
10
9
  # When children are added, their parent will be set to this group.
11
10
  class Group < Base
12
-
13
11
  include Attributes::HasChildren
14
-
12
+
15
13
  # Get the width of this group.
16
14
  #
17
15
  # @return [Integer]
18
16
  def width
19
17
  return @width unless @width == :auto
20
18
  return 0 if children.empty?
21
-
19
+
22
20
  children.collect { |child| child.x + child.width + child.offsets.width }.max
23
21
  end
24
-
22
+
25
23
  # Get the height of this group.
26
24
  #
27
25
  # @return [Integer]
28
26
  def height
29
27
  return @height unless @height == :auto
30
28
  return 0 if children.empty?
31
-
29
+
32
30
  children.collect { |child| child.y + child.height + child.offsets.height }.max
33
31
  end
34
-
32
+
35
33
  # Add a child to this group and set it's parent to this Group.
36
34
  #
37
35
  # @param [Component] component
38
36
  # @return [Component]
39
37
  def add_child(component)
40
38
  component = super
41
-
39
+
42
40
  component.parent = self
43
-
41
+
44
42
  component
45
43
  end
46
-
44
+
47
45
  # Remove a child from this object's children at the given index and set it's parent to nil.
48
46
  #
49
47
  # @param [Integer] index
50
48
  # @return [Component]
51
49
  def delete_child_at(index)
52
50
  component = super
53
-
51
+
54
52
  component.parent = nil
55
-
53
+
56
54
  component
57
55
  end
58
-
56
+
59
57
  # Update all children.
60
58
  def update
61
59
  super
62
-
60
+
63
61
  update_children
64
62
  end
65
-
63
+
66
64
  # Draw all children relative to this location.
67
65
  # TODO: If the dimensions of this group of this group are less than the computed dimensions, the drawing will be clipped.
68
66
  def draw
69
67
  super
70
-
68
+
71
69
  draw_children
72
70
  end
73
-
74
71
  end
75
-
76
72
  end
77
73
  end
@@ -5,12 +5,10 @@ end
5
5
 
6
6
  module Cura
7
7
  module Component
8
-
9
8
  # A component displaying text.
10
9
  class Label < Base
11
-
12
10
  include Attributes::HasAttributes
13
-
11
+
14
12
  # Note that you can pass the following:
15
13
  # alignment: { horizontal: true, vertical: true }
16
14
  # instead of:
@@ -21,94 +19,94 @@ module Cura
21
19
  @bold = false
22
20
  @underline = false
23
21
  @text = ""
24
-
22
+
25
23
  super
26
24
  end
27
-
25
+
28
26
  # TODO: #text_foreground, #text_background (? Maybe a separate Text component, like in )
29
-
27
+
30
28
  # Get the width of this label.
31
29
  #
32
30
  # @return [Integer]
33
31
  def width
34
32
  return text_width if @width == :auto
35
-
33
+
36
34
  @width
37
35
  end
38
-
36
+
39
37
  # Get the height of this label.
40
38
  #
41
39
  # @return [Integer]
42
40
  def height
43
41
  return text_height if @height == :auto
44
-
42
+
45
43
  @height
46
44
  end
47
-
45
+
48
46
  # @method text
49
47
  # Get the text of this label.
50
48
  #
51
49
  # @return [String]
52
-
50
+
53
51
  # @method text=(value)
54
52
  # Set the text of this label.
55
53
  #
56
54
  # @param [#to_s] value
57
55
  # @return [String]
58
56
  attribute(:text) { |value| value.to_s }
59
-
57
+
60
58
  # Get the lines of this label.
61
59
  #
62
60
  # @return [<String>]
63
61
  def lines
64
62
  @text.split("\n") # NOTE: Would use String#lines but it's output doesn't think a trailing newline character constitutes a line unless it is followed by another character. #split also removes the newline characters.
65
63
  end
66
-
64
+
67
65
  # Get the width of the text of this label.
68
66
  #
69
67
  # @return [Integer]
70
68
  def text_width
71
69
  return 0 if @text.empty?
72
-
70
+
73
71
  lines.collect(&:length).sort.last
74
72
  end
75
-
73
+
76
74
  # Get the height of the text of this label.
77
75
  #
78
76
  # @return [Integer]
79
77
  def text_height
80
78
  value = lines.length
81
-
79
+
82
80
  value == 0 ? 1 : value
83
81
  end
84
-
82
+
85
83
  # @method bold?
86
84
  # Get whether the text is bold.
87
85
  #
88
86
  # @return [Boolean]
89
-
87
+
90
88
  # @method bold=(value)
91
89
  # Set whether the text is bold.
92
90
  #
93
91
  # @return [Boolean]
94
92
  attribute(:bold, query: true)
95
-
93
+
96
94
  # @method underline?
97
95
  # Get whether the text is underlined.
98
96
  #
99
97
  # @return [Boolean]
100
-
98
+
101
99
  # @method underlined=(value)
102
100
  # Set whether the text is underlined.
103
101
  #
104
102
  # @return [Boolean]
105
103
  attribute(:underline, query: true)
106
-
104
+
107
105
  # @method horizontal_alignment
108
106
  # Get the horizontal alignment of this label.
109
107
  #
110
108
  # @return [Symbol]
111
-
109
+
112
110
  # @method horizontal_alignment=(value)
113
111
  # Set the horizontal alignment of this label.
114
112
  # Must be :left, :center, or :right.
@@ -116,13 +114,13 @@ module Cura
116
114
  # @param [#to_sym] value
117
115
  # @return [Symbol]
118
116
  attribute(:horizontal_alignment) { |value| convert_horizontal_alignment_attribute(value) }
119
-
117
+
120
118
  # @method vertical_alignment
121
119
  # Get the vertical alignment of this label.
122
120
  # Will be :left, :center, or :right.
123
121
  #
124
122
  # @return [Symbol]
125
-
123
+
126
124
  # @method vertical_alignment=(value)
127
125
  # Set the vertical alignment of this label.
128
126
  # Must be :left, :center, or :right.
@@ -130,48 +128,48 @@ module Cura
130
128
  # @param [#to_sym] value
131
129
  # @return [Symbol]
132
130
  attribute(:vertical_alignment) { |value| convert_vertical_alignment_attribute(value) }
133
-
131
+
134
132
  def draw
135
133
  super
136
-
134
+
137
135
  draw_text unless text.empty?
138
136
  end
139
-
137
+
140
138
  protected
141
-
139
+
142
140
  # Helper method for subclasses
143
141
  def text_to_draw
144
142
  @text
145
143
  end
146
-
144
+
147
145
  # Helper method for subclasses
148
146
  def character_to_draw(character)
149
147
  character
150
148
  end
151
-
149
+
152
150
  # TODO: Should use instance vars
153
151
  def draw_text
154
- x_offset = x_offset_start = x_offset_from_alignment# + @offsets.left
155
- y_offset = y_offset_from_alignment# + @offsets.top
152
+ x_offset = x_offset_start = x_offset_from_alignment # + @offsets.left
153
+ y_offset = y_offset_from_alignment # + @offsets.top
156
154
  absolute_x = self.absolute_x
157
155
  absolute_y = self.absolute_y
158
-
156
+
159
157
  text_to_draw.each_char do |character|
160
158
  if character == "\n" # TODO: If multiline? Also check if outside the bounds of the drawing area
161
159
  x_offset = x_offset_start
162
-
160
+
163
161
  y_offset += 1
164
162
  else
165
163
  unless x_offset > width || y_offset > height
166
164
  character = character_to_draw(character)
167
165
  draw_character(x_offset, y_offset, character, foreground, background, @bold, @underline)
168
166
  end
169
-
167
+
170
168
  x_offset += 1
171
169
  end
172
170
  end
173
171
  end
174
-
172
+
175
173
  def x_offset_from_alignment
176
174
  case horizontal_alignment
177
175
  when :left then 0
@@ -179,7 +177,7 @@ module Cura
179
177
  when :right then (text_width - width).abs
180
178
  end
181
179
  end
182
-
180
+
183
181
  def y_offset_from_alignment
184
182
  case vertical_alignment
185
183
  when :top then 0
@@ -187,38 +185,36 @@ module Cura
187
185
  when :bottom then (text_height - height).abs
188
186
  end
189
187
  end
190
-
188
+
191
189
  protected
192
-
190
+
193
191
  # TODO: Just use a #alignment attribute and have a Cura::Alignment object?
194
192
  def convert_attributes(attributes={})
195
193
  attributes = super
196
-
194
+
197
195
  if attributes.key?(:alignment)
198
196
  alignment_attributes = attributes.delete(:alignment).to_h
199
-
197
+
200
198
  attributes[:horizontal_alignment] = alignment_attributes[:horizontal] if alignment_attributes.key?(:horizontal)
201
199
  attributes[:vertical_alignment] = alignment_attributes[:vertical] if alignment_attributes.key?(:vertical)
202
200
  end
203
-
201
+
204
202
  attributes
205
203
  end
206
-
204
+
207
205
  def convert_horizontal_alignment_attribute(value)
208
206
  value = value.to_sym
209
207
  raise ArgumentError, "must be :left, :center, or :right" unless [:left, :center, :right].include?(value)
210
-
208
+
211
209
  value
212
210
  end
213
-
211
+
214
212
  def convert_vertical_alignment_attribute(value)
215
213
  value = value.to_sym
216
214
  raise ArgumentError, "must be :top, :center, or :bottom" unless [:top, :center, :bottom].include?(value)
217
-
215
+
218
216
  value
219
217
  end
220
-
221
218
  end
222
-
223
219
  end
224
220
  end