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.
Files changed (68) hide show
  1. data/README.md +14 -0
  2. data/lib/ruby_mvc.rb +3 -1
  3. data/lib/ruby_mvc/application.rb +52 -2
  4. data/lib/ruby_mvc/controllers.rb +28 -0
  5. data/lib/ruby_mvc/controllers/action.rb +93 -0
  6. data/lib/ruby_mvc/controllers/action_group.rb +70 -0
  7. data/lib/ruby_mvc/controllers/app_controller.rb +4 -2
  8. data/lib/ruby_mvc/controllers/rails_controller.rb +2 -0
  9. data/lib/ruby_mvc/models.rb +2 -0
  10. data/lib/ruby_mvc/models/ar_table_model.rb +133 -0
  11. data/lib/ruby_mvc/models/array_table_model.rb +81 -13
  12. data/lib/ruby_mvc/models/keyed_array_table_model.rb +1 -1
  13. data/lib/ruby_mvc/models/model.rb +129 -0
  14. data/lib/ruby_mvc/models/table_model.rb +107 -10
  15. data/lib/ruby_mvc/models/view_model_template.rb +140 -0
  16. data/lib/ruby_mvc/renderers.rb +1 -0
  17. data/lib/ruby_mvc/renderers/html4_table_model_renderer.rb +7 -6
  18. data/lib/ruby_mvc/renderers/hyperlink_cell_renderer.rb +47 -0
  19. data/lib/ruby_mvc/toolkit.rb +5 -1
  20. data/lib/ruby_mvc/toolkit/browser_history.rb +115 -0
  21. data/lib/ruby_mvc/toolkit/dialog.rb +12 -1
  22. data/lib/ruby_mvc/toolkit/frame.rb +3 -1
  23. data/lib/ruby_mvc/toolkit/grid_view.rb +46 -0
  24. data/lib/ruby_mvc/toolkit/messagebox.rb +32 -0
  25. data/lib/ruby_mvc/toolkit/peers/wxruby.rb +5 -0
  26. data/lib/ruby_mvc/toolkit/peers/wxruby/app.rb +23 -2
  27. data/lib/ruby_mvc/toolkit/peers/wxruby/common.rb +11 -1
  28. data/lib/ruby_mvc/toolkit/peers/wxruby/dialog.rb +82 -0
  29. data/lib/ruby_mvc/toolkit/peers/wxruby/form_builder.rb +108 -0
  30. data/lib/ruby_mvc/toolkit/peers/wxruby/frame.rb +85 -1
  31. data/lib/ruby_mvc/toolkit/peers/wxruby/grid_model.rb +79 -0
  32. data/lib/ruby_mvc/toolkit/peers/wxruby/grid_view.rb +117 -0
  33. data/lib/ruby_mvc/toolkit/peers/wxruby/messagebox.rb +58 -0
  34. data/lib/ruby_mvc/toolkit/peers/wxruby/web_view.rb +40 -10
  35. data/lib/ruby_mvc/toolkit/property_change_notifier.rb +46 -0
  36. data/lib/ruby_mvc/toolkit/signal_handler.rb +149 -0
  37. data/lib/ruby_mvc/toolkit/web_view.rb +1 -1
  38. data/lib/ruby_mvc/toolkit/widget.rb +13 -6
  39. data/lib/ruby_mvc/views.rb +8 -59
  40. data/lib/ruby_mvc/views/{ar_type_list.rb → ar_form_view.rb} +10 -13
  41. data/lib/ruby_mvc/views/ar_support.rb +29 -0
  42. data/lib/ruby_mvc/views/ar_type_editor.rb +17 -28
  43. data/lib/ruby_mvc/views/ar_web_model_view.rb +59 -0
  44. data/lib/ruby_mvc/views/ar_web_type_list.rb +44 -0
  45. data/lib/ruby_mvc/views/browser_view.rb +185 -0
  46. data/lib/ruby_mvc/views/form_view.rb +111 -0
  47. data/lib/ruby_mvc/views/grid_table_view.rb +96 -0
  48. data/lib/ruby_mvc/views/table_view.rb +0 -39
  49. data/lib/ruby_mvc/views/view.rb +121 -0
  50. data/lib/ruby_mvc/views/web_content_table_view.rb +40 -0
  51. data/lib/ruby_mvc/views/{web_view.rb → web_content_view.rb} +17 -28
  52. data/lib/ruby_mvc/views/web_model_view.rb +67 -0
  53. data/ruby_mvc.gemspec +1 -1
  54. data/sample/browser_view.rb +57 -0
  55. data/sample/form.rb +59 -0
  56. data/sample/form2.rb +63 -0
  57. data/sample/grid_table_view.rb +68 -0
  58. data/sample/grid_view.rb +44 -0
  59. data/sample/grid_view2.rb +57 -0
  60. data/sample/test.html +1 -0
  61. data/sample/test2.html +33 -0
  62. data/sample/web_view.rb +4 -0
  63. data/test/unit/models/test_array_table_model.rb +19 -3
  64. data/test/unit/models/test_keyed_array_table_model.rb +3 -2
  65. data/test/unit/models/test_model.rb +88 -0
  66. metadata +39 -20
  67. data/lib/ruby_mvc/toolkit/notification.rb +0 -202
  68. data/lib/ruby_mvc/views/ar_model_editor.rb +0 -84
@@ -0,0 +1,108 @@
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_builder.rb
21
+ # Created: Fri 30 Dec 2011 17:20:42 CET
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ module RubyMVC
27
+ module Toolkit
28
+ module WxRuby
29
+
30
+ # This module is a helper class used to build the
31
+ # concrete representations of the FormView controls
32
+
33
+ class FormBuilder
34
+ def self.build(parent, form)
35
+ builder = self.new
36
+ builder.build(parent, form)
37
+ builder
38
+ end
39
+
40
+ def initialize
41
+ @fields = {}
42
+ @panel = Wx::BoxSizer.new(Wx::VERTICAL)
43
+ @sizer = Wx::FlexGridSizer.new(0, 2, 5, 5)
44
+ @panel.add(@sizer, 0, Wx::ALIGN_CENTER_VERTICAL|Wx::ALL, 5)
45
+ end
46
+
47
+ def widget
48
+ @panel
49
+ end
50
+
51
+ def build(parent, form)
52
+ @form = form
53
+ form.layout do |key, label, val, editor, disabled|
54
+ puts "key: #{key}; disabled: #{disabled}"
55
+ case(editor)
56
+ when :textarea
57
+ w = build_textfield(parent, label, val, true)
58
+ else
59
+ w = build_textfield(parent, label, val)
60
+ end
61
+ @fields[key] = w
62
+ w.disable if disabled
63
+ end
64
+ end
65
+
66
+ def submit
67
+ save_form
68
+ end
69
+
70
+ private
71
+ def save_form
72
+ vals = {}
73
+ @fields.each do |k, v|
74
+ if v && v.is_modified
75
+ vals[k] = v.get_value
76
+ end
77
+ end
78
+ @form.submit(vals)
79
+ end
80
+
81
+ # def load_form(model)
82
+ # @fields.keys.each do |k|
83
+ # @fields[k].set_value(model[k].to_s)
84
+ # end
85
+ # end
86
+
87
+ def build_textfield(parent, label, val = "", multiline = false)
88
+ if multiline
89
+ flags = Wx::TE_MULTILINE
90
+ size = [ 150, -1 ]
91
+ else
92
+ flags = 0
93
+ size = [ 150, -1 ]
94
+ end
95
+ st = Wx::StaticText.new(parent, :label => label)
96
+ tf = Wx::TextCtrl.new(parent, :value => val.to_s, :size => size, :style => flags)
97
+ tf.evt_set_focus { |e| tf.set_selection(0, -1) }
98
+ tf.evt_kill_focus { |e| tf.set_selection(0, 0) }
99
+ # @sizer.add(st, 0, Wx::ALIGN_LEFT|Wx::ALL, 5)
100
+ # @sizer.add(tf, 1, Wx::ALIGN_CENTER|Wx::ALL, 5)
101
+ @sizer.add(st)
102
+ @sizer.add(tf)
103
+ tf
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -27,6 +27,7 @@ module RubyMVC
27
27
  module Toolkit
28
28
  module WxRuby
29
29
  class Frame < Wx::Frame
30
+ include Toolkit::SignalHandler
30
31
  include Common
31
32
  Toolkit::Frame.peer_class = self
32
33
 
@@ -34,7 +35,19 @@ module RubyMVC
34
35
  opts = {}
35
36
  opts[:title] = options[:title]
36
37
  opts[:size] = [ options[:width], options[:height] ]
37
- super(options[:parent], opts)
38
+ if parent = options[:parent]
39
+ parent = parent.peer
40
+ end
41
+ super(parent, opts)
42
+ if icon = options[:icon]
43
+ self.set_icon WxRuby.load_icon(icon)
44
+ end
45
+ @action_index = {}
46
+
47
+ evt_close do |e|
48
+ e.skip
49
+ signal_emit("window-closed", self)
50
+ end
38
51
  end
39
52
 
40
53
  # This method is used to add a child to the existing
@@ -42,6 +55,77 @@ module RubyMVC
42
55
 
43
56
  def add(child, options = {})
44
57
  child.peer.reparent(self)
58
+
59
+ if child.is_a?(RubyMVC::Views::View) && (a = child.actions)
60
+ child.frame = self
61
+ merge_actions(a)
62
+ end
63
+ end
64
+
65
+ def merge_actions(actions)
66
+ # puts "#merge_actions #{actions.inspect}"
67
+ tb = toolbar
68
+ actions.each do |a|
69
+ i = @action_index.size
70
+ # puts "Action: #{a.label}"
71
+ case a[:icon]
72
+ when :stock_new
73
+ artid = Wx::ART_NEW
74
+ when :stock_edit
75
+ artid = Wx::ART_NORMAL_FILE
76
+ when :stock_delete
77
+ artid = Wx::ART_DELETE
78
+ when :stock_home
79
+ artid = Wx::ART_GO_HOME
80
+ when :stock_back
81
+ artid = Wx::ART_GO_BACK
82
+ when :stock_forward
83
+ artid = Wx::ART_GO_FORWARD
84
+ when :stock_reload
85
+ artid = Wx::ART_REDO
86
+ end
87
+ if artid
88
+ icon = Wx::ArtProvider.get_bitmap(artid, Wx::ART_TOOLBAR, [ 16, 16 ])
89
+ else
90
+ icon = Wx::NULL_BITMAP
91
+ end
92
+
93
+ tb.add_tool(i, a.label, icon)
94
+ tb.enable_tool(i, a.sensitive)
95
+ a.signal_connect("property-changed") do |a, key, old, val|
96
+ # puts "property changed: #{key} => #{val}"
97
+ tb.enable_tool(i, val)
98
+ end
99
+ evt_tool(i) do |event|
100
+ # puts "Action[#{i}] triggered: #{a.key}"
101
+ a.call
102
+ end
103
+ @action_index[a.key] = i
104
+ end
105
+ @toolbar.realize
106
+
107
+ # puts "action_index: #{@action_index.inspect}"
108
+ end
109
+
110
+ def unmerge_actions(actions)
111
+ # puts "unmerge actions: #{actions.inspect}"
112
+ tb = toolbar
113
+ actions.each do |a|
114
+ idx = @action_index.delete(a.key)
115
+ # puts "unmerge action[#{idx}] => #{a.inspect}"
116
+ tb.delete_tool(idx) if idx
117
+ end
118
+ end
119
+
120
+ protected
121
+ def toolbar
122
+ if !@toolbar
123
+ @toolbar = create_tool_bar(
124
+ Wx::TB_HORIZONTAL |
125
+ Wx::TB_FLAT |
126
+ Wx::TB_TEXT)
127
+ end
128
+ @toolbar
45
129
  end
46
130
  end
47
131
  end
@@ -0,0 +1,79 @@
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: grid_model.rb
21
+ # Created: Sat 31 Dec 2011 18:29:03 CET
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ module RubyMVC
27
+ module Toolkit
28
+ module WxRuby
29
+
30
+ # This class provides an adapter between a
31
+ # RubyMVC::Models::TableModel instance and the
32
+ # Wx::GridTableBase API so that we can drive Wx::Grid
33
+ # instances using our model definitions.
34
+
35
+ class GridModel < Wx::GridTableBase
36
+ def initialize(model)
37
+ super()
38
+ @model = model
39
+ @labels = model.labels
40
+ @cols = {}
41
+ @labels.each_with_index do |l, i|
42
+ @cols[i] = l[:key]
43
+ end
44
+ end
45
+
46
+ def get_number_cols
47
+ @model.labels.size
48
+ end
49
+
50
+ def get_number_rows
51
+ @model.size
52
+ end
53
+
54
+ def get_value(row, col)
55
+ @model.value_for(row, get_key(col)).to_s
56
+ end
57
+
58
+ def is_empty_cell(row, col)
59
+ get_value(row, col).nil?
60
+ end
61
+
62
+ def get_attr(row, col, kind)
63
+ end
64
+
65
+ def get_row_label_value(row)
66
+ (row + 1).to_s
67
+ end
68
+
69
+ def get_col_label_value(col)
70
+ @labels[col][:label]
71
+ end
72
+
73
+ def get_key(col)
74
+ @cols[col]
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,117 @@
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: dialog.rb
21
+ # Created: Sun 11 Dec 2011 14:37:40 CST
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ module RubyMVC
27
+ module Toolkit
28
+ module WxRuby
29
+ class GridView < Wx::Grid
30
+ include SignalHandler
31
+ include Common
32
+ Toolkit::GridView.peer_class = self
33
+
34
+ def initialize(options = {})
35
+ puts "options: #{options.inspect}"
36
+ super(WxRuby.parent(options), options[:id] || -1)
37
+ if false == options[:show_row_labels]
38
+ set_row_label_size(0)
39
+ end
40
+ @selected_rows = []
41
+
42
+ evt_grid_cmd_cell_left_dclick(self.get_id()) do |e|
43
+ if @gm
44
+ col = @gm.get_key(e.get_col)
45
+ else
46
+ col = e.get_col
47
+ end
48
+ signal_emit("row-activated", self, @model, e.get_row, col)
49
+ end
50
+
51
+ evt_grid_range_select do |e|
52
+ puts "Event alt: #{e.alt_down}; ctrl: #{e.control_down}; brc: #{e.get_bottom_right_coords}; bottom: #{e.get_bottom_row}; left: #{e.get_left_col}; right: #{e.get_right_col}; tlc: #{e.get_top_left_coords}; top: #{e.get_top_row}; meta: #{e.meta_down}; selecting: #{e.selecting}; shift: #{e.shift_down}" if !e.selecting
53
+ next if !e.selecting
54
+
55
+ # FIXME: this should be a bit more clever in the
56
+ # future, but right now, we're only dealing with
57
+ # row selection
58
+ # puts "Event alt: #{e.alt_down}; ctrl: #{e.control_down}; brc: #{e.get_bottom_right_coords}; bottom: #{e.get_bottom_row}; left: #{e.get_left_col}; right: #{e.get_right_col}; tlc: #{e.get_top_left_coords}; top: #{e.get_top_row}; meta: #{e.meta_down}; selecting: #{e.selecting}; shift: #{e.shift_down}"
59
+ top = e.get_top_row
60
+ bottom = e.get_bottom_row
61
+ sel = []
62
+ top.upto(bottom) do |i|
63
+ sel << i
64
+ end
65
+ @selected_rows = sel
66
+ signal_emit("row-selection-changed", self, @model, sel)
67
+ end
68
+ end
69
+
70
+ def model=(model)
71
+ @model = model
72
+ @gm = GridModel.new(model)
73
+ set_table(@gm, Wx::Grid::GridSelectRows)
74
+
75
+ # FIXME: this is a bit cheezy and there should be a
76
+ # better way to communicate between the grid table
77
+ # and the view than this... Apparently, the wxRuby
78
+ # implementation doesn't expose the message
79
+ # dispatching required between GridTableBase and the
80
+ # Grid displaying it. Kinda defeats the point...
81
+
82
+ @model.signal_connect("rows-inserted") do |s, i, r|
83
+ puts "refresh rows-inserted"
84
+ @gm = GridModel.new(model)
85
+ set_table(@gm, Wx::Grid::GridSelectRows, false)
86
+ end
87
+ @model.signal_connect("rows-removed") do |s, i, r|
88
+ puts "refresh rows-removed"
89
+ @gm = GridModel.new(model)
90
+ set_table(@gm, Wx::Grid::GridSelectRows, false)
91
+ end
92
+ @model.signal_connect("row-changed") do |s, i, r|
93
+ puts "refresh row-changed"
94
+ @gm = GridModel.new(model)
95
+ set_table(@gm, Wx::Grid::GridSelectRows, false)
96
+ end
97
+ end
98
+
99
+ def set_table(table, flags, clear_selection = true)
100
+ super(table, flags)
101
+ @selected_rows.clear if clear_selection
102
+ auto_size_columns(false)
103
+ signal_emit("row-selection-changed", self, @model, @selected_rows)
104
+ end
105
+
106
+ def editable=(val)
107
+ enable_editing(val)
108
+ end
109
+
110
+ def selected_rows
111
+ # FIXME: I shouldn't have to maintain this list...
112
+ @selected_rows
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,58 @@
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: messagebox.rb
21
+ # Created: Mon 9 Jan 2012 11:34:52 GMT
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ module RubyMVC
27
+ module Toolkit
28
+ module WxRuby
29
+ class MessageBox < Wx::MessageDialog
30
+ include Common
31
+ Toolkit::MessageBox.peer_class = self
32
+
33
+ def initialize(message, options)
34
+ opts = {}
35
+ title = options[:title] || "Message"
36
+ if parent = options[:parent]
37
+ parent = parent.peer
38
+ end
39
+ case(options[:class])
40
+ when :error
41
+ flags = Wx::OK | Wx::ICON_ERROR
42
+ when :info
43
+ flags = Wx::OK | Wx::ICON_INFORMATION
44
+ when :question
45
+ flags = Wx::YES_NO | Wx::ICON_QUESTION
46
+ else
47
+ flags = Wx::OK | Wx::CANCEL
48
+ end
49
+ super(parent, message.to_s, title, flags)
50
+ end
51
+
52
+ def show
53
+ show_modal
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end