ruby_mvc 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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