ironnails 0.0.1
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.
- data/Rakefile +21 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/ironnails.gemspec +96 -0
- data/lib/iron_nails.rb +1 -0
- data/lib/ironnails/bin/IronNails.Library.dll +0 -0
- data/lib/ironnails/bin/IronRuby.Libraries.Yaml.dll +0 -0
- data/lib/ironnails/bin/IronRuby.Libraries.dll +0 -0
- data/lib/ironnails/bin/IronRuby.dll +0 -0
- data/lib/ironnails/bin/Microsoft.Dynamic.dll +0 -0
- data/lib/ironnails/bin/Microsoft.Scripting.Core.dll +0 -0
- data/lib/ironnails/bin/Microsoft.Scripting.ExtensionAttribute.dll +0 -0
- data/lib/ironnails/bin/Microsoft.Scripting.dll +0 -0
- data/lib/ironnails/config/configuration.rb +141 -0
- data/lib/ironnails/config/initializer.rb +144 -0
- data/lib/ironnails/controller/base.rb +135 -0
- data/lib/ironnails/controller/view_operations.rb +101 -0
- data/lib/ironnails/controller.rb +2 -0
- data/lib/ironnails/core_ext/array.rb +15 -0
- data/lib/ironnails/core_ext/class/attribute_accessors.rb +57 -0
- data/lib/ironnails/core_ext/class.rb +8 -0
- data/lib/ironnails/core_ext/fixnum.rb +22 -0
- data/lib/ironnails/core_ext/hash.rb +32 -0
- data/lib/ironnails/core_ext/kernel.rb +26 -0
- data/lib/ironnails/core_ext/string.rb +58 -0
- data/lib/ironnails/core_ext/symbol.rb +78 -0
- data/lib/ironnails/core_ext/system/net/web_request.rb +110 -0
- data/lib/ironnails/core_ext/system/security/secure_string.rb +18 -0
- data/lib/ironnails/core_ext/system/windows/markup/xaml_reader.rb +6 -0
- data/lib/ironnails/core_ext/system/windows/ui_element.rb +17 -0
- data/lib/ironnails/core_ext/time.rb +28 -0
- data/lib/ironnails/core_ext.rb +12 -0
- data/lib/ironnails/errors.rb +19 -0
- data/lib/ironnails/iron_xml.rb +83 -0
- data/lib/ironnails/logger.rb +4 -0
- data/lib/ironnails/logging/buffered_logger.rb +137 -0
- data/lib/ironnails/logging/class_logger.rb +29 -0
- data/lib/ironnails/models/base.rb +16 -0
- data/lib/ironnails/models/bindable_collection.rb +15 -0
- data/lib/ironnails/models/model_mixin.rb +69 -0
- data/lib/ironnails/models.rb +3 -0
- data/lib/ironnails/nails_engine.rb +398 -0
- data/lib/ironnails/observable.rb +117 -0
- data/lib/ironnails/security/secure_string.rb +61 -0
- data/lib/ironnails/version.rb +11 -0
- data/lib/ironnails/view/collections.rb +117 -0
- data/lib/ironnails/view/commands/add_sub_view_command.rb +33 -0
- data/lib/ironnails/view/commands/behavior_command.rb +29 -0
- data/lib/ironnails/view/commands/command.rb +208 -0
- data/lib/ironnails/view/commands/event_command.rb +32 -0
- data/lib/ironnails/view/commands/timed_command.rb +40 -0
- data/lib/ironnails/view/commands.rb +5 -0
- data/lib/ironnails/view/view.rb +190 -0
- data/lib/ironnails/view/view_model.rb +45 -0
- data/lib/ironnails/view/xaml_proxy.rb +226 -0
- data/lib/ironnails/view.rb +5 -0
- data/lib/ironnails/wpf.rb +113 -0
- data/lib/ironnails/wpf_application.rb +30 -0
- data/lib/ironnails.rb +68 -0
- metadata +133 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
module IronNails
|
|
2
|
+
|
|
3
|
+
module View
|
|
4
|
+
|
|
5
|
+
# encapsulates what IronNails sees as a view.
|
|
6
|
+
# That is the xaml proxy and some meta data for
|
|
7
|
+
# IronNails.
|
|
8
|
+
class View
|
|
9
|
+
|
|
10
|
+
include IronNails::Logging::ClassLogger
|
|
11
|
+
include IronNails::Core::Observable
|
|
12
|
+
extend Forwardable
|
|
13
|
+
|
|
14
|
+
def_delegators :@proxy, :add_control, :add_command, :add_timer, :invoke, :get_property, :play_storyboard, :stop_storyboard
|
|
15
|
+
|
|
16
|
+
# gets or sets the name of this view
|
|
17
|
+
attr_accessor :name
|
|
18
|
+
|
|
19
|
+
# gets or sets the element name on the canvas for this view
|
|
20
|
+
attr_accessor :element_name
|
|
21
|
+
|
|
22
|
+
# gets or sets the xaml proxy that is associated with this view
|
|
23
|
+
attr_accessor :proxy
|
|
24
|
+
|
|
25
|
+
# gets or sets the parent of this view
|
|
26
|
+
attr_accessor :parent
|
|
27
|
+
|
|
28
|
+
# gets or sets the name of the component that will contain this view
|
|
29
|
+
attr_accessor :container
|
|
30
|
+
|
|
31
|
+
# gets or sets the name of the controller this view is associated with
|
|
32
|
+
attr_accessor :controller
|
|
33
|
+
|
|
34
|
+
# gets the flag that indicates if this view needs to be initialized or not
|
|
35
|
+
attr_reader :loaded
|
|
36
|
+
|
|
37
|
+
# gets the collection of children for this view
|
|
38
|
+
attr_reader :children
|
|
39
|
+
|
|
40
|
+
def initialize(options)
|
|
41
|
+
options.each do |k, v|
|
|
42
|
+
if k == :view_name
|
|
43
|
+
@name = v
|
|
44
|
+
else
|
|
45
|
+
instance_variable_set "@#{k}", v
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
@element_name ||= name
|
|
49
|
+
@children = []
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def added?
|
|
53
|
+
@added
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# indicates whether we initialized this view already or not
|
|
57
|
+
def loaded?
|
|
58
|
+
@loaded
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# indicates whether this view has to be rendered inside a component
|
|
62
|
+
def has_container?
|
|
63
|
+
!container.nil?
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# indicates whether this view has to set its datacontext in order to function
|
|
67
|
+
def sets_datacontext?
|
|
68
|
+
!has_parent? || !!@sets_datacontext
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# indicates whether this view has a parent
|
|
72
|
+
def has_parent?
|
|
73
|
+
!parent.nil?
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# adds this view to a component in an existing view
|
|
77
|
+
def add_control(target, control_proxy)
|
|
78
|
+
proxy.add_control(target, control_proxy)
|
|
79
|
+
self
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def dispatcher
|
|
83
|
+
proxy.instance.dispatcher
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# loads this view into memory and adds the children if needed
|
|
87
|
+
def load(mode = :complete)
|
|
88
|
+
unless @loaded || mode == :reload
|
|
89
|
+
self.proxy = XamlProxy.load(name)
|
|
90
|
+
proxy.instance.name = element_name.to_s.to_clr_string if has_parent?
|
|
91
|
+
@loaded = true
|
|
92
|
+
#notify_observers :loaded, self
|
|
93
|
+
end
|
|
94
|
+
if has_container? && has_parent? && mode == :complete && !added?
|
|
95
|
+
parent.add_control(container, proxy)
|
|
96
|
+
@added = true
|
|
97
|
+
end
|
|
98
|
+
children.each { |cv| cv.load }
|
|
99
|
+
logger.debug("loaded view #{name}", IRONNAILS_FRAMEWORKNAME)
|
|
100
|
+
self
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# sets the data context of this view
|
|
104
|
+
def data_context=(value)
|
|
105
|
+
self.proxy.data_context = value
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# configures and then shows the window
|
|
109
|
+
def show
|
|
110
|
+
configure
|
|
111
|
+
self.proxy.show
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# configures and then returns an instance of the loaded view
|
|
115
|
+
def instance
|
|
116
|
+
configure
|
|
117
|
+
proxy.instance
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# configures the view, it loads it and then triggers the observers for further configuration
|
|
121
|
+
def configure
|
|
122
|
+
load
|
|
123
|
+
notify_observers :configuring, self
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# adds a child view definition to this view.
|
|
127
|
+
def add_child(options)
|
|
128
|
+
child = children.find { |vw| vw.name == options[:name] }
|
|
129
|
+
children.delete(child) unless child.nil?
|
|
130
|
+
children << View.new(options.merge(:parent => self, :controller => controller))
|
|
131
|
+
logger.debug("added child view (#{options[:name]} to #{name})", IRONNAILS_FRAMEWORKNAME)
|
|
132
|
+
self
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# returns whether this child view is alread contained by this view or not
|
|
136
|
+
def has_child?(view)
|
|
137
|
+
children.any? { |vw| vw == view }
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# # adds a command to this view
|
|
141
|
+
# def add_command(cmd)
|
|
142
|
+
# proxy.add_command cmd
|
|
143
|
+
# end
|
|
144
|
+
#
|
|
145
|
+
# # adds a timer to this view
|
|
146
|
+
# def add_timer(cmd)
|
|
147
|
+
# proxy.add_timer cmd
|
|
148
|
+
# end
|
|
149
|
+
|
|
150
|
+
# executes the code block on the view
|
|
151
|
+
def on_proxy(&b)
|
|
152
|
+
load
|
|
153
|
+
#proxy.instance_eval(&b)
|
|
154
|
+
b.call proxy
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# def invoke(target, method)
|
|
158
|
+
# proxy.invoke target, method
|
|
159
|
+
# end
|
|
160
|
+
|
|
161
|
+
# indicates whether this view has a data context set already or not
|
|
162
|
+
def has_datacontext?
|
|
163
|
+
!proxy.nil? && !proxy.instance.data_context.nil?
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def find(view_name)
|
|
167
|
+
return self if name == view_name.to_sym || view_name.nil?
|
|
168
|
+
children.find { |cv| cv.name == view_name }
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# equality comparer for easier selection
|
|
172
|
+
def ==(view)
|
|
173
|
+
view.respond_to?(:name) ? self.name == view.name : self.name = view.to_sym
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
alias_method :===, :==
|
|
177
|
+
alias_method :equals, :==
|
|
178
|
+
|
|
179
|
+
# sorting comparer for ordering lists
|
|
180
|
+
def <=>(view)
|
|
181
|
+
self.name <=> command.view.name
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
alias_method :compare_to, :<=>
|
|
185
|
+
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module IronNails
|
|
2
|
+
|
|
3
|
+
module View
|
|
4
|
+
|
|
5
|
+
# The base class for view models in an IronNails application.
|
|
6
|
+
module ViewModelMixin
|
|
7
|
+
|
|
8
|
+
include IronNails::Logging::ClassLogger
|
|
9
|
+
|
|
10
|
+
def __view_model_name_
|
|
11
|
+
self.class.demodulize.underscore
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# adds a model for the view in the dictionary
|
|
15
|
+
def add_model(k, v)
|
|
16
|
+
unless self.respond_to?(k) && self.respond_to?(:"#{k}=")
|
|
17
|
+
logger.debug "adding object to the view model #{k}", IRONNAILS_FRAMEWORKNAME
|
|
18
|
+
self.class.send :attr_accessor, k
|
|
19
|
+
end
|
|
20
|
+
self.send :"#{k}=", v
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
alias_method :set_model, :add_model
|
|
24
|
+
|
|
25
|
+
# configures a command appropriately on the view.
|
|
26
|
+
# for an EventCommand it will pass it to the view and the view will attach the
|
|
27
|
+
# appropriate events
|
|
28
|
+
# for a TimedCommand it will create a timer in the view proxy object
|
|
29
|
+
# for a BehaviorCommand it will add the appropriate delegate command to the
|
|
30
|
+
# Commands dictionary on the ViewModel class
|
|
31
|
+
def add_command(cmd)
|
|
32
|
+
dc = cmd.to_clr_command
|
|
33
|
+
cmd_name = cmd.name.to_s
|
|
34
|
+
unless self.respond_to?(cmd_name.to_sym) && self.respond_to?(:"#{cmd_name}=")
|
|
35
|
+
logger.debug "adding command to the view model #{cmd_name}", IRONNAILS_FRAMEWORKNAME
|
|
36
|
+
self.class.send :attr_accessor, cmd_name.to_sym
|
|
37
|
+
end
|
|
38
|
+
self.send :"#{cmd_name}=", dc
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
module IronNails
|
|
2
|
+
|
|
3
|
+
module View
|
|
4
|
+
|
|
5
|
+
module Extensions
|
|
6
|
+
|
|
7
|
+
module ThreadingSupport
|
|
8
|
+
|
|
9
|
+
def on_ui_thread(element=:instance, &b)
|
|
10
|
+
send(element).dispatcher.begin_invoke(DispatcherPriority.normal, Action.new(&b))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Schedules this command to execute on a different thread
|
|
14
|
+
# and schedules the update of the view on the UI thread.
|
|
15
|
+
def on_new_thread(request, &b)
|
|
16
|
+
cb = WaitCallback.new do
|
|
17
|
+
begin
|
|
18
|
+
# b.call
|
|
19
|
+
blk = lambda { |obj| b.call }
|
|
20
|
+
instance.dispatcher.begin_invoke(DispatcherPriority.normal, Action.of(System::Object).new(&blk), request.call )
|
|
21
|
+
rescue Exception => e
|
|
22
|
+
logger.error "#{e.message}"
|
|
23
|
+
MessageBox.Show("There was a problem. #{e.message}")
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
ThreadPool.queue_user_work_item cb
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module CommandSupport
|
|
32
|
+
|
|
33
|
+
include IronNails::View::Extensions::ThreadingSupport
|
|
34
|
+
|
|
35
|
+
def execute_command(command)
|
|
36
|
+
unless command.asynchronous?
|
|
37
|
+
command.execute
|
|
38
|
+
else
|
|
39
|
+
on_new_thread(lambda { command.execute }) { command.refresh_view }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
module TimerSupport
|
|
46
|
+
|
|
47
|
+
include IronNails::View::Extensions::CommandSupport
|
|
48
|
+
|
|
49
|
+
def add_timer(command)
|
|
50
|
+
command.view = self
|
|
51
|
+
@attached = false
|
|
52
|
+
instance_variable_set "@#{command.timer_name}", DispatcherTimer.new
|
|
53
|
+
ti = get_timer_for command
|
|
54
|
+
ti.interval = command.interval.to_timespan
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def start_timer(command)
|
|
58
|
+
ti = get_timer_for command
|
|
59
|
+
ti.tick do
|
|
60
|
+
execute_command command if command.can_execute?
|
|
61
|
+
end unless attached?
|
|
62
|
+
@attached = true
|
|
63
|
+
ti.start
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def attached?
|
|
67
|
+
!!@attached
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def stop_timer(command)
|
|
71
|
+
ti = get_timer_for command
|
|
72
|
+
ti.stop
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def get_timer_for(command)
|
|
78
|
+
instance_variable_get "@#{command.timer_name}"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
module EventSupport
|
|
84
|
+
|
|
85
|
+
include IronNails::View::Extensions::CommandSupport
|
|
86
|
+
|
|
87
|
+
# Adds the specified +command+ to this view
|
|
88
|
+
def add_command(command)
|
|
89
|
+
command.view = self
|
|
90
|
+
ele = (command.affinity || command.element).to_sym
|
|
91
|
+
send(command.element.to_sym).send(command.trigger.to_sym) do
|
|
92
|
+
on_ui_thread(ele) do
|
|
93
|
+
execute_command command
|
|
94
|
+
end if command.can_execute?
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
module SubViewSupport
|
|
101
|
+
|
|
102
|
+
# def add_sub_view(command)
|
|
103
|
+
# command.view = self
|
|
104
|
+
# command.execute if command.can_execute?
|
|
105
|
+
# end
|
|
106
|
+
|
|
107
|
+
# Adds a subview to the current view.
|
|
108
|
+
def add_control(target, view)
|
|
109
|
+
parent = send(target)
|
|
110
|
+
vw = view.respond_to?(:instance) ? view.instance : view
|
|
111
|
+
if parent.respond_to? :content=
|
|
112
|
+
parent.content = vw
|
|
113
|
+
elsif parent.respond_to? :children
|
|
114
|
+
parent.children.add vw
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# The IronNails::View::XamlProxy class wraps a xaml file and brings it alive
|
|
123
|
+
class XamlProxy
|
|
124
|
+
|
|
125
|
+
include IronNails::Logging::ClassLogger
|
|
126
|
+
include IronNails::View::Extensions::EventSupport
|
|
127
|
+
include IronNails::View::Extensions::TimerSupport
|
|
128
|
+
include IronNails::View::Extensions::SubViewSupport
|
|
129
|
+
include IronNails::Core::Observable
|
|
130
|
+
|
|
131
|
+
# gets or sets the name of the view
|
|
132
|
+
attr_accessor :view_name
|
|
133
|
+
|
|
134
|
+
# gets the instance of the view
|
|
135
|
+
attr_reader :instance
|
|
136
|
+
|
|
137
|
+
# gets or sets the extension for the view file.
|
|
138
|
+
# defaults to xaml
|
|
139
|
+
attr_accessor :view_extension
|
|
140
|
+
|
|
141
|
+
# gets the path to the view file
|
|
142
|
+
attr_reader :view_path
|
|
143
|
+
|
|
144
|
+
def initialize(name)
|
|
145
|
+
@view_name = name
|
|
146
|
+
@view_extension = ".xaml"
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# loads the view into the instance variable
|
|
150
|
+
def load_view
|
|
151
|
+
@instance = XamlReader.load_from_path view_path if File.exists? view_path
|
|
152
|
+
@instance = view_name.to_s.classify.new if @instance.nil?
|
|
153
|
+
@instance
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# returns the path to the file for the current view.
|
|
157
|
+
# this is the file we'll be the proxy for
|
|
158
|
+
def view_path
|
|
159
|
+
path = "#{IRONNAILS_VIEWS_ROOT}/#{view_name}#{view_extension}"
|
|
160
|
+
@view_path = path unless @view_path == path
|
|
161
|
+
@view_path
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def visibility=(visi)
|
|
165
|
+
instance.visibility = visi.to_sym.to_visibility if instance.respond_to?(:visibility)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# shows the proxied view
|
|
169
|
+
def show
|
|
170
|
+
WpfApplication.current.has_main_window? ? instance.show : instance
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def invoke(element, method, *args, &b)
|
|
174
|
+
instance.send(element.to_sym).send(method.to_sym, *args, &b)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def get_property(element, method, *args, &b)
|
|
178
|
+
send(element.to_sym).send(method.to_sym, *args, &b)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def play_storyboard(storyboard_name)
|
|
182
|
+
storyboard = instance.resources[storyboard_name.to_s.to_clr_string]
|
|
183
|
+
storyboard.begin instance unless storyboard.nil?
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def stop_storyboard(storyboard_name)
|
|
187
|
+
storyboard = instance.resources[storyboard_name.to_s.to_clr_string]
|
|
188
|
+
storyboard.stop instance unless storyboard.nil?
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# tells this proxy to render itself with the changed information
|
|
192
|
+
def refresh
|
|
193
|
+
@instance.refresh
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def method_missing(sym, *args, &blk)
|
|
197
|
+
# First we check if we can find a named control
|
|
198
|
+
# When we can't find a control we'll check if we can find
|
|
199
|
+
# a method on the view instance by that name, if that is the
|
|
200
|
+
# case we will call that method otherwise we'll return the control
|
|
201
|
+
# if we found one. When no method or control could be found we
|
|
202
|
+
# delegate to the default behavior
|
|
203
|
+
obj = @instance.find_name(sym.to_s.to_clr_string)
|
|
204
|
+
nmsym = sym.to_s.camelize.to_sym
|
|
205
|
+
if @instance.respond_to?(nmsym) && obj.nil?
|
|
206
|
+
@instance.send sym, *args, &blk
|
|
207
|
+
else
|
|
208
|
+
obj.nil? ? super : obj
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
class << self
|
|
213
|
+
|
|
214
|
+
# creates an instance of the view specified by the +view_name+
|
|
215
|
+
def load(view_name)
|
|
216
|
+
vw = new view_name.to_s
|
|
217
|
+
vw.load_view
|
|
218
|
+
vw
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
module IronNails
|
|
2
|
+
|
|
3
|
+
module Wpf
|
|
4
|
+
module Builders
|
|
5
|
+
def name_collector
|
|
6
|
+
@___name_collector_
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def [](name)
|
|
10
|
+
name_collector[name]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def inject_names(obj)
|
|
14
|
+
name_collector.each_pair { |k, v| obj.instance_variable_set("@#{k}".to_sym, v) }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def evaluate_properties(obj, args, &b)
|
|
18
|
+
obj.instance_variable_set(:@___name_collector_, name_collector)
|
|
19
|
+
|
|
20
|
+
args.each_pair do |k, v|
|
|
21
|
+
if k == :name
|
|
22
|
+
name_collector[v] = obj
|
|
23
|
+
end
|
|
24
|
+
if k == :binding
|
|
25
|
+
binding = Binding.new
|
|
26
|
+
binding.path = PropertyPath.new v[:property_name]
|
|
27
|
+
binding.source = v[:target]||self;
|
|
28
|
+
binding.mode = v[:mode]
|
|
29
|
+
obj.set_binding(v[:property], binding);
|
|
30
|
+
obj.owner = v[:target]||self
|
|
31
|
+
else
|
|
32
|
+
obj.send :"#{k.to_s}=", v
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if obj.respond_to? :name
|
|
37
|
+
name_collector[obj.name] = obj unless obj.name.nil?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
obj
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def add_object_to_name_collector(collection, obj, args = {}, &b)
|
|
44
|
+
obj = evaluate_properties(obj, args, &b)
|
|
45
|
+
obj.instance_eval(&b) unless b.nil?
|
|
46
|
+
collection.add obj
|
|
47
|
+
obj
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def add_class_to_name_collector(collection, klass, args = {}, &b)
|
|
51
|
+
obj = evaluate_properties(klass.new, args, &b)
|
|
52
|
+
obj.instance_eval(&b) unless b.nil?
|
|
53
|
+
collection.add obj
|
|
54
|
+
obj
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def assign_to_name_collector(property, klass, args = {}, &b)
|
|
58
|
+
obj = evaluate_properties(klass.new, args, &b)
|
|
59
|
+
obj.instance_eval(&b) unless b.nil?
|
|
60
|
+
self.send property, obj
|
|
61
|
+
obj
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def self.build(klass, args = {}, &b)
|
|
66
|
+
obj = klass.new
|
|
67
|
+
obj.instance_variable_set(:@___name_collector_, {})
|
|
68
|
+
|
|
69
|
+
args.each_pair do |k, v|
|
|
70
|
+
if k == :name
|
|
71
|
+
obj.name_collector[v] = obj
|
|
72
|
+
end
|
|
73
|
+
obj.send :"#{k.to_s}=", v
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
obj.instance_eval(&b) if b != nil
|
|
77
|
+
obj
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
class System::Windows::Data::Binding
|
|
83
|
+
alias_method :old_mode=, :mode=
|
|
84
|
+
|
|
85
|
+
def mode=(value)
|
|
86
|
+
self.old_mode = value.to_binding_mode
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class Panel
|
|
92
|
+
include IronNails::Wpf::Builders
|
|
93
|
+
|
|
94
|
+
def add(klass, args = {}, &b)
|
|
95
|
+
add_class_to_name_collector(children, klass, args, &b)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def add_name(name, obj)
|
|
99
|
+
name_collector[name] = obj
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def add_obj(obj)
|
|
103
|
+
add_object_to_name_collector(children, obj)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
alias_method :old_background=, :background=
|
|
107
|
+
|
|
108
|
+
def background=(color)
|
|
109
|
+
self.old_background = color.to_brush
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class WpfApplication < System::Windows::Application
|
|
2
|
+
|
|
3
|
+
include IronNails::Logging::ClassLogger
|
|
4
|
+
|
|
5
|
+
attr_reader :nails_engine
|
|
6
|
+
|
|
7
|
+
def initialize(&b)
|
|
8
|
+
logger.debug "Starting application", IRONNAILS_FRAMEWORKNAME
|
|
9
|
+
@nails_engine = NailsEngine.new
|
|
10
|
+
#@nails_engine = TestViewManager.new
|
|
11
|
+
controller = instance_eval &b
|
|
12
|
+
nails_engine.register_controller controller
|
|
13
|
+
nails_engine.show_initial_window controller do |view_instance|
|
|
14
|
+
@main_window = view_instance
|
|
15
|
+
run view_instance
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def has_main_window?
|
|
20
|
+
@main_window.nil?
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def set_skin(name)
|
|
24
|
+
self.resources.merged_dictionaries.add load_skin(name)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def load_skin(name)
|
|
28
|
+
XamlReader.load_from_path "#{IRONNAILS_ROOT}/skins/#{name}.xaml"
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/ironnails.rb
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'logger'
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'forwardable'
|
|
5
|
+
rescue LoadError => e
|
|
6
|
+
msg = "It looks like you tried to load the application without passing the"
|
|
7
|
+
msg << " library paths to IronRuby.\n"
|
|
8
|
+
msg << "You can fix that by passing the following switch to ir\n(replace C:\\tools\\ruby and c:\\tools\\ironruby with the paths for your configuration):\n"
|
|
9
|
+
msg << "ir -I 'C:\\tools\\ironruby\\libs;C:\\tools\\ruby\\lib\\ruby\\site_ruby\\1.8;C:\\tools\\ruby\\lib\\ruby\\1.8'\n"
|
|
10
|
+
msg << "or you could change the first line of the rake file (Rakefile.rb) to reflect your configuration\n"
|
|
11
|
+
raise LoadError.new(msg)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
IRONNAILS_ROOT = "#{File.dirname(__FILE__)}/../.." unless defined?(IRONNAILS_ROOT)
|
|
15
|
+
IRONNAILS_VIEWS_ROOT = "#{IRONNAILS_ROOT}/app/views" unless defined? IRONNAILS_VIEWS_ROOT
|
|
16
|
+
IRONNAILS_ENV = (ENV['IRONNAILS_ENV'] || 'development').dup unless defined?(IRONNAILS_ENV)
|
|
17
|
+
IRONNAILS_FRAMEWORKNAME = "IronNails Framework" unless defined?(IRONNAILS_FRAMEWORKNAME)
|
|
18
|
+
|
|
19
|
+
nails_vendor_lib = File.join(IRONNAILS_ROOT, "vendor/ironnails")
|
|
20
|
+
$:.unshift nails_vendor_lib if File.exist? nails_vendor_lib
|
|
21
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
|
22
|
+
|
|
23
|
+
%w(app/views app/helpers app/converters app/controllers app/models lib bin).each do |pth|
|
|
24
|
+
$:.unshift File.join(IRONNAILS_ROOT, pth)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# load .NET libraries
|
|
28
|
+
require 'System'
|
|
29
|
+
require 'WindowsBase'
|
|
30
|
+
require 'PresentationCore'
|
|
31
|
+
require 'PresentationFramework'
|
|
32
|
+
require 'System.Windows.Forms'
|
|
33
|
+
require 'System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
|
|
34
|
+
require 'System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
|
|
35
|
+
require 'WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
|
|
36
|
+
require 'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
|
|
37
|
+
require 'PresentationFramework.Aero, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
|
|
38
|
+
require 'System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
|
|
39
|
+
require 'System.Net, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
|
|
40
|
+
require 'System.ServiceModel.Web, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
|
|
41
|
+
require 'System.Windows.Presentation, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
|
|
42
|
+
require 'UIAutomationProvider, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
|
|
43
|
+
require 'System.Security, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
|
|
44
|
+
require "System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
|
|
45
|
+
|
|
46
|
+
# load IronNails static CLR helpers
|
|
47
|
+
require 'ironnails/bin/IronNails.Library.dll'
|
|
48
|
+
lst = System::Collections::Generic::List.of(System::String).new
|
|
49
|
+
$:.each {|pth| lst.add pth.to_clr_string }
|
|
50
|
+
IronNails::Library::DlrHelper.load_paths = lst
|
|
51
|
+
IronNails::Library::DlrHelper.app_root = IRONNAILS_ROOT
|
|
52
|
+
|
|
53
|
+
# load IronRuby files of the IronNails framework
|
|
54
|
+
require 'ironnails/version'
|
|
55
|
+
require 'ironnails/logger'
|
|
56
|
+
require 'ironnails/config/configuration'
|
|
57
|
+
require 'ironnails/config/initializer'
|
|
58
|
+
require 'ironnails/security/secure_string'
|
|
59
|
+
require 'ironnails/core_ext'
|
|
60
|
+
require 'ironnails/errors'
|
|
61
|
+
require 'ironnails/observable'
|
|
62
|
+
require 'ironnails/iron_xml'
|
|
63
|
+
require 'ironnails/view'
|
|
64
|
+
require 'ironnails/models'
|
|
65
|
+
require 'ironnails/controller'
|
|
66
|
+
require 'ironnails/nails_engine'
|
|
67
|
+
require 'ironnails/wpf_application'
|
|
68
|
+
|