cura 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|