cura 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/README.md +45 -21
- data/cura.gemspec +1 -1
- data/examples/hello_world/lib/hello_world.rb +10 -10
- data/examples/mruby-examples/mrbgem.rake +5 -6
- data/examples/todo_list/data.db +0 -0
- data/examples/todo_list/lib/todo_list/application.rb +24 -18
- data/lib/cura/adapter.rb +13 -20
- data/lib/cura/application.rb +47 -51
- data/lib/cura/attributes/has_ancestry.rb +4 -8
- data/lib/cura/attributes/has_application.rb +3 -7
- data/lib/cura/attributes/has_attributes.rb +1 -9
- data/lib/cura/attributes/has_children.rb +14 -20
- data/lib/cura/attributes/has_colors.rb +14 -18
- data/lib/cura/attributes/has_coordinates.rb +9 -15
- data/lib/cura/attributes/has_dimensions.rb +12 -18
- data/lib/cura/attributes/has_events.rb +10 -18
- data/lib/cura/attributes/has_focusability.rb +5 -11
- data/lib/cura/attributes/has_initialize.rb +1 -5
- data/lib/cura/attributes/has_offsets.rb +16 -20
- data/lib/cura/attributes/has_orientation.rb +12 -18
- data/lib/cura/attributes/has_relative_coordinates.rb +4 -8
- data/lib/cura/attributes/has_root.rb +18 -22
- data/lib/cura/attributes/has_side_attributes.rb +18 -24
- data/lib/cura/attributes/has_windows.rb +13 -19
- data/lib/cura/borders.rb +0 -4
- data/lib/cura/color.rb +84 -91
- data/lib/cura/component/base.rb +29 -33
- data/lib/cura/component/button.rb +10 -16
- data/lib/cura/component/group.rb +14 -18
- data/lib/cura/component/label.rb +44 -48
- data/lib/cura/component/listbox.rb +24 -28
- data/lib/cura/component/pack.rb +14 -18
- data/lib/cura/component/scrollbar.rb +41 -45
- data/lib/cura/component/textbox.rb +21 -25
- data/lib/cura/cursor.rb +15 -23
- data/lib/cura/error/base.rb +0 -3
- data/lib/cura/error/invalid_adapter.rb +1 -7
- data/lib/cura/error/invalid_application.rb +1 -7
- data/lib/cura/error/invalid_color.rb +1 -7
- data/lib/cura/error/invalid_component.rb +1 -7
- data/lib/cura/error/invalid_middleware.rb +1 -7
- data/lib/cura/event.rb +4 -8
- data/lib/cura/event/base.rb +17 -24
- data/lib/cura/event/click.rb +1 -6
- data/lib/cura/event/dispatcher.rb +20 -26
- data/lib/cura/event/focus.rb +1 -6
- data/lib/cura/event/handler.rb +16 -24
- data/lib/cura/event/key_down.rb +11 -17
- data/lib/cura/event/middleware/aimer/base.rb +4 -10
- data/lib/cura/event/middleware/aimer/dispatcher_target.rb +2 -8
- data/lib/cura/event/middleware/aimer/mouse_focus.rb +6 -11
- data/lib/cura/event/middleware/aimer/target_option.rb +4 -10
- data/lib/cura/event/middleware/base.rb +0 -4
- data/lib/cura/event/middleware/dispatch.rb +0 -4
- data/lib/cura/event/middleware/translator/base.rb +4 -10
- data/lib/cura/event/middleware/translator/mouse_click.rb +4 -8
- data/lib/cura/event/mouse.rb +5 -11
- data/lib/cura/event/mouse_button.rb +21 -27
- data/lib/cura/event/mouse_wheel_down.rb +1 -6
- data/lib/cura/event/mouse_wheel_up.rb +1 -6
- data/lib/cura/event/resize.rb +0 -4
- data/lib/cura/event/selected.rb +1 -6
- data/lib/cura/event/unfocus.rb +1 -6
- data/lib/cura/focus_controller.rb +19 -23
- data/lib/cura/key.rb +277 -283
- data/lib/cura/margins.rb +0 -4
- data/lib/cura/offsets.rb +14 -18
- data/lib/cura/padding.rb +0 -4
- data/lib/cura/pencil.rb +3 -7
- data/lib/cura/version.rb +1 -3
- data/lib/cura/window.rb +11 -16
- data/spec/cura/attributes/has_ancestry_spec.rb +39 -39
- data/spec/cura/attributes/has_application_spec.rb +20 -20
- data/spec/cura/attributes/has_attributes_spec.rb +26 -26
- data/spec/cura/attributes/has_children_spec.rb +54 -54
- data/spec/cura/attributes/has_colors_spec.rb +4 -4
- data/spec/cura/attributes/has_coordinates_spec.rb +4 -4
- data/spec/cura/attributes/has_dimensions_spec.rb +4 -4
- data/spec/cura/attributes/has_events_spec.rb +4 -4
- data/spec/cura/attributes/has_focusability_spec.rb +18 -18
- data/spec/cura/attributes/has_offsets_spec.rb +4 -4
- data/spec/cura/attributes/has_orientation_spec.rb +38 -38
- data/spec/cura/attributes/has_relative_coordinates_spec.rb +4 -4
- data/spec/cura/attributes/has_side_attributes_spec.rb +4 -4
- data/spec/spec_helper.rb +1 -1
- data/spec/support/shared_examples_for_attributes.rb +41 -41
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58ffd768a7cabdd176ee4d6063ce373aa1fb47a8
|
4
|
+
data.tar.gz: 8afa76729e3f1b62abc326be6a371905760caaa8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca3650bc0c20a6fd526a44ed4f1e89cadcbe5f21e30889078eaa1d0ffcfad999791e91629041bd90d217905182c03bea1ec4f7cce6fb2704807ca1a086105dd0
|
7
|
+
data.tar.gz: 8538379553f3090dad61c27d2f99569260106547d793a070ea48a3ee4b1a16bc61cc752f347bfc90e49ce3ef3859fa26031f3d917e35be5de1f9969fc2e3ff3e
|
data/README.md
CHANGED
@@ -1,19 +1,45 @@
|
|
1
1
|
# Cura
|
2
2
|
|
3
|
-
A component toolkit for creating
|
3
|
+
A component toolkit for creating user interfaces.
|
4
|
+
|
5
|
+
Cura can be used to create:
|
6
|
+
|
7
|
+
* Command-line interfaces (`CLI`).
|
8
|
+
* Text-based user interfaces (`TUI`).
|
9
|
+
* Graphical user interfaces (`GUI`).
|
10
|
+
* Read-Eval-Print-Loops (`REPL`).
|
11
|
+
* Extensions or functionality in current applications.
|
12
|
+
|
13
|
+
Cura is:
|
14
|
+
|
15
|
+
* Portable
|
16
|
+
* * No dependencies on external libraries or gems, besides adapters.
|
17
|
+
* * Does not use any IO or system-specific methods.
|
18
|
+
* * Can be used on any Ruby implementation, including MRuby (embeddable).
|
19
|
+
* Adaptable
|
20
|
+
* * Adapters exist for implementation and platform specific windowing, drawing, and terminal printing libraries.
|
21
|
+
* * Easily create adapters for any external library to implement a custom view tree for any application.
|
4
22
|
|
5
23
|
Cura provides:
|
6
24
|
|
25
|
+
* <s>Command system</s>
|
26
|
+
* * <s>Simple routing DSL.</s>
|
27
|
+
* * <s>Class based commands.</s>
|
28
|
+
* * <s>Windows and \*NIX style option parsing (optional, for use outside of CLI environments).</s>
|
29
|
+
* * <s>Usable in CLI, TUI, GUI, REPL, or any environment.</s>
|
7
30
|
* Component system
|
8
|
-
* *
|
9
|
-
* * Box model layouts
|
31
|
+
* * [View tree][view_tree] hierarchy.
|
32
|
+
* * Box model layouts.
|
33
|
+
* * <s>CCML, a XML user interface markup language for defining view trees</s>
|
10
34
|
* Event system
|
11
|
-
* *
|
12
|
-
* * Middleware
|
13
|
-
* *
|
14
|
-
* *
|
35
|
+
* * Dispatch event loop.
|
36
|
+
* * Middleware for modifying or translating events.
|
37
|
+
* * Defining events on any Ruby object.
|
38
|
+
* * Propagation using both the capturing and the bubbling models and ability to stop propagation.
|
15
39
|
* Adapter system
|
16
40
|
|
41
|
+
> Note: <s>Strikethrough</s> means not yet implemented (wait for 0.1.0)
|
42
|
+
|
17
43
|
## Install
|
18
44
|
|
19
45
|
### Bundler: `gem 'cura'`
|
@@ -29,7 +55,6 @@ Used for its libraries.
|
|
29
55
|
**Text-based User Interface (TUI)**
|
30
56
|
|
31
57
|
* [Termbox][ruby-termbox]
|
32
|
-
* [Termbox FFI][ruby-termbox-ffi]
|
33
58
|
* [Curses][ruby-curses]
|
34
59
|
|
35
60
|
**Graphical User Interface (GUI)**
|
@@ -67,18 +92,16 @@ Ruby FFI based adapters should also work in JRuby.
|
|
67
92
|
|
68
93
|
## Usage
|
69
94
|
|
70
|
-
> **NOTE:** The following is not functional yet. Move along...
|
71
|
-
|
72
95
|
```rb
|
73
96
|
require 'cura'
|
74
97
|
|
75
98
|
# Define our window
|
76
99
|
|
77
100
|
class MainWindow < Cura::Window
|
78
|
-
|
101
|
+
|
79
102
|
def initialize
|
80
103
|
super
|
81
|
-
|
104
|
+
|
82
105
|
@label = Cura::Label.new(
|
83
106
|
text: 'Hello, world!',
|
84
107
|
bold: true,
|
@@ -88,26 +111,26 @@ class MainWindow < Cura::Window
|
|
88
111
|
border: { size: 1, color: Cura::Color.red },
|
89
112
|
padding: 3
|
90
113
|
)
|
91
|
-
|
114
|
+
|
92
115
|
add_child( @label ) # Will mixin any adapter methods for Label
|
93
116
|
end
|
94
|
-
|
117
|
+
|
95
118
|
end
|
96
119
|
|
97
120
|
# Define our application and add our window
|
98
121
|
|
99
122
|
class Application < Cura::Application
|
100
|
-
|
123
|
+
|
101
124
|
def initialize
|
102
125
|
super
|
103
|
-
|
126
|
+
|
104
127
|
@window = MainWindow.new
|
105
|
-
|
128
|
+
|
106
129
|
add_window( @window )
|
107
|
-
|
130
|
+
|
108
131
|
@window.show # Note that in TUIs, only one window can be shown at once.
|
109
132
|
end
|
110
|
-
|
133
|
+
|
111
134
|
end
|
112
135
|
|
113
136
|
# Require any adapters
|
@@ -127,9 +150,9 @@ adapter_names = Cura::Adapter.all.collect(&:name)
|
|
127
150
|
adapter = loop do
|
128
151
|
puts "Choose one or type 'exit': #{ adapter_names.join(', ') }"
|
129
152
|
print '> '
|
130
|
-
|
153
|
+
|
131
154
|
answer = gets.downcase.strip
|
132
|
-
|
155
|
+
|
133
156
|
exit if answer == 'exit'
|
134
157
|
retry unless adapter_names.include?( answer.to_sym )
|
135
158
|
end
|
@@ -145,6 +168,7 @@ Copyright © 2015 Ryan Scott Lewis <ryan@rynet.us>.
|
|
145
168
|
|
146
169
|
The MIT License (MIT) - See LICENSE for further details.
|
147
170
|
|
171
|
+
[view_tree]: http://www.mit.edu/~6.005/fa14/classes/22-graphical-user-interfaces/
|
148
172
|
[ruby-termbox]: https://github.com/RyanScottLewis/ruby-cura-adapter-termbox
|
149
173
|
[ruby-termbox-ffi]: https://github.com/RyanScottLewis/ruby-cura-adapter-termbox-ffi
|
150
174
|
[ruby-curses]: https://github.com/RyanScottLewis/ruby-cura-adapter-curses
|
data/cura.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.version = Cura::VERSION
|
12
12
|
|
13
13
|
# Dependencies
|
14
|
-
s.add_development_dependency "builder", "~> 3.2.2" # TODO:
|
14
|
+
s.add_development_dependency "builder", "~> 3.2.2" # TODO: Needed? Reallllyyy?
|
15
15
|
|
16
16
|
# Pragmatically set variables
|
17
17
|
s.homepage = "http://github.com/RyanScottLewis/#{s.name}"
|
@@ -48,7 +48,7 @@ class HelloWorld < Cura::Application
|
|
48
48
|
# end
|
49
49
|
#
|
50
50
|
# end
|
51
|
-
|
51
|
+
|
52
52
|
on_event(:key_down) do |event|
|
53
53
|
stop if event.control? && event.name == :C # CTRL+C
|
54
54
|
end
|
@@ -61,10 +61,10 @@ class HelloWorld < Cura::Application
|
|
61
61
|
attr_reader :form_zip_textbox
|
62
62
|
attr_reader :form_submit_button
|
63
63
|
attr_reader :people_listbox
|
64
|
-
|
64
|
+
|
65
65
|
def initialize(attributes={})
|
66
66
|
super
|
67
|
-
|
67
|
+
|
68
68
|
@dispatcher.wait_time = 100 # Update every 100 milliseconds instead of waiting forever for events
|
69
69
|
|
70
70
|
window = Cura::Window.new
|
@@ -72,7 +72,7 @@ class HelloWorld < Cura::Application
|
|
72
72
|
|
73
73
|
pack = Cura::Component::Pack.new(width: window.width, height: window.height, fill: true)
|
74
74
|
window.add_child(pack)
|
75
|
-
|
75
|
+
|
76
76
|
label_header = Cura::Component::Label.new(text: "Cura", bold: true, underline: true, alignment: { horizontal: :center }, margin: { top: 1 })
|
77
77
|
pack.add_child(label_header)
|
78
78
|
|
@@ -155,13 +155,13 @@ class HelloWorld < Cura::Application
|
|
155
155
|
zip = application.form_zip_textbox.text
|
156
156
|
|
157
157
|
application.clear_form
|
158
|
-
|
158
|
+
|
159
159
|
label_text_segments = []
|
160
160
|
label_text_segments << "First: #{first}" unless first.empty?
|
161
161
|
label_text_segments << "Last: #{last}" unless last.empty?
|
162
162
|
label_text_segments << "Age: #{age}" unless age.empty?
|
163
163
|
label_text_segments << "ZIP: #{zip}" unless zip.empty?
|
164
|
-
|
164
|
+
|
165
165
|
label = Cura::Component::Label.new(text: label_text_segments.join(" - "))
|
166
166
|
application.people_listbox.add_child(label)
|
167
167
|
end
|
@@ -169,13 +169,13 @@ class HelloWorld < Cura::Application
|
|
169
169
|
|
170
170
|
people_label = Cura::Component::Label.new(text: "People:")
|
171
171
|
pack.add_child(people_label)
|
172
|
-
|
172
|
+
|
173
173
|
@people_listbox = Cura::Component::Listbox.new
|
174
174
|
@people_listbox.on_event(:key_down) { |event| delete_child(selected_child) if event.control? && event.name == :D }
|
175
175
|
|
176
176
|
pack.add_child(@people_listbox)
|
177
|
-
|
178
|
-
|
177
|
+
|
178
|
+
|
179
179
|
|
180
180
|
input_textbox.focus
|
181
181
|
end
|
@@ -197,5 +197,5 @@ class HelloWorld < Cura::Application
|
|
197
197
|
|
198
198
|
@form_first_name_textbox.focus
|
199
199
|
end
|
200
|
-
|
200
|
+
|
201
201
|
end
|
@@ -1,14 +1,13 @@
|
|
1
1
|
MRuby::Gem::Specification.new('cura-examples') do |spec|
|
2
|
-
|
2
|
+
|
3
3
|
spec.license = 'MIT'
|
4
4
|
spec.author = 'Ryan Scott Lewis'
|
5
5
|
spec.summary = ''
|
6
|
-
|
6
|
+
|
7
7
|
spec.rbfiles = []
|
8
|
-
|
9
|
-
# HelloWorld
|
8
|
+
|
10
9
|
spec.rbfiles << "#{dir}/../hello_world/lib/hello_world.rb"
|
11
|
-
|
10
|
+
|
12
11
|
spec.bins << "hello_world"
|
13
|
-
|
12
|
+
|
14
13
|
end
|
data/examples/todo_list/data.db
CHANGED
Binary file
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "pry"
|
2
|
+
|
1
3
|
require "cura"
|
2
4
|
|
3
5
|
require "todo_list/component/header"
|
@@ -5,50 +7,54 @@ require "todo_list/component/lists"
|
|
5
7
|
require "todo_list/component/list_items"
|
6
8
|
|
7
9
|
module TodoList
|
8
|
-
|
10
|
+
|
9
11
|
class Application < Cura::Application
|
10
|
-
|
12
|
+
|
11
13
|
on_event(:key_down) do |event|
|
12
14
|
stop if event.control? && event.name == :C # CTRL+C
|
13
15
|
end
|
14
|
-
|
16
|
+
|
15
17
|
attr_reader :list_items
|
16
|
-
|
18
|
+
|
17
19
|
def initialize(attributes={})
|
18
20
|
super
|
19
|
-
|
21
|
+
|
20
22
|
window = Cura::Window.new
|
21
|
-
|
23
|
+
|
22
24
|
add_window(window)
|
23
|
-
|
25
|
+
|
24
26
|
window.on_event(:key_down) do |event|
|
25
27
|
@focus_controller.index += 1 if event.control? && event.name == :F
|
26
28
|
@focus_controller.index -= 1 if event.control? && event.name == :B
|
29
|
+
if event.control? && event.name == :P
|
30
|
+
application.stop!
|
31
|
+
pry
|
32
|
+
end
|
27
33
|
end
|
28
|
-
|
34
|
+
|
29
35
|
#-
|
30
|
-
|
36
|
+
|
31
37
|
window.root = Cura::Component::Pack.new(width: window.width, height: window.height, fill: true)
|
32
|
-
|
38
|
+
|
33
39
|
header = Component::Header.new
|
34
40
|
window.add_child(header)
|
35
|
-
|
41
|
+
|
36
42
|
middle_pack = Cura::Component::Pack.new(height: window.height - 1, orientation: :horizontal, fill: true)
|
37
43
|
window.add_child(middle_pack)
|
38
|
-
|
44
|
+
|
39
45
|
sidebar = Component::Lists.new(width: 30, padding: 1)
|
40
46
|
middle_pack.add_child(sidebar)
|
41
|
-
|
47
|
+
|
42
48
|
@list_items = Component::ListItems.new(width: window.width - 30 - 4, padding: 1)
|
43
49
|
middle_pack.add_child(@list_items) # , expand: true, fill: true) # TODO
|
44
|
-
|
50
|
+
|
45
51
|
#-
|
46
|
-
|
52
|
+
|
47
53
|
@list_items.list = sidebar.listbox.selected_object if sidebar.listbox.children?
|
48
|
-
|
54
|
+
|
49
55
|
sidebar.create_list_textbox.focus
|
50
56
|
end
|
51
|
-
|
57
|
+
|
52
58
|
end
|
53
|
-
|
59
|
+
|
54
60
|
end
|
data/lib/cura/adapter.rb
CHANGED
@@ -4,64 +4,57 @@ if Kernel.respond_to?(:require)
|
|
4
4
|
end
|
5
5
|
|
6
6
|
module Cura
|
7
|
-
|
8
7
|
# The base class for adapters.
|
9
8
|
class Adapter
|
10
|
-
|
11
9
|
class << self
|
12
|
-
|
13
10
|
# The list of all Adapter subclasses.
|
14
11
|
#
|
15
12
|
# @return [Array]
|
16
13
|
def all
|
17
14
|
@all ||= []
|
18
15
|
end
|
19
|
-
|
16
|
+
|
20
17
|
def inherited(subclass)
|
21
18
|
all << subclass
|
22
19
|
end
|
23
|
-
|
20
|
+
|
24
21
|
def mixins
|
25
22
|
@mixins ||= {}
|
26
23
|
end
|
27
|
-
|
24
|
+
|
28
25
|
def mixin(value)
|
29
26
|
mixins.merge!(value.to_h)
|
30
27
|
end
|
31
|
-
|
32
28
|
end
|
33
|
-
|
29
|
+
|
34
30
|
include Attributes::HasInitialize
|
35
31
|
include Attributes::HasAttributes
|
36
|
-
|
32
|
+
|
37
33
|
def initialize(attributes={})
|
38
34
|
@setup = false
|
39
|
-
|
35
|
+
|
40
36
|
super
|
41
37
|
end
|
42
|
-
|
38
|
+
|
43
39
|
def setup
|
44
40
|
@setup = true
|
45
|
-
|
41
|
+
|
46
42
|
self.class.mixins.each { |type, mod| type.send(:include, mod) }
|
47
|
-
|
43
|
+
|
48
44
|
self
|
49
45
|
end
|
50
|
-
|
46
|
+
|
51
47
|
def setup?
|
52
48
|
@setup
|
53
49
|
end
|
54
|
-
|
50
|
+
|
55
51
|
def clear
|
56
|
-
|
57
52
|
end
|
58
|
-
|
53
|
+
|
59
54
|
def cleanup
|
60
55
|
@setup = false
|
61
|
-
|
56
|
+
|
62
57
|
self
|
63
58
|
end
|
64
|
-
|
65
59
|
end
|
66
|
-
|
67
60
|
end
|
data/lib/cura/application.rb
CHANGED
@@ -3,11 +3,11 @@ if Kernel.respond_to?(:require)
|
|
3
3
|
require "cura/attributes/has_windows"
|
4
4
|
require "cura/attributes/has_events"
|
5
5
|
require "cura/attributes/has_initialize"
|
6
|
-
|
6
|
+
|
7
7
|
require "cura/component/base"
|
8
|
-
|
8
|
+
|
9
9
|
require "cura/event/dispatcher"
|
10
|
-
|
10
|
+
|
11
11
|
require "cura/event/click"
|
12
12
|
require "cura/event/focus"
|
13
13
|
require "cura/event/unfocus"
|
@@ -18,121 +18,119 @@ if Kernel.respond_to?(:require)
|
|
18
18
|
require "cura/event/mouse_wheel_up"
|
19
19
|
require "cura/event/resize"
|
20
20
|
require "cura/event/selected"
|
21
|
-
|
21
|
+
|
22
22
|
require "cura/event/middleware/dispatch"
|
23
23
|
require "cura/event/middleware/aimer/mouse_focus"
|
24
24
|
require "cura/event/middleware/aimer/target_option"
|
25
25
|
require "cura/event/middleware/aimer/dispatcher_target"
|
26
26
|
require "cura/event/middleware/translator/mouse_click"
|
27
|
-
|
27
|
+
|
28
28
|
require "cura/error/invalid_adapter"
|
29
|
-
|
29
|
+
|
30
30
|
require "cura/cursor"
|
31
31
|
require "cura/pencil"
|
32
32
|
end
|
33
33
|
|
34
34
|
module Cura
|
35
|
-
|
36
35
|
# An application.
|
37
36
|
class Application
|
38
|
-
|
39
37
|
class << self
|
40
|
-
|
41
38
|
def run(attributes={})
|
42
39
|
new(attributes).run
|
43
40
|
end
|
44
|
-
|
45
41
|
end
|
46
|
-
|
42
|
+
|
47
43
|
include Attributes::HasInitialize
|
48
44
|
include Attributes::HasAttributes
|
49
45
|
include Attributes::HasWindows
|
50
46
|
include Attributes::HasEvents
|
51
|
-
|
47
|
+
|
52
48
|
def initialize(attributes={})
|
53
49
|
super
|
54
|
-
|
50
|
+
|
51
|
+
# setup_adapter
|
52
|
+
|
55
53
|
@running = false
|
56
54
|
@cursor = Cursor.new(application: self)
|
57
55
|
@pencil = Pencil.new
|
58
|
-
|
56
|
+
|
59
57
|
setup_adapter
|
60
58
|
setup_dispatcher
|
61
59
|
end
|
62
|
-
|
60
|
+
|
63
61
|
# @method adapter
|
64
62
|
# Get the adapter used for running this application.
|
65
63
|
#
|
66
64
|
# @return [Adapter]
|
67
|
-
|
65
|
+
|
68
66
|
# @method adapter=(adapter)
|
69
67
|
# Set the adapter used for running this application.
|
70
68
|
# This cannot be set after #run is used.
|
71
69
|
#
|
72
70
|
# @param [Adapter] value The new adapter.
|
73
71
|
# @return [Adapter]
|
74
|
-
|
72
|
+
|
75
73
|
attribute(:adapter) { |adapter| validate_adapter(adapter) }
|
76
|
-
|
74
|
+
|
77
75
|
# Get the text cursor.
|
78
76
|
#
|
79
77
|
# @return [Cursor]
|
80
78
|
attr_reader :cursor
|
81
|
-
|
79
|
+
|
82
80
|
# Get the pencil used for drawing.
|
83
81
|
#
|
84
82
|
# @return [Pencil]
|
85
83
|
attr_reader :pencil
|
86
|
-
|
84
|
+
|
87
85
|
# Get the event dispatcher.
|
88
86
|
#
|
89
87
|
# @return [Event::Dispatcher]
|
90
88
|
attr_reader :dispatcher
|
91
|
-
|
89
|
+
|
92
90
|
# Run this application.
|
93
91
|
#
|
94
92
|
# @return [Application] This application.
|
95
93
|
def run
|
96
94
|
run_event_loop
|
97
|
-
|
95
|
+
|
98
96
|
self
|
99
97
|
ensure
|
100
98
|
@adapter.cleanup
|
101
99
|
end
|
102
|
-
|
100
|
+
|
103
101
|
# Stop the application after the current run cycle.
|
104
102
|
#
|
105
103
|
# @return [Application] This application.
|
106
104
|
def stop
|
107
105
|
@running = false
|
108
|
-
|
106
|
+
|
109
107
|
self
|
110
108
|
end
|
111
|
-
|
109
|
+
|
112
110
|
# Stop the application immediently.
|
113
111
|
#
|
114
112
|
# @return [Application] This application.
|
115
113
|
def stop!
|
116
114
|
stop
|
117
115
|
@adapter.cleanup
|
118
|
-
|
116
|
+
|
119
117
|
self
|
120
118
|
end
|
121
|
-
|
119
|
+
|
122
120
|
# Check if this application is running.
|
123
121
|
#
|
124
122
|
# @return [Boolean]
|
125
123
|
def running?
|
126
124
|
@running
|
127
125
|
end
|
128
|
-
|
126
|
+
|
129
127
|
# Get the currently focused component.
|
130
128
|
#
|
131
129
|
# @return [Component::Base]
|
132
130
|
def focused
|
133
131
|
@dispatcher.target
|
134
132
|
end
|
135
|
-
|
133
|
+
|
136
134
|
# Set focus to a component.
|
137
135
|
#
|
138
136
|
# There can only be one component focused at a time within an application, if any.
|
@@ -142,14 +140,14 @@ module Cura
|
|
142
140
|
# @return [Component::Base]
|
143
141
|
def focus(component)
|
144
142
|
raise TypeError, "component must be nil or be a Cura::Component::Base" unless component.nil? || component.is_a?(Cura::Component::Base)
|
145
|
-
|
143
|
+
|
146
144
|
dispatch_event(:unfocus)
|
147
145
|
@dispatcher.target = component
|
148
146
|
dispatch_event(:focus)
|
149
|
-
|
147
|
+
|
150
148
|
component
|
151
149
|
end
|
152
|
-
|
150
|
+
|
153
151
|
# Dispatch an event.
|
154
152
|
#
|
155
153
|
# @param [#to_sym] event The name of the event class to create an instance of or an event instance.
|
@@ -159,16 +157,16 @@ module Cura
|
|
159
157
|
def dispatch_event(event, options={})
|
160
158
|
@dispatcher.dispatch_event(event, options)
|
161
159
|
end
|
162
|
-
|
160
|
+
|
163
161
|
# Add a window to this application.
|
164
162
|
#
|
165
163
|
# @param [Window] window
|
166
164
|
# @return [Window]
|
167
165
|
def add_window(window)
|
168
166
|
super
|
169
|
-
|
167
|
+
|
170
168
|
window.application = self
|
171
|
-
|
169
|
+
|
172
170
|
window
|
173
171
|
end
|
174
172
|
|
@@ -178,19 +176,19 @@ module Cura
|
|
178
176
|
def update
|
179
177
|
update_windows
|
180
178
|
cursor.update
|
181
|
-
|
179
|
+
|
182
180
|
self
|
183
181
|
end
|
184
|
-
|
182
|
+
|
185
183
|
# Draw all windows.
|
186
184
|
#
|
187
185
|
# @return [Application]
|
188
186
|
def draw
|
189
187
|
draw_windows
|
190
|
-
|
188
|
+
|
191
189
|
self
|
192
190
|
end
|
193
|
-
|
191
|
+
|
194
192
|
# Instance inspection.
|
195
193
|
#
|
196
194
|
# @return [String]
|
@@ -199,47 +197,45 @@ module Cura
|
|
199
197
|
end
|
200
198
|
|
201
199
|
protected
|
202
|
-
|
200
|
+
|
203
201
|
def setup_adapter
|
204
202
|
if @adapter.nil?
|
205
203
|
adapter_class ||= Adapter.all.first
|
206
204
|
raise Error::InvalidAdapter if adapter_class.nil?
|
207
|
-
|
205
|
+
|
208
206
|
@adapter = adapter_class.new
|
209
207
|
end
|
210
|
-
|
208
|
+
|
211
209
|
# TODO: If a class is given, run .new on it first
|
212
|
-
|
210
|
+
|
213
211
|
@adapter.setup
|
214
212
|
end
|
215
|
-
|
213
|
+
|
216
214
|
def setup_dispatcher
|
217
215
|
@dispatcher = Event::Dispatcher.new(application: self)
|
218
|
-
|
216
|
+
|
219
217
|
@dispatcher.middleware << Event::Middleware::Aimer::MouseFocus.new
|
220
218
|
@dispatcher.middleware << Event::Middleware::Aimer::TargetOption.new
|
221
219
|
@dispatcher.middleware << Event::Middleware::Aimer::DispatcherTarget.new
|
222
220
|
@dispatcher.middleware << Event::Middleware::Dispatch.new
|
223
221
|
@dispatcher.middleware << Event::Middleware::Translator::MouseClick.new
|
224
222
|
end
|
225
|
-
|
223
|
+
|
226
224
|
def validate_adapter(adapter)
|
227
225
|
# TODO: Raise error if ever set more than once
|
228
226
|
raise Error::InvalidAdapter unless adapter.is_a?(Cura::Adapter)
|
229
|
-
|
227
|
+
|
230
228
|
adapter
|
231
229
|
end
|
232
|
-
|
230
|
+
|
233
231
|
def run_event_loop
|
234
232
|
@running = true
|
235
|
-
|
233
|
+
|
236
234
|
while @running
|
237
235
|
update
|
238
236
|
draw
|
239
237
|
dispatcher.run
|
240
238
|
end
|
241
239
|
end
|
242
|
-
|
243
240
|
end
|
244
|
-
|
245
241
|
end
|