rugui 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +165 -0
- data/README +67 -0
- data/README.rdoc +67 -0
- data/Rakefile +56 -0
- data/VERSION.yml +4 -0
- data/bin/rugui +16 -0
- data/lib/rugui/base_controller.rb +194 -0
- data/lib/rugui/base_model.rb +22 -0
- data/lib/rugui/base_object.rb +73 -0
- data/lib/rugui/base_view.rb +302 -0
- data/lib/rugui/base_view_helper.rb +23 -0
- data/lib/rugui/configuration.rb +136 -0
- data/lib/rugui/framework_adapters/GTK.rb +233 -0
- data/lib/rugui/framework_adapters/Qt4.rb +171 -0
- data/lib/rugui/framework_adapters/base_framework_adapter.rb +90 -0
- data/lib/rugui/framework_adapters/framework_adapter_support.rb +35 -0
- data/lib/rugui/gem_builder.rb +21 -0
- data/lib/rugui/gem_dependency.rb +282 -0
- data/lib/rugui/initialize_hooks.rb +36 -0
- data/lib/rugui/initializer.rb +162 -0
- data/lib/rugui/log_support.rb +118 -0
- data/lib/rugui/observable_property_proxy.rb +73 -0
- data/lib/rugui/observable_property_support.rb +251 -0
- data/lib/rugui/plugin/loader.rb +77 -0
- data/lib/rugui/property_observer.rb +58 -0
- data/lib/rugui/signal_support.rb +57 -0
- data/lib/rugui/tasks/gems_application.rake +71 -0
- data/lib/rugui/tasks/rugui.rb +8 -0
- data/lib/rugui/tasks/rugui_framework.rb +4 -0
- data/lib/rugui/tasks/runner_application.rake +4 -0
- data/lib/rugui/tasks/spec_application.rake +64 -0
- data/lib/rugui/tasks/spec_framework.rake +27 -0
- data/lib/rugui/tasks/test_application.rake +77 -0
- data/lib/rugui/vendor_gem_source_index.rb +140 -0
- data/lib/rugui/version.rb +9 -0
- data/lib/rugui.rb +37 -0
- data/spec/framework/base_controller_spec.rb +48 -0
- data/spec/framework/base_model_spec.rb +13 -0
- data/spec/framework/base_view_helper_spec.rb +13 -0
- data/spec/framework/base_view_spec.rb +92 -0
- data/spec/framework/log_support_spec.rb +16 -0
- data/spec/framework/observable_property_proxy_spec.rb +67 -0
- data/spec/framework/observable_property_support_spec.rb +283 -0
- data/spec/framework/property_observer_spec.rb +88 -0
- data/spec/helpers/controllers.rb +29 -0
- data/spec/helpers/initialize_hooks_helper.rb +18 -0
- data/spec/helpers/models.rb +9 -0
- data/spec/helpers/observables.rb +210 -0
- data/spec/helpers/view_helpers.rb +9 -0
- data/spec/helpers/views.rb +72 -0
- data/spec/rcov.opts +1 -0
- data/spec/resource_files/my_other_view.glade +46 -0
- data/spec/resource_files/my_view.glade +46 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +15 -0
- metadata +149 -0
data/LICENSE
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
GNU LESSER GENERAL PUBLIC LICENSE
|
2
|
+
Version 3, 29 June 2007
|
3
|
+
|
4
|
+
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
5
|
+
Everyone is permitted to copy and distribute verbatim copies
|
6
|
+
of this license document, but changing it is not allowed.
|
7
|
+
|
8
|
+
|
9
|
+
This version of the GNU Lesser General Public License incorporates
|
10
|
+
the terms and conditions of version 3 of the GNU General Public
|
11
|
+
License, supplemented by the additional permissions listed below.
|
12
|
+
|
13
|
+
0. Additional Definitions.
|
14
|
+
|
15
|
+
As used herein, "this License" refers to version 3 of the GNU Lesser
|
16
|
+
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
17
|
+
General Public License.
|
18
|
+
|
19
|
+
"The Library" refers to a covered work governed by this License,
|
20
|
+
other than an Application or a Combined Work as defined below.
|
21
|
+
|
22
|
+
An "Application" is any work that makes use of an interface provided
|
23
|
+
by the Library, but which is not otherwise based on the Library.
|
24
|
+
Defining a subclass of a class defined by the Library is deemed a mode
|
25
|
+
of using an interface provided by the Library.
|
26
|
+
|
27
|
+
A "Combined Work" is a work produced by combining or linking an
|
28
|
+
Application with the Library. The particular version of the Library
|
29
|
+
with which the Combined Work was made is also called the "Linked
|
30
|
+
Version".
|
31
|
+
|
32
|
+
The "Minimal Corresponding Source" for a Combined Work means the
|
33
|
+
Corresponding Source for the Combined Work, excluding any source code
|
34
|
+
for portions of the Combined Work that, considered in isolation, are
|
35
|
+
based on the Application, and not on the Linked Version.
|
36
|
+
|
37
|
+
The "Corresponding Application Code" for a Combined Work means the
|
38
|
+
object code and/or source code for the Application, including any data
|
39
|
+
and utility programs needed for reproducing the Combined Work from the
|
40
|
+
Application, but excluding the System Libraries of the Combined Work.
|
41
|
+
|
42
|
+
1. Exception to Section 3 of the GNU GPL.
|
43
|
+
|
44
|
+
You may convey a covered work under sections 3 and 4 of this License
|
45
|
+
without being bound by section 3 of the GNU GPL.
|
46
|
+
|
47
|
+
2. Conveying Modified Versions.
|
48
|
+
|
49
|
+
If you modify a copy of the Library, and, in your modifications, a
|
50
|
+
facility refers to a function or data to be supplied by an Application
|
51
|
+
that uses the facility (other than as an argument passed when the
|
52
|
+
facility is invoked), then you may convey a copy of the modified
|
53
|
+
version:
|
54
|
+
|
55
|
+
a) under this License, provided that you make a good faith effort to
|
56
|
+
ensure that, in the event an Application does not supply the
|
57
|
+
function or data, the facility still operates, and performs
|
58
|
+
whatever part of its purpose remains meaningful, or
|
59
|
+
|
60
|
+
b) under the GNU GPL, with none of the additional permissions of
|
61
|
+
this License applicable to that copy.
|
62
|
+
|
63
|
+
3. Object Code Incorporating Material from Library Header Files.
|
64
|
+
|
65
|
+
The object code form of an Application may incorporate material from
|
66
|
+
a header file that is part of the Library. You may convey such object
|
67
|
+
code under terms of your choice, provided that, if the incorporated
|
68
|
+
material is not limited to numerical parameters, data structure
|
69
|
+
layouts and accessors, or small macros, inline functions and templates
|
70
|
+
(ten or fewer lines in length), you do both of the following:
|
71
|
+
|
72
|
+
a) Give prominent notice with each copy of the object code that the
|
73
|
+
Library is used in it and that the Library and its use are
|
74
|
+
covered by this License.
|
75
|
+
|
76
|
+
b) Accompany the object code with a copy of the GNU GPL and this license
|
77
|
+
document.
|
78
|
+
|
79
|
+
4. Combined Works.
|
80
|
+
|
81
|
+
You may convey a Combined Work under terms of your choice that,
|
82
|
+
taken together, effectively do not restrict modification of the
|
83
|
+
portions of the Library contained in the Combined Work and reverse
|
84
|
+
engineering for debugging such modifications, if you also do each of
|
85
|
+
the following:
|
86
|
+
|
87
|
+
a) Give prominent notice with each copy of the Combined Work that
|
88
|
+
the Library is used in it and that the Library and its use are
|
89
|
+
covered by this License.
|
90
|
+
|
91
|
+
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
92
|
+
document.
|
93
|
+
|
94
|
+
c) For a Combined Work that displays copyright notices during
|
95
|
+
execution, include the copyright notice for the Library among
|
96
|
+
these notices, as well as a reference directing the user to the
|
97
|
+
copies of the GNU GPL and this license document.
|
98
|
+
|
99
|
+
d) Do one of the following:
|
100
|
+
|
101
|
+
0) Convey the Minimal Corresponding Source under the terms of this
|
102
|
+
License, and the Corresponding Application Code in a form
|
103
|
+
suitable for, and under terms that permit, the user to
|
104
|
+
recombine or relink the Application with a modified version of
|
105
|
+
the Linked Version to produce a modified Combined Work, in the
|
106
|
+
manner specified by section 6 of the GNU GPL for conveying
|
107
|
+
Corresponding Source.
|
108
|
+
|
109
|
+
1) Use a suitable shared library mechanism for linking with the
|
110
|
+
Library. A suitable mechanism is one that (a) uses at run time
|
111
|
+
a copy of the Library already present on the user's computer
|
112
|
+
system, and (b) will operate properly with a modified version
|
113
|
+
of the Library that is interface-compatible with the Linked
|
114
|
+
Version.
|
115
|
+
|
116
|
+
e) Provide Installation Information, but only if you would otherwise
|
117
|
+
be required to provide such information under section 6 of the
|
118
|
+
GNU GPL, and only to the extent that such information is
|
119
|
+
necessary to install and execute a modified version of the
|
120
|
+
Combined Work produced by recombining or relinking the
|
121
|
+
Application with a modified version of the Linked Version. (If
|
122
|
+
you use option 4d0, the Installation Information must accompany
|
123
|
+
the Minimal Corresponding Source and Corresponding Application
|
124
|
+
Code. If you use option 4d1, you must provide the Installation
|
125
|
+
Information in the manner specified by section 6 of the GNU GPL
|
126
|
+
for conveying Corresponding Source.)
|
127
|
+
|
128
|
+
5. Combined Libraries.
|
129
|
+
|
130
|
+
You may place library facilities that are a work based on the
|
131
|
+
Library side by side in a single library together with other library
|
132
|
+
facilities that are not Applications and are not covered by this
|
133
|
+
License, and convey such a combined library under terms of your
|
134
|
+
choice, if you do both of the following:
|
135
|
+
|
136
|
+
a) Accompany the combined library with a copy of the same work based
|
137
|
+
on the Library, uncombined with any other library facilities,
|
138
|
+
conveyed under the terms of this License.
|
139
|
+
|
140
|
+
b) Give prominent notice with the combined library that part of it
|
141
|
+
is a work based on the Library, and explaining where to find the
|
142
|
+
accompanying uncombined form of the same work.
|
143
|
+
|
144
|
+
6. Revised Versions of the GNU Lesser General Public License.
|
145
|
+
|
146
|
+
The Free Software Foundation may publish revised and/or new versions
|
147
|
+
of the GNU Lesser General Public License from time to time. Such new
|
148
|
+
versions will be similar in spirit to the present version, but may
|
149
|
+
differ in detail to address new problems or concerns.
|
150
|
+
|
151
|
+
Each version is given a distinguishing version number. If the
|
152
|
+
Library as you received it specifies that a certain numbered version
|
153
|
+
of the GNU Lesser General Public License "or any later version"
|
154
|
+
applies to it, you have the option of following the terms and
|
155
|
+
conditions either of that published version or of any later version
|
156
|
+
published by the Free Software Foundation. If the Library as you
|
157
|
+
received it does not specify a version number of the GNU Lesser
|
158
|
+
General Public License, you may choose any version of the GNU Lesser
|
159
|
+
General Public License ever published by the Free Software Foundation.
|
160
|
+
|
161
|
+
If the Library as you received it specifies that a proxy can decide
|
162
|
+
whether future versions of the GNU Lesser General Public License shall
|
163
|
+
apply, that proxy's public statement of acceptance of any version is
|
164
|
+
permanent authorization for you to choose that version for the
|
165
|
+
Library.
|
data/README
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
= RuGUI
|
2
|
+
|
3
|
+
RuGUI is a framework which aims to help building desktop applications. RuGUI was
|
4
|
+
mostly inspired by the *Ruby on Rails* framework, taking most of its features
|
5
|
+
from it.
|
6
|
+
|
7
|
+
RuGUI approach is to provide a MVC design for the application, separating
|
8
|
+
business logic from application presentation, making it easy to maintain and
|
9
|
+
evolve the application.
|
10
|
+
|
11
|
+
Also, a Observer/Observable pattern is implemented so that you can define
|
12
|
+
observable properties in your model which are observed by controllers that
|
13
|
+
should react to changes in the model. This makes the application code even more
|
14
|
+
clean when dealing with applications that have multiple data entry points. For
|
15
|
+
example, when receiving data from a network one may update a value in a model,
|
16
|
+
and the controller will update all needed widgets (progress bars, labels, status
|
17
|
+
bar, etc).
|
18
|
+
|
19
|
+
The initial framework was based on the great Ruby/GTK API, but RuGUI has evolved
|
20
|
+
so that you may use other GUI frameworks with it. Since version 1.1.x it has
|
21
|
+
placed all functionality specific for GTK wrapped in a framework adapter. This
|
22
|
+
has made it possible to write a QT adapter and now it is possible to use all of
|
23
|
+
the RuGUI features together with QT. As the framework evolve other framework
|
24
|
+
adapters may be written, enabling the use of RuGUI with any other GUI frameworks.
|
25
|
+
|
26
|
+
== Instalation
|
27
|
+
|
28
|
+
Download the source from:
|
29
|
+
|
30
|
+
http://github.com/intelitiva/rugui/tree/master
|
31
|
+
|
32
|
+
Next, build and install the gem:
|
33
|
+
|
34
|
+
gem build rugui.gemspec
|
35
|
+
gem install rugui-X.X.X.gem
|
36
|
+
|
37
|
+
To check if the installation was successful type in a console:
|
38
|
+
|
39
|
+
rugui -v
|
40
|
+
|
41
|
+
== Dependencies
|
42
|
+
|
43
|
+
RuGUI depends, of course, on the Ruby binding for the GUI framework that you'll
|
44
|
+
use. It is known to work on Linux and Windows plataforms. Currently it depends
|
45
|
+
on the ActiveSupport gem, which can be installed by:
|
46
|
+
|
47
|
+
gem install activesupport
|
48
|
+
|
49
|
+
To be able to generate applications and controllers/models/views, you will need
|
50
|
+
the rubigen gem, which can be installed by:
|
51
|
+
|
52
|
+
gem install rubigen
|
53
|
+
|
54
|
+
== Generating an Application
|
55
|
+
|
56
|
+
To generate an application, go to the directory where you want to create the
|
57
|
+
application and type:
|
58
|
+
|
59
|
+
rugui <app_name>
|
60
|
+
|
61
|
+
For more options type:
|
62
|
+
|
63
|
+
rugui -h
|
64
|
+
|
65
|
+
== More info
|
66
|
+
|
67
|
+
http://rugui.org
|
data/README.rdoc
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
= RuGUI
|
2
|
+
|
3
|
+
RuGUI is a framework which aims to help building desktop applications. RuGUI was
|
4
|
+
mostly inspired by the *Ruby on Rails* framework, taking most of its features
|
5
|
+
from it.
|
6
|
+
|
7
|
+
RuGUI approach is to provide a MVC design for the application, separating
|
8
|
+
business logic from application presentation, making it easy to maintain and
|
9
|
+
evolve the application.
|
10
|
+
|
11
|
+
Also, a Observer/Observable pattern is implemented so that you can define
|
12
|
+
observable properties in your model which are observed by controllers that
|
13
|
+
should react to changes in the model. This makes the application code even more
|
14
|
+
clean when dealing with applications that have multiple data entry points. For
|
15
|
+
example, when receiving data from a network one may update a value in a model,
|
16
|
+
and the controller will update all needed widgets (progress bars, labels, status
|
17
|
+
bar, etc).
|
18
|
+
|
19
|
+
The initial framework was based on the great Ruby/GTK API, but RuGUI has evolved
|
20
|
+
so that you may use other GUI frameworks with it. Since version 1.1.x it has
|
21
|
+
placed all functionality specific for GTK wrapped in a framework adapter. This
|
22
|
+
has made it possible to write a QT adapter and now it is possible to use all of
|
23
|
+
the RuGUI features together with QT. As the framework evolve other framework
|
24
|
+
adapters may be written, enabling the use of RuGUI with any other GUI frameworks.
|
25
|
+
|
26
|
+
== Instalation
|
27
|
+
|
28
|
+
Download the source from:
|
29
|
+
|
30
|
+
http://github.com/intelitiva/rugui/tree/master
|
31
|
+
|
32
|
+
Next, build and install the gem:
|
33
|
+
|
34
|
+
gem build rugui.gemspec
|
35
|
+
gem install rugui-X.X.X.gem
|
36
|
+
|
37
|
+
To check if the installation was successful type in a console:
|
38
|
+
|
39
|
+
rugui -v
|
40
|
+
|
41
|
+
== Dependencies
|
42
|
+
|
43
|
+
RuGUI depends, of course, on the Ruby binding for the GUI framework that you'll
|
44
|
+
use. It is known to work on Linux and Windows plataforms. Currently it depends
|
45
|
+
on the ActiveSupport gem, which can be installed by:
|
46
|
+
|
47
|
+
gem install activesupport
|
48
|
+
|
49
|
+
To be able to generate applications and controllers/models/views, you will need
|
50
|
+
the rubigen gem, which can be installed by:
|
51
|
+
|
52
|
+
gem install rubigen
|
53
|
+
|
54
|
+
== Generating an Application
|
55
|
+
|
56
|
+
To generate an application, go to the directory where you want to create the
|
57
|
+
application and type:
|
58
|
+
|
59
|
+
rugui <app_name>
|
60
|
+
|
61
|
+
For more options type:
|
62
|
+
|
63
|
+
rugui -h
|
64
|
+
|
65
|
+
== More info
|
66
|
+
|
67
|
+
http://rugui.org
|
data/Rakefile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
#
|
2
|
+
# To change this template, choose Tools | Templates
|
3
|
+
# and open the template in the editor.
|
4
|
+
|
5
|
+
|
6
|
+
require 'rake'
|
7
|
+
require 'rake/testtask'
|
8
|
+
require 'rake/rdoctask'
|
9
|
+
|
10
|
+
require 'rubygems'
|
11
|
+
require 'rugui/tasks/rugui_framework'
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gemspec|
|
16
|
+
gemspec.name = "rugui"
|
17
|
+
gemspec.summary = "A simple MVC framework for RubyGTK."
|
18
|
+
gemspec.email = ["vicente.mundim@intelitiva.com", "felipe.mesquita@intelitiva.com", "claudio.escudero@intelitiva.com"]
|
19
|
+
gemspec.homepage = "http://rugui.org"
|
20
|
+
gemspec.description = "A simple MVC framework for RubyGTK."
|
21
|
+
gemspec.authors = ["Vicente Mundim", "Felipe Mesquita", "Claudio Escudero"]
|
22
|
+
gemspec.add_dependency(%q<activesupport>, [">= 2.1.1"])
|
23
|
+
gemspec.add_dependency(%q<rubigen>, [">= 1.5.1"])
|
24
|
+
gemspec.version = "1.2.0"
|
25
|
+
gemspec.date = %q{2009-04-01}
|
26
|
+
gemspec.rubyforge_project = "rugui"
|
27
|
+
end
|
28
|
+
rescue LoadError
|
29
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
require 'rake/contrib/sshpublisher'
|
34
|
+
namespace :rubyforge do
|
35
|
+
|
36
|
+
desc "Release gem and RDoc documentation to RubyForge"
|
37
|
+
task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
|
38
|
+
|
39
|
+
namespace :release do
|
40
|
+
desc "Publish RDoc to RubyForge."
|
41
|
+
task :docs => [:rdoc] do
|
42
|
+
config = YAML.load(
|
43
|
+
File.read(File.expand_path('~/.rubyforge/user-config.yml'))
|
44
|
+
)
|
45
|
+
|
46
|
+
host = "#{config['username']}@rubyforge.org"
|
47
|
+
remote_dir = "/var/www/gforge-projects/rugui"
|
48
|
+
local_dir = 'rdoc'
|
49
|
+
|
50
|
+
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
rescue LoadError
|
55
|
+
puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
|
56
|
+
end
|
data/VERSION.yml
ADDED
data/bin/rugui
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rubigen'
|
5
|
+
|
6
|
+
if %w(-v --version).include? ARGV.first
|
7
|
+
require 'rugui/version'
|
8
|
+
puts "RuGUI #{RuGUI::VERSION::STRING}"
|
9
|
+
exit(0)
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'rubigen/scripts/generate'
|
13
|
+
source = RubiGen::PathSource.new(:application, File.join(File.dirname(__FILE__), "../rugui_generators"))
|
14
|
+
RubiGen::Base.reset_sources
|
15
|
+
RubiGen::Base.append_sources source
|
16
|
+
RubiGen::Scripts::Generate.new.run(ARGV, :generator => 'rugui')
|
@@ -0,0 +1,194 @@
|
|
1
|
+
module RuGUI
|
2
|
+
#
|
3
|
+
# Base class for all controllers.
|
4
|
+
#
|
5
|
+
class BaseController < BaseObject
|
6
|
+
include RuGUI::PropertyObserver
|
7
|
+
include RuGUI::LogSupport
|
8
|
+
include RuGUI::SignalSupport
|
9
|
+
|
10
|
+
attr_accessor :models
|
11
|
+
attr_accessor :views
|
12
|
+
attr_accessor :controllers
|
13
|
+
attr_accessor :parent_controller
|
14
|
+
|
15
|
+
def initialize(parent_controller = nil)
|
16
|
+
@models = {}
|
17
|
+
@views = {}
|
18
|
+
@controllers = {}
|
19
|
+
|
20
|
+
if parent_controller.nil?
|
21
|
+
@parent_controller = self
|
22
|
+
else
|
23
|
+
@parent_controller = parent_controller
|
24
|
+
end
|
25
|
+
|
26
|
+
setup_models
|
27
|
+
setup_views
|
28
|
+
setup_controllers
|
29
|
+
end
|
30
|
+
|
31
|
+
# This is included here so that the initialize method is properly updated.
|
32
|
+
include RuGUI::InitializeHooks
|
33
|
+
|
34
|
+
# Returns the framework_adapter for this class.
|
35
|
+
def framework_adapter
|
36
|
+
framework_adapter_for('BaseController')
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Registers a model for this controller.
|
41
|
+
#
|
42
|
+
# If the given model is a string or symbol, it will be camelized and
|
43
|
+
# a new instance of the model class will be created.
|
44
|
+
#
|
45
|
+
def register_model(model, name = nil)
|
46
|
+
model = create_instance(model) if model.is_a?(String) or model.is_a?(Symbol)
|
47
|
+
name ||= model.class.to_s.underscore
|
48
|
+
model.register_observer(self, name)
|
49
|
+
@models[name.to_sym] = model
|
50
|
+
create_model_attribute_reader(name)
|
51
|
+
|
52
|
+
model.post_registration(self)
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Registers a view for this controller.
|
57
|
+
#
|
58
|
+
# If the given view is a string or symbol, it will be camelized and a new
|
59
|
+
# instance of the view class will be created.
|
60
|
+
#
|
61
|
+
def register_view(view, name = nil)
|
62
|
+
view = create_instance(view) if view.is_a?(String) or view.is_a?(Symbol)
|
63
|
+
name ||= view.class.to_s.underscore
|
64
|
+
view.register_controller(self)
|
65
|
+
@views[name.to_sym] = view
|
66
|
+
create_view_attribute_reader(name)
|
67
|
+
|
68
|
+
view.post_registration(self)
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# Registers a child controller for this controller.
|
73
|
+
#
|
74
|
+
# If the given controller is a string or symbol, it will be camelized and
|
75
|
+
# a new instance of the controller class will be created.
|
76
|
+
#
|
77
|
+
def register_controller(controller, name = nil)
|
78
|
+
controller = create_instance(controller, self) if controller.is_a?(String) or controller.is_a?(Symbol)
|
79
|
+
name ||= controller.class.to_s.underscore
|
80
|
+
controller.parent_controller = self
|
81
|
+
@controllers[name.to_sym] = controller
|
82
|
+
create_controller_attribute_reader(name)
|
83
|
+
|
84
|
+
controller.post_registration
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Called after the controller is registered in another one.
|
89
|
+
#
|
90
|
+
def post_registration
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns the main controller instance.
|
94
|
+
#
|
95
|
+
# This is an useful way to quickly access the main controller from any other
|
96
|
+
# controller. Since applications may have only one main controller and it is
|
97
|
+
# always the 'root' of the tree of controllers, this provides indirect
|
98
|
+
# access to any other controller in the application.
|
99
|
+
#
|
100
|
+
# NOTE: The main controller is cached, so that subsequent calls are faster.
|
101
|
+
def main_controller
|
102
|
+
@main_controller ||= find_main_controller
|
103
|
+
end
|
104
|
+
|
105
|
+
protected
|
106
|
+
#
|
107
|
+
# Subclasses should reimplement this to register models.
|
108
|
+
#
|
109
|
+
def setup_models
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Subclasses should reimplement this to register views.
|
114
|
+
#
|
115
|
+
def setup_views
|
116
|
+
end
|
117
|
+
|
118
|
+
#
|
119
|
+
# Subclasses should reimplement this to register controllers.
|
120
|
+
#
|
121
|
+
def setup_controllers
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
def create_instance(klass_name, *args)
|
126
|
+
klass_name.to_s.camelize.constantize.new(*args)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Creates an attribute reader for the model.
|
130
|
+
def create_model_attribute_reader(name)
|
131
|
+
create_attribute_reader(:models, name)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Creates an attribute reader for the view.
|
135
|
+
def create_view_attribute_reader(name)
|
136
|
+
create_attribute_reader(:views, name)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Creates an attribute reader for the controller.
|
140
|
+
def create_controller_attribute_reader(name)
|
141
|
+
create_attribute_reader(:controllers, name)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Creates an attribute reader for the some entity.
|
145
|
+
def create_attribute_reader(entity, name)
|
146
|
+
self.class.class_eval <<-class_eval
|
147
|
+
def #{name}
|
148
|
+
@#{entity}[:#{name}]
|
149
|
+
end
|
150
|
+
class_eval
|
151
|
+
end
|
152
|
+
|
153
|
+
# Navigates through the controllers hierarchy trying to find the main
|
154
|
+
# controller (i.e., a class that extends RuGUI::BaseMainController).
|
155
|
+
def find_main_controller
|
156
|
+
if self.parent_controller.is_a?(RuGUI::BaseMainController)
|
157
|
+
self.parent_controller
|
158
|
+
elsif self.parent_controller == self
|
159
|
+
return nil
|
160
|
+
else
|
161
|
+
self.parent_controller.main_controller
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
#
|
167
|
+
# A base class for main controllers.
|
168
|
+
#
|
169
|
+
# Provides a method for running the application as well as a method to quit.
|
170
|
+
#
|
171
|
+
class BaseMainController < BaseController
|
172
|
+
# Returns the framework_adapter for this class.
|
173
|
+
def framework_adapter
|
174
|
+
framework_adapter_for('BaseMainController')
|
175
|
+
end
|
176
|
+
|
177
|
+
#
|
178
|
+
# Runs the application.
|
179
|
+
#
|
180
|
+
def run
|
181
|
+
logger.info "Starting the application through #{self.class.name}."
|
182
|
+
self.framework_adapter.run
|
183
|
+
end
|
184
|
+
|
185
|
+
#
|
186
|
+
# Exits from the application.
|
187
|
+
#
|
188
|
+
def quit
|
189
|
+
logger.info "Exiting the application through #{self.class.name}."
|
190
|
+
self.framework_adapter.quit
|
191
|
+
logger.info "Application finished."
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RuGUI
|
2
|
+
class BaseModel < BaseObject
|
3
|
+
include RuGUI::ObservablePropertySupport
|
4
|
+
include RuGUI::LogSupport
|
5
|
+
|
6
|
+
def initialize(observable_properties_values = {})
|
7
|
+
initialize_observable_property_support(observable_properties_values)
|
8
|
+
end
|
9
|
+
|
10
|
+
# This is included here so that the initialize method is properly updated.
|
11
|
+
include RuGUI::InitializeHooks
|
12
|
+
|
13
|
+
# Returns the framework_adapter for this class.
|
14
|
+
def framework_adapter
|
15
|
+
framework_adapter_for('BaseModel')
|
16
|
+
end
|
17
|
+
|
18
|
+
# Called after the model is registered in a controller.
|
19
|
+
def post_registration(controller)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module RuGUI
|
2
|
+
# A base object for all RuGUI classes.
|
3
|
+
#
|
4
|
+
# It mainly defines customized inspect which will display only some of the
|
5
|
+
# instance variables, avoiding excessive overhead when generating tracebacks.
|
6
|
+
class BaseObject
|
7
|
+
# All RuGUI objects can have access to framework adapters.
|
8
|
+
include RuGUI::FrameworkAdapters::FrameworkAdapterSupport
|
9
|
+
|
10
|
+
# Returns a string containing a human-readable representation of obj.
|
11
|
+
#
|
12
|
+
# It will display each instance variable value unless it is also a
|
13
|
+
# RuGUI::BaseObject.
|
14
|
+
def inspect
|
15
|
+
instance_variables_values = instance_variables.collect do |instance_variable_name|
|
16
|
+
instance_variable_value = instance_variable_get(instance_variable_name)
|
17
|
+
inspected_instance_variable_value = nil
|
18
|
+
if instance_variable_value.is_a?(RuGUI::BaseObject)
|
19
|
+
inspected_instance_variable_value = inspect_base_object(instance_variable_value)
|
20
|
+
elsif instance_variable_value.is_a?(Array)
|
21
|
+
inspected_instance_variable_value = inspect_array(instance_variable_value)
|
22
|
+
elsif instance_variable_value.is_a?(Hash)
|
23
|
+
inspected_instance_variable_value = inspect_hash(instance_variable_value)
|
24
|
+
else
|
25
|
+
inspected_instance_variable_value = instance_variable_value.inspect
|
26
|
+
end
|
27
|
+
|
28
|
+
"#{instance_variable_name}=#{inspected_instance_variable_value}"
|
29
|
+
end
|
30
|
+
|
31
|
+
"#<#{self.class.name} #{instance_variables_values.join(" ")}>"
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
def inspect_base_object(base_object_value)
|
36
|
+
"#<#{base_object_value.class.inspect}>"
|
37
|
+
end
|
38
|
+
|
39
|
+
def inspect_array(array_value)
|
40
|
+
array_values = array_value.collect do |item|
|
41
|
+
if item.is_a?(RuGUI::BaseObject)
|
42
|
+
inspect_base_object(item)
|
43
|
+
elsif item.is_a?(Array)
|
44
|
+
inspect_array(item)
|
45
|
+
elsif item.is_a?(Hash)
|
46
|
+
inspect_hash(item)
|
47
|
+
else
|
48
|
+
item.inspect
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
"[#{array_values.join(', ')}]"
|
53
|
+
end
|
54
|
+
|
55
|
+
def inspect_hash(hash_value)
|
56
|
+
hash_values = hash_value.collect do |key, value|
|
57
|
+
inspected_value = nil
|
58
|
+
if value.is_a?(RuGUI::BaseObject)
|
59
|
+
inspected_value = inspect_base_object(value)
|
60
|
+
elsif value.is_a?(Array)
|
61
|
+
inspected_value = inspect_array(value)
|
62
|
+
elsif value.is_a?(Hash)
|
63
|
+
inspected_value = inspect_hash(value)
|
64
|
+
else
|
65
|
+
inspected_value = value.inspect
|
66
|
+
end
|
67
|
+
"#{key.inspect}=>#{inspected_value}"
|
68
|
+
end
|
69
|
+
|
70
|
+
"{#{hash_values.join(', ')}}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|