ruby_mvc 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +14 -0
- data/lib/ruby_mvc.rb +3 -1
- data/lib/ruby_mvc/application.rb +52 -2
- data/lib/ruby_mvc/controllers.rb +28 -0
- data/lib/ruby_mvc/controllers/action.rb +93 -0
- data/lib/ruby_mvc/controllers/action_group.rb +70 -0
- data/lib/ruby_mvc/controllers/app_controller.rb +4 -2
- data/lib/ruby_mvc/controllers/rails_controller.rb +2 -0
- data/lib/ruby_mvc/models.rb +2 -0
- data/lib/ruby_mvc/models/ar_table_model.rb +133 -0
- data/lib/ruby_mvc/models/array_table_model.rb +81 -13
- data/lib/ruby_mvc/models/keyed_array_table_model.rb +1 -1
- data/lib/ruby_mvc/models/model.rb +129 -0
- data/lib/ruby_mvc/models/table_model.rb +107 -10
- data/lib/ruby_mvc/models/view_model_template.rb +140 -0
- data/lib/ruby_mvc/renderers.rb +1 -0
- data/lib/ruby_mvc/renderers/html4_table_model_renderer.rb +7 -6
- data/lib/ruby_mvc/renderers/hyperlink_cell_renderer.rb +47 -0
- data/lib/ruby_mvc/toolkit.rb +5 -1
- data/lib/ruby_mvc/toolkit/browser_history.rb +115 -0
- data/lib/ruby_mvc/toolkit/dialog.rb +12 -1
- data/lib/ruby_mvc/toolkit/frame.rb +3 -1
- data/lib/ruby_mvc/toolkit/grid_view.rb +46 -0
- data/lib/ruby_mvc/toolkit/messagebox.rb +32 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby.rb +5 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/app.rb +23 -2
- data/lib/ruby_mvc/toolkit/peers/wxruby/common.rb +11 -1
- data/lib/ruby_mvc/toolkit/peers/wxruby/dialog.rb +82 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/form_builder.rb +108 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/frame.rb +85 -1
- data/lib/ruby_mvc/toolkit/peers/wxruby/grid_model.rb +79 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/grid_view.rb +117 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/messagebox.rb +58 -0
- data/lib/ruby_mvc/toolkit/peers/wxruby/web_view.rb +40 -10
- data/lib/ruby_mvc/toolkit/property_change_notifier.rb +46 -0
- data/lib/ruby_mvc/toolkit/signal_handler.rb +149 -0
- data/lib/ruby_mvc/toolkit/web_view.rb +1 -1
- data/lib/ruby_mvc/toolkit/widget.rb +13 -6
- data/lib/ruby_mvc/views.rb +8 -59
- data/lib/ruby_mvc/views/{ar_type_list.rb → ar_form_view.rb} +10 -13
- data/lib/ruby_mvc/views/ar_support.rb +29 -0
- data/lib/ruby_mvc/views/ar_type_editor.rb +17 -28
- data/lib/ruby_mvc/views/ar_web_model_view.rb +59 -0
- data/lib/ruby_mvc/views/ar_web_type_list.rb +44 -0
- data/lib/ruby_mvc/views/browser_view.rb +185 -0
- data/lib/ruby_mvc/views/form_view.rb +111 -0
- data/lib/ruby_mvc/views/grid_table_view.rb +96 -0
- data/lib/ruby_mvc/views/table_view.rb +0 -39
- data/lib/ruby_mvc/views/view.rb +121 -0
- data/lib/ruby_mvc/views/web_content_table_view.rb +40 -0
- data/lib/ruby_mvc/views/{web_view.rb → web_content_view.rb} +17 -28
- data/lib/ruby_mvc/views/web_model_view.rb +67 -0
- data/ruby_mvc.gemspec +1 -1
- data/sample/browser_view.rb +57 -0
- data/sample/form.rb +59 -0
- data/sample/form2.rb +63 -0
- data/sample/grid_table_view.rb +68 -0
- data/sample/grid_view.rb +44 -0
- data/sample/grid_view2.rb +57 -0
- data/sample/test.html +1 -0
- data/sample/test2.html +33 -0
- data/sample/web_view.rb +4 -0
- data/test/unit/models/test_array_table_model.rb +19 -3
- data/test/unit/models/test_keyed_array_table_model.rb +3 -2
- data/test/unit/models/test_model.rb +88 -0
- metadata +39 -20
- data/lib/ruby_mvc/toolkit/notification.rb +0 -202
- data/lib/ruby_mvc/views/ar_model_editor.rb +0 -84
@@ -0,0 +1,29 @@
|
|
1
|
+
#--
|
2
|
+
######################################################################
|
3
|
+
#
|
4
|
+
# Copyright 2011 Andrew S. Townley
|
5
|
+
#
|
6
|
+
# Permission to use, copy, modify, and disribute this software for
|
7
|
+
# any purpose with or without fee is hereby granted, provided that
|
8
|
+
# the above copyright notices and this permission notice appear in
|
9
|
+
# all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
|
12
|
+
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
13
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
14
|
+
# AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
|
15
|
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
17
|
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
18
|
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
#
|
20
|
+
# File: ar_support.rb
|
21
|
+
# Created: Mon 12 Dec 2011 06:49:00 CST
|
22
|
+
#
|
23
|
+
#####################################################################
|
24
|
+
#++
|
25
|
+
|
26
|
+
require 'ruby_mvc/views/ar_form_view'
|
27
|
+
require 'ruby_mvc/views/ar_type_editor'
|
28
|
+
require 'ruby_mvc/views/ar_web_type_list'
|
29
|
+
require 'ruby_mvc/views/ar_web_model_view'
|
@@ -26,36 +26,25 @@
|
|
26
26
|
module RubyMVC
|
27
27
|
module Views
|
28
28
|
|
29
|
-
class ActiveRecordTypeEditor <
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
@
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
window do
|
46
|
-
stack do
|
47
|
-
obj.description = "Some text"
|
48
|
-
editor = active_record_model_editor obj
|
49
|
-
flow :margin_left => 0, :left => "-25%" do
|
50
|
-
button "Cancel", :align => "right" do
|
51
|
-
close
|
52
|
-
end
|
53
|
-
button "Save", :align => "right" do
|
54
|
-
editor.save
|
55
|
-
close
|
29
|
+
class ActiveRecordTypeEditor < GridTableView
|
30
|
+
def initialize(app, parent, entity_type, options = {}, &block)
|
31
|
+
options[:editable] = false
|
32
|
+
options[:show_row_labels] = false
|
33
|
+
@model = Models::ActiveRecordTableModel.new(entity_type)
|
34
|
+
@template = options[:template]
|
35
|
+
super((@template ? @template.apply(@model) : @model), options)
|
36
|
+
signal_connect("row-edit") do |s, m, i, r|
|
37
|
+
app.dialog(:title => options[:editor_title], :parent => parent) do |dlg|
|
38
|
+
form = FormView.new((@template ? @template.apply(r) : r), &block)
|
39
|
+
form.signal_connect("form-submit") do |form, d|
|
40
|
+
begin
|
41
|
+
r.save!
|
42
|
+
m.update_row(i, r)
|
43
|
+
rescue ActiveRecord::RecordInvalid => e
|
44
|
+
app.error(e, :title => "Validation Error", :parent => dlg)
|
56
45
|
end
|
57
|
-
debug("created buttons")
|
58
46
|
end
|
47
|
+
dlg.add form
|
59
48
|
end
|
60
49
|
end
|
61
50
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#--
|
2
|
+
######################################################################
|
3
|
+
#
|
4
|
+
# Copyright 2011-2012 Andrew S. Townley
|
5
|
+
#
|
6
|
+
# Permission to use, copy, modify, and disribute this software for
|
7
|
+
# any purpose with or without fee is hereby granted, provided that
|
8
|
+
# the above copyright notices and this permission notice appear in
|
9
|
+
# all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
|
12
|
+
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
13
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
14
|
+
# AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
|
15
|
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
17
|
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
18
|
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
#
|
20
|
+
# File: ar_web_model_view.rb
|
21
|
+
# Created: Mon 9 Jan 2012 22:45:05 GMT
|
22
|
+
#
|
23
|
+
#####################################################################
|
24
|
+
#++
|
25
|
+
|
26
|
+
module RubyMVC
|
27
|
+
module Views
|
28
|
+
|
29
|
+
class ActiveRecordWebModelView < WebModelView
|
30
|
+
signal "row-edit"
|
31
|
+
signal "row-delete", :vetoable => true
|
32
|
+
|
33
|
+
def initialize(row, options = {})
|
34
|
+
super
|
35
|
+
|
36
|
+
action(:edit, :label => "Edit", :icon => :stock_edit) do
|
37
|
+
signal_emit("row-edit", self, row)
|
38
|
+
end
|
39
|
+
|
40
|
+
# action(:delete, :label => "Delete", :icon => :stock_delete) do
|
41
|
+
# signal_emit("row-delete", self, row)
|
42
|
+
# end
|
43
|
+
end
|
44
|
+
|
45
|
+
def render
|
46
|
+
html = super
|
47
|
+
tagz {
|
48
|
+
tagz.concat html
|
49
|
+
tagz.concat render_links
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
def render_links
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#--
|
2
|
+
######################################################################
|
3
|
+
#
|
4
|
+
# Copyright 2011-2012 Andrew S. Townley
|
5
|
+
#
|
6
|
+
# Permission to use, copy, modify, and disribute this software for
|
7
|
+
# any purpose with or without fee is hereby granted, provided that
|
8
|
+
# the above copyright notices and this permission notice appear in
|
9
|
+
# all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
|
12
|
+
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
13
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
14
|
+
# AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
|
15
|
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
17
|
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
18
|
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
#
|
20
|
+
# File: ar_web_type_list.rb
|
21
|
+
# Created: Mon 9 Jan 2012 15:56:18 GMT
|
22
|
+
#
|
23
|
+
#####################################################################
|
24
|
+
#++
|
25
|
+
|
26
|
+
module RubyMVC
|
27
|
+
module Views
|
28
|
+
|
29
|
+
class ActiveRecordWebTypeList < WebContentTableView
|
30
|
+
def initialize(entity_type, options = {}, &block)
|
31
|
+
@model = Models::ActiveRecordTableModel.new(entity_type)
|
32
|
+
if options.is_a? Hash
|
33
|
+
@template = options[:template]
|
34
|
+
else
|
35
|
+
@template = options
|
36
|
+
options = {}
|
37
|
+
end
|
38
|
+
super((@template ? @template.apply(@model) : @model), options)
|
39
|
+
action(:edit, :label => "Edit", :icon => :stock_edit, &block)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
#--
|
2
|
+
######################################################################
|
3
|
+
#
|
4
|
+
# Copyright 2011 Andrew S. Townley
|
5
|
+
#
|
6
|
+
# Permission to use, copy, modify, and disribute this software for
|
7
|
+
# any purpose with or without fee is hereby granted, provided that
|
8
|
+
# the above copyright notices and this permission notice appear in
|
9
|
+
# all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
|
12
|
+
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
13
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
14
|
+
# AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
|
15
|
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
17
|
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
18
|
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
#
|
20
|
+
# File: browser_view.rb
|
21
|
+
# Created: Mon 2 Jan 2012 22:44:26 CET
|
22
|
+
#
|
23
|
+
#####################################################################
|
24
|
+
#++
|
25
|
+
|
26
|
+
module RubyMVC
|
27
|
+
module Views
|
28
|
+
|
29
|
+
# This class is slightly different at the moment as it
|
30
|
+
# really should have a HypermediaContentModel instance that
|
31
|
+
# feeds it vs. being explicitly driven by the client. This
|
32
|
+
# should be addressed better in a future version.
|
33
|
+
|
34
|
+
class BrowserView < PeerView
|
35
|
+
widget Toolkit::WebView
|
36
|
+
|
37
|
+
def initialize(options = {}, &block)
|
38
|
+
super
|
39
|
+
|
40
|
+
class << action(:back,
|
41
|
+
:label => "Back", :icon => :stock_back, :widget => widget) do
|
42
|
+
go_back
|
43
|
+
end
|
44
|
+
|
45
|
+
def sensitive
|
46
|
+
x = @options[:widget].can_go_back?
|
47
|
+
property_changed(:sensitive, @sensitive, x)
|
48
|
+
@sensitive = x
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class << action(:forward,
|
53
|
+
:label => "Forward", :icon => :stock_forward, :widget => widget) do
|
54
|
+
go_forward
|
55
|
+
end
|
56
|
+
|
57
|
+
def sensitive
|
58
|
+
x = @options[:widget].can_go_forward?
|
59
|
+
property_changed(:sensitive, @sensitive, x)
|
60
|
+
@sensitive = x
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class << action(:reload,
|
65
|
+
:label => "Reload", :icon => :stock_reload, :widget => widget) do
|
66
|
+
reload
|
67
|
+
end
|
68
|
+
|
69
|
+
def sensitive
|
70
|
+
w = @options[:widget]
|
71
|
+
x = (!w.location.nil? && "" != w.location)
|
72
|
+
property_changed(:sensitive, @sensitive, x)
|
73
|
+
@sensitive = x
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
widget.signal_connect("load-finished") do
|
78
|
+
# puts "load-finished #{widget.location}"
|
79
|
+
# FIXME: this is a hack, but it's the only way for now
|
80
|
+
@actions.each { |a| a.selection(self, nil, nil); a.sensitive }
|
81
|
+
# puts "back? #{widget.can_go_back?}"
|
82
|
+
# puts "forward? #{widget.can_go_forward?}"
|
83
|
+
end
|
84
|
+
|
85
|
+
widget.signal_connect("navigation-requested") do |s, h, t|
|
86
|
+
puts "BrowserView#navigation-requested: #{h}"
|
87
|
+
if (c = self.controller)
|
88
|
+
puts "forwarding to controller: #{c}"
|
89
|
+
c.link_activated(s, h)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def go_forward
|
95
|
+
reset_actions
|
96
|
+
widget.go_forward
|
97
|
+
append_actions((location || {})[:actions])
|
98
|
+
end
|
99
|
+
|
100
|
+
def go_back
|
101
|
+
reset_actions
|
102
|
+
widget.go_back
|
103
|
+
append_actions((location || {})[:actions])
|
104
|
+
end
|
105
|
+
|
106
|
+
def open(uri)
|
107
|
+
reset_actions
|
108
|
+
widget.open(uri)
|
109
|
+
end
|
110
|
+
|
111
|
+
def load_html(*args)
|
112
|
+
reset_actions
|
113
|
+
# puts "#load_html: " << args.inspect
|
114
|
+
widget.load_html(*args)
|
115
|
+
end
|
116
|
+
|
117
|
+
def reload
|
118
|
+
if location && v = location[:view]
|
119
|
+
load(v, location[:uri])
|
120
|
+
else
|
121
|
+
super
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def append_html(*args, &block)
|
126
|
+
widget.append_html(*args, &block)
|
127
|
+
end
|
128
|
+
|
129
|
+
def load(view, uri = nil)
|
130
|
+
if !view.is_a? WebContentView
|
131
|
+
raise ArgumentError, "view must currently be a WebContentView instance"
|
132
|
+
end
|
133
|
+
|
134
|
+
# FIXME: need action support in the history management
|
135
|
+
# too so that actions are appropriately added/removed
|
136
|
+
# during forward/backward navigation requests
|
137
|
+
|
138
|
+
load_html(view.render, uri || view.uri)
|
139
|
+
widget.location[:view] = view
|
140
|
+
|
141
|
+
# If our view provides a different controller, then we
|
142
|
+
# need to defer link handling to that controller instead
|
143
|
+
# of ours (which probably wasn't defined in the first
|
144
|
+
# place)
|
145
|
+
|
146
|
+
if (vc = view.controller) && vc != self.controller
|
147
|
+
puts "assigned new controller from WebContentView: #{vc}"
|
148
|
+
self.controller = vc
|
149
|
+
else
|
150
|
+
puts "no controller defined for #{view}"
|
151
|
+
end
|
152
|
+
|
153
|
+
# add any content actions
|
154
|
+
append_actions(view.actions)
|
155
|
+
end
|
156
|
+
|
157
|
+
def add(view)
|
158
|
+
if !view.is_a? WebContentView
|
159
|
+
raise ArgumentError, "view must currently be a WebContentView instance"
|
160
|
+
end
|
161
|
+
|
162
|
+
append_html(view.render)
|
163
|
+
|
164
|
+
# FIXME: this should really be done, but we need to be a bit
|
165
|
+
# more sophisticated in the way we manage it
|
166
|
+
# append_actions(view.actions)
|
167
|
+
end
|
168
|
+
|
169
|
+
private
|
170
|
+
def append_actions(actions)
|
171
|
+
return if !actions
|
172
|
+
|
173
|
+
location[:actions] = actions if location
|
174
|
+
frame.merge_actions(actions)
|
175
|
+
end
|
176
|
+
|
177
|
+
def reset_actions
|
178
|
+
if location && (ca = location[:actions])
|
179
|
+
frame.unmerge_actions(ca)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
#--
|
2
|
+
######################################################################
|
3
|
+
#
|
4
|
+
# Copyright 2011 Andrew S. Townley
|
5
|
+
#
|
6
|
+
# Permission to use, copy, modify, and disribute this software for
|
7
|
+
# any purpose with or without fee is hereby granted, provided that
|
8
|
+
# the above copyright notices and this permission notice appear in
|
9
|
+
# all copies.
|
10
|
+
#
|
11
|
+
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL
|
12
|
+
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
13
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
14
|
+
# AUTHORS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT OR
|
15
|
+
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
17
|
+
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
18
|
+
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
#
|
20
|
+
# File: form_view.rb
|
21
|
+
# Created: Fri 30 Dec 2011 14:48:46 CET
|
22
|
+
#
|
23
|
+
#####################################################################
|
24
|
+
#++
|
25
|
+
|
26
|
+
module RubyMVC
|
27
|
+
module Views
|
28
|
+
|
29
|
+
# FormView instances are an abstract representation of a
|
30
|
+
# form-based editor for model instances. It is deliberately
|
31
|
+
# modelled on HTML forms where possible.
|
32
|
+
|
33
|
+
class FormView < View
|
34
|
+
# This signal is emitted by the hosting widget when the
|
35
|
+
# form has been submitted. The block is passed arguments
|
36
|
+
# for the form and the model (or model proxy) being used.
|
37
|
+
|
38
|
+
signal "form-submit", :vetoable => true
|
39
|
+
|
40
|
+
# This signal is emitted by the hosting widget when the
|
41
|
+
# form has been reset.
|
42
|
+
|
43
|
+
signal "form-reset"
|
44
|
+
|
45
|
+
def initialize(model, &block)
|
46
|
+
@model = model
|
47
|
+
@editors = {}
|
48
|
+
@validators = {}
|
49
|
+
@disabled = {}
|
50
|
+
self.instance_eval(&block) if block
|
51
|
+
end
|
52
|
+
|
53
|
+
def editor(key, editor)
|
54
|
+
@editors[key.to_sym] = editor
|
55
|
+
end
|
56
|
+
|
57
|
+
# This method sets a validator block for the given key.
|
58
|
+
# More than one validator can be initialized for each
|
59
|
+
# property key
|
60
|
+
|
61
|
+
def validator(key, &block)
|
62
|
+
return if !block
|
63
|
+
vals = (@validators[key.to_sym] ||= [])
|
64
|
+
vals << block
|
65
|
+
end
|
66
|
+
|
67
|
+
# This method is used to ensure that the specified model
|
68
|
+
# key field appears, but is disabled. This can also be
|
69
|
+
# done via the model by ensuring editable is false.
|
70
|
+
|
71
|
+
def disabled(key, val = true)
|
72
|
+
@disabled[key.to_sym] = val
|
73
|
+
end
|
74
|
+
|
75
|
+
# This method is used by the concrete hosting widget to
|
76
|
+
# iterate through the form field definitions so that it
|
77
|
+
# can create the actual UI form.
|
78
|
+
|
79
|
+
def layout(&block)
|
80
|
+
@model.labels.each do |l|
|
81
|
+
k = l[:key]
|
82
|
+
if (@disabled.has_key?(k) && @disabled[k]) \
|
83
|
+
|| !@model.is_editable?(k)
|
84
|
+
disabled = true
|
85
|
+
else
|
86
|
+
disabled = false
|
87
|
+
end
|
88
|
+
block.call(k, l[:label], @model[k], @editors[k] || l[:editor], disabled)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# This method is called when the form should be saved to
|
93
|
+
# the underlying model.
|
94
|
+
|
95
|
+
def submit(values)
|
96
|
+
values.each do |k, v|
|
97
|
+
@model[k] = v if @model.is_editable? k
|
98
|
+
end
|
99
|
+
signal_emit("form-submit", self, @model)
|
100
|
+
end
|
101
|
+
|
102
|
+
def reset(&block)
|
103
|
+
@model.keys.each do |k|
|
104
|
+
block.call(k, @model[k])
|
105
|
+
end
|
106
|
+
signal_emit("form-reset", self, @model)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|