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
data/README.md CHANGED
@@ -63,7 +63,21 @@ wxruby-ruby19 gem using the following platform magic:
63
63
 
64
64
  $ gem install --platform x86-darwin-9 --no-ri --no-rdoc wxruby-ruby19
65
65
 
66
+
66
67
  ### Windows
67
68
 
68
69
  Amazingly enough, it seems to *just work* on Windows (Vista is the
69
70
  only tested configuration at the moment). YMMV.
71
+
72
+
73
+ Building and Publishing the Gem
74
+ -------------------------------
75
+
76
+ In order to build the gem, simply execute the following command:
77
+
78
+ $ gem build ruby_mvc.gemspec
79
+
80
+ Once you're sure things are working, then push the gem to
81
+ rubygems.org:
82
+
83
+ $ gem push ruby_mvc-VERSION.gem
data/lib/ruby_mvc.rb CHANGED
@@ -24,10 +24,12 @@
24
24
  #++
25
25
 
26
26
  require 'yaml'
27
+ require 'uri'
28
+ require 'cgi'
27
29
  require 'ruby_mvc/module'
28
30
  require 'ruby_mvc/toolkit'
29
31
  require 'ruby_mvc/renderers'
30
- require 'ruby_mvc/controllers/app_controller'
32
+ require 'ruby_mvc/controllers'
31
33
  require 'ruby_mvc/models'
32
34
  require 'ruby_mvc/views'
33
35
  require 'ruby_mvc/application'
@@ -27,26 +27,76 @@ module RubyMVC
27
27
 
28
28
  # This provides the entry point for a basic application.
29
29
  class Application
30
+ # FIXME 2011-12-29 ast: The relationship between
31
+ # Toolkit::App and the AppController classes don't really
32
+ # make sense. This needs to be revisited in a future
33
+ # iteration.
34
+
30
35
  attr_accessor :frame
31
36
  attr_accessor :controller
37
+ attr_accessor :windows
32
38
 
33
39
  def initialize(options, &block)
34
- self.frame = Toolkit::Frame.new(options)
40
+ @windows = []
41
+ if ico = options[:icon]
42
+ ico = options[:icon] = File.expand_path(ico)
43
+ puts "icon requested: #{ico}"
44
+ end
45
+ @windows << (self.frame = Toolkit::Frame.new(options))
35
46
  if cc = options[:controller]
36
47
  self.controller = cc
37
48
  self.controller.app = self
38
49
  self.controller.init
39
50
  end
51
+ @frame_width = options[:width]
52
+ @frame_height = options[:height]
40
53
  self.instance_eval(&block) if block
41
54
  self.frame.show
42
55
  end
56
+
57
+ def window(options, &block)
58
+ set_parent(options)
59
+
60
+ # FIXME: this is a bit of a hack for wxRuby peers
61
+ options[:height] = @frame_height if !options[:height]
62
+ options[:width] = @frame_width if !options[:width]
63
+ win = Toolkit::Frame.new(options)
64
+ block.call(win) if block
65
+ win.show
66
+
67
+ # FIXME: need to be able to intercept the close event so
68
+ # we can remove the window from the list
69
+ @windows << win
70
+ win
71
+ end
72
+
73
+ def dialog(options, &block)
74
+ set_parent(options)
75
+ dlg = Toolkit::Dialog.new(options)
76
+ block.call(dlg) if block
77
+ dlg.show
78
+ dlg
79
+ end
80
+
81
+ def error(msg, options)
82
+ options[:class] = :error
83
+ dlg = Toolkit::MessageBox.new(msg, options)
84
+ dlg.show
85
+ end
86
+
87
+ protected
88
+ def set_parent(options)
89
+ if !options[:parent]
90
+ options[:parent] = self.frame
91
+ end
92
+ end
43
93
  end
44
94
 
45
95
  # This method creates a default application and runs it
46
96
  # using the active toolkit.
47
97
 
48
98
  def self.app(*args, &block)
49
- Toolkit::App.new do
99
+ Toolkit::App.new(*args) do
50
100
  Application.new(*args, &block)
51
101
  end
52
102
  end
@@ -0,0 +1,28 @@
1
+ #--
2
+ ######################################################################
3
+ #
4
+ # Copyright 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: controllers.rb
21
+ # Created: Mon 2 Jan 2012 16:44:27 CET
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ require 'ruby_mvc/controllers/action'
27
+ require 'ruby_mvc/controllers/action_group'
28
+ require 'ruby_mvc/controllers/app_controller'
@@ -0,0 +1,93 @@
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: action.rb
21
+ # Created: Sun 1 Jan 2012 16:44:29 CET
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ module RubyMVC
27
+
28
+ # This class provides the ability to define discrete
29
+ # operations a la the Command pattern. Actions have keys,
30
+ # labels and a block that is called when they are activated.
31
+ # Additionally, they may be initialized with options that
32
+ # define when they are available.
33
+
34
+ class Action
35
+ include Toolkit::PropertyChangeNotifier
36
+ attr_reader :key
37
+
38
+ def initialize(key, options = {}, &block)
39
+ @key = key.to_sym
40
+ @options = options
41
+ @block = block
42
+ @sensitive = true
43
+ @sensitive = false if !@options[:enable].nil?
44
+ if !(x = options[:sensitive]).nil?
45
+ @sensitive = x
46
+ end
47
+ end
48
+
49
+ # This method is used to access the options for this
50
+ # action.
51
+
52
+ def [](key)
53
+ @options[key]
54
+ end
55
+
56
+ def label
57
+ @options[:label] || @key.to_s.capitalize
58
+ end
59
+
60
+ def call(*args)
61
+ @block.call(*args) if @block
62
+ end
63
+
64
+ def sensitive=(val)
65
+ if val != @sensitive
66
+ @sensitive = val
67
+ property_changed(:sensitive, !val, val)
68
+ end
69
+ end
70
+
71
+ # This method may be overridden by action instances to
72
+ # have more control over when the action should be enabled
73
+ # or not.
74
+
75
+ def sensitive
76
+ @sensitive
77
+ end
78
+
79
+ # This method is used to allow the action instances to
80
+ # determine internal state changes based on selection
81
+ # state changes in their view.
82
+
83
+ def selection(sender, model, sel)
84
+ case @options[:enable]
85
+ when :select_multi
86
+ self.sensitive = sel.size >= 1
87
+ when :select_single
88
+ self.sensitive = sel.size == 1
89
+ end
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,70 @@
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: action_group.rb
21
+ # Created: Sun 1 Jan 2012 17:32:19 CET
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ module RubyMVC
27
+
28
+ # This class provides a collection for actions so that they
29
+ # can be more easily managed. ActionGroups form the basis
30
+ # for creating menus, toolbars and similar control groups.
31
+
32
+ class ActionGroup
33
+ def initialize
34
+ @actions = []
35
+ @index = {}
36
+ end
37
+
38
+ # This method is used to retrieve an action by action key.
39
+
40
+ def [](key)
41
+ @index[key]
42
+ end
43
+
44
+ def <<(action)
45
+ if !@actions.include? action
46
+ @actions << action
47
+ @index[action.key] = action
48
+ end
49
+ end
50
+
51
+ def delete(action)
52
+ if action.is_a? Symbol
53
+ key = action
54
+ else
55
+ key = action.key
56
+ end
57
+ val = @index.delete(key)
58
+ @actions.delete(val)
59
+ end
60
+
61
+ def each(&block)
62
+ @actions.each(&block)
63
+ end
64
+
65
+ def each_with_index(&block)
66
+ @actions.each_with_index(&block)
67
+ end
68
+ end
69
+
70
+ end
@@ -41,9 +41,11 @@ module RubyMVC
41
41
 
42
42
  def link_activated(sender, link)
43
43
  puts "#link_activated(#{sender}, #{link})"
44
- m = RubyMVC.method_name(link).to_sym
44
+ uri = URI.parse(link)
45
+ params = CGI.parse(uri.query) if uri.query
46
+ m = RubyMVC.method_name(uri.path).to_sym
45
47
  if self.respond_to? m
46
- self.send(m, sender, link)
48
+ self.send(m, sender, link, params)
47
49
  end
48
50
  end
49
51
  end
@@ -24,6 +24,8 @@
24
24
  #++
25
25
 
26
26
  require 'active_record'
27
+ require 'ruby_mvc/models/ar_table_model'
28
+ require 'ruby_mvc/views/ar_support'
27
29
 
28
30
  module RubyMVC
29
31
 
@@ -23,6 +23,8 @@
23
23
  #####################################################################
24
24
  #++
25
25
 
26
+ require 'ruby_mvc/models/model'
27
+ require 'ruby_mvc/models/view_model_template'
26
28
  require 'ruby_mvc/models/table_model'
27
29
  require 'ruby_mvc/models/array_table_model'
28
30
  require 'ruby_mvc/models/keyed_array_table_model'
@@ -0,0 +1,133 @@
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_table_model.rb
21
+ # Created: Sun 11 Dec 2011 10:38:34 CST
22
+ #
23
+ #####################################################################
24
+ #++
25
+
26
+ module RubyMVC
27
+ module Models
28
+
29
+ # This class provides an adapter between the ActiveRecord
30
+ # model classes and the RubyMVC TableModel interface. This
31
+ # class is designed to be able to provide access to either
32
+ # all instances of a particular AR table or only a subset of
33
+ # the rows matching a particular query.
34
+
35
+ class ActiveRecordTableModel < TableModel
36
+ attr_reader :keys
37
+
38
+ def initialize(entity_type, rows = nil)
39
+ super()
40
+ @row_idx = []
41
+ @entity_type = entity_type
42
+ @rows = rows
43
+ @keys = @entity_type.attribute_names.sort
44
+
45
+ # FIXME: this is a hack because I'm not sure how best to
46
+ # ensure we have the rows we need
47
+ self.each { |r| }
48
+ end
49
+
50
+ def create_rows(count = 1)
51
+ rows = []
52
+ count.times { rows << @entity_type.new }
53
+ rows
54
+ end
55
+
56
+ def insert_row(index, row)
57
+ @row_idx.insert(index, row)
58
+ super(index, row)
59
+ end
60
+
61
+ def insert_rows(index, rows)
62
+ if index == -1
63
+ @row_idx.concat(rows)
64
+ else
65
+ rows.each_with_index do |row, i|
66
+ @row_idx.insert(index + i, row)
67
+ end
68
+ end
69
+ super(index, rows)
70
+ end
71
+
72
+ def remove_row(index)
73
+ if row = @row_idx.delete_at(index)
74
+ @entity_type.delete(row[@entity_type.primary_key])
75
+ signal_emit("rows-removed", self, index, [ row ])
76
+ end
77
+ row
78
+ end
79
+
80
+ def remove_rows(index, count)
81
+ rows = []
82
+ count.times do
83
+ rows << @row_idx.delete_at(index)
84
+ @entity_type.delete(rows.last[@entity_type.primary_key])
85
+ end
86
+ signal_emit("rows-removed", self, index, rows)
87
+ rows
88
+ end
89
+
90
+ def update_row(index, row)
91
+ @row_idx[index] = row
92
+ super
93
+ end
94
+
95
+ def [](index)
96
+ @row_idx[index]
97
+ end
98
+
99
+ def each(&block)
100
+ @row_idx.clear
101
+ _rows.each do |row|
102
+ @row_idx << row
103
+ block.call(row)
104
+ end
105
+ end
106
+
107
+ def each_with_index(&block)
108
+ @row_idx.clear
109
+ _rows.each_with_index do |row, i|
110
+ @row_idx << row
111
+ block.call(row, i)
112
+ end
113
+ end
114
+
115
+ def value_for(row, key)
116
+ @row_idx[row][key]
117
+ end
118
+
119
+ def size
120
+ puts "idx.size: #{@row_idx.size}"
121
+ [_rows.count, @row_idx.size].max
122
+ end
123
+
124
+ protected
125
+ def _rows
126
+ x = @rows || @entity_type.find(:all)
127
+ puts "working with #{x.count} rows"
128
+ x
129
+ end
130
+ end
131
+
132
+ end
133
+ end