qml 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.
- checksums.yaml +7 -0
- data/.gitignore +46 -0
- data/.rspec +2 -0
- data/.travis.yml +15 -0
- data/.yardopts +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +351 -0
- data/Rakefile +6 -0
- data/examples/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/examples/fizzbuzz/fizzbuzz.rb +43 -0
- data/examples/fizzbuzz/main.qml +38 -0
- data/examples/imageprovider/imageprovider.rb +57 -0
- data/examples/imageprovider/main.qml +51 -0
- data/examples/todo/main.qml +70 -0
- data/examples/todo/todo.rb +36 -0
- data/examples/twitter/main.qml +36 -0
- data/examples/twitter/twitter.rb +55 -0
- data/ext/qml/accessclass.cpp +71 -0
- data/ext/qml/accessclass.h +19 -0
- data/ext/qml/accessobject.cpp +30 -0
- data/ext/qml/accessobject.h +22 -0
- data/ext/qml/application.cpp +54 -0
- data/ext/qml/application.h +17 -0
- data/ext/qml/common.h +18 -0
- data/ext/qml/ext_accesssupport.cpp +77 -0
- data/ext/qml/ext_accesssupport.h +42 -0
- data/ext/qml/ext_gcmarker.cpp +39 -0
- data/ext/qml/ext_gcmarker.h +27 -0
- data/ext/qml/ext_kernel.cpp +62 -0
- data/ext/qml/ext_kernel.h +11 -0
- data/ext/qml/ext_metaobject.cpp +410 -0
- data/ext/qml/ext_metaobject.h +62 -0
- data/ext/qml/ext_pluginloader.cpp +55 -0
- data/ext/qml/ext_pluginloader.h +32 -0
- data/ext/qml/ext_pointer.cpp +134 -0
- data/ext/qml/ext_pointer.h +43 -0
- data/ext/qml/ext_testutil.cpp +42 -0
- data/ext/qml/ext_testutil.h +11 -0
- data/ext/qml/extconf.rb +84 -0
- data/ext/qml/foreignclass.cpp +72 -0
- data/ext/qml/foreignclass.h +88 -0
- data/ext/qml/foreignmetaobject.cpp +345 -0
- data/ext/qml/foreignmetaobject.h +46 -0
- data/ext/qml/foreignobject.cpp +22 -0
- data/ext/qml/foreignobject.h +21 -0
- data/ext/qml/functioninfo.h +16 -0
- data/ext/qml/init.cpp +69 -0
- data/ext/qml/listmodel.cpp +112 -0
- data/ext/qml/listmodel.h +43 -0
- data/ext/qml/markable.h +12 -0
- data/ext/qml/objectdata.cpp +26 -0
- data/ext/qml/objectdata.h +20 -0
- data/ext/qml/objectgc.cpp +69 -0
- data/ext/qml/objectgc.h +28 -0
- data/ext/qml/plugins/core/applicationextension.cpp +34 -0
- data/ext/qml/plugins/core/applicationextension.h +28 -0
- data/ext/qml/plugins/core/componentextension.cpp +41 -0
- data/ext/qml/plugins/core/componentextension.h +28 -0
- data/ext/qml/plugins/core/contextextension.cpp +39 -0
- data/ext/qml/plugins/core/contextextension.h +29 -0
- data/ext/qml/plugins/core/core.pro +29 -0
- data/ext/qml/plugins/core/coreplugin.cpp +87 -0
- data/ext/qml/plugins/core/coreplugin.h +49 -0
- data/ext/qml/plugins/core/engineextension.cpp +27 -0
- data/ext/qml/plugins/core/engineextension.h +28 -0
- data/ext/qml/plugins/core/imageprovider.cpp +38 -0
- data/ext/qml/plugins/core/imageprovider.h +18 -0
- data/ext/qml/plugins/core/imagerequestpromise.cpp +19 -0
- data/ext/qml/plugins/core/imagerequestpromise.h +21 -0
- data/ext/qml/plugins/core/qmlexception.cpp +11 -0
- data/ext/qml/plugins/core/qmlexception.h +17 -0
- data/ext/qml/plugins/testutil/objectlifechecker.cpp +17 -0
- data/ext/qml/plugins/testutil/objectlifechecker.h +24 -0
- data/ext/qml/plugins/testutil/ownershiptest.cpp +26 -0
- data/ext/qml/plugins/testutil/ownershiptest.h +30 -0
- data/ext/qml/plugins/testutil/testobject.cpp +6 -0
- data/ext/qml/plugins/testutil/testobject.h +108 -0
- data/ext/qml/plugins/testutil/testobjectsubclass.cpp +10 -0
- data/ext/qml/plugins/testutil/testobjectsubclass.h +19 -0
- data/ext/qml/plugins/testutil/testutil.pro +20 -0
- data/ext/qml/plugins/testutil/testutilplugin.cpp +47 -0
- data/ext/qml/plugins/testutil/testutilplugin.h +32 -0
- data/ext/qml/qmltyperegisterer.cpp +74 -0
- data/ext/qml/qmltyperegisterer.h +30 -0
- data/ext/qml/rubyclass.cpp +94 -0
- data/ext/qml/rubyclass.h +234 -0
- data/ext/qml/rubyvalue.cpp +690 -0
- data/ext/qml/rubyvalue.h +256 -0
- data/ext/qml/signalforwarder.cpp +66 -0
- data/ext/qml/signalforwarder.h +29 -0
- data/ext/qml/util.cpp +120 -0
- data/ext/qml/util.h +101 -0
- data/ext/qml/valuereference.cpp +50 -0
- data/ext/qml/valuereference.h +22 -0
- data/ext/qml/weakvaluereference.cpp +27 -0
- data/ext/qml/weakvaluereference.h +19 -0
- data/lib/qml.rb +41 -0
- data/lib/qml/access.rb +137 -0
- data/lib/qml/application.rb +139 -0
- data/lib/qml/class_builder.rb +126 -0
- data/lib/qml/component.rb +53 -0
- data/lib/qml/context.rb +71 -0
- data/lib/qml/data.rb +2 -0
- data/lib/qml/data/array_model.rb +103 -0
- data/lib/qml/data/error.rb +5 -0
- data/lib/qml/data/list_model.rb +146 -0
- data/lib/qml/dispatchable.rb +34 -0
- data/lib/qml/dispatcher.rb +61 -0
- data/lib/qml/engine.rb +54 -0
- data/lib/qml/error_converter.rb +15 -0
- data/lib/qml/errors.rb +26 -0
- data/lib/qml/geometry.rb +3 -0
- data/lib/qml/geometry/point.rb +5 -0
- data/lib/qml/geometry/rectangle.rb +5 -0
- data/lib/qml/geometry/size.rb +5 -0
- data/lib/qml/image_provider.rb +87 -0
- data/lib/qml/meta_object.rb +20 -0
- data/lib/qml/models.rb +1 -0
- data/lib/qml/name_helper.rb +12 -0
- data/lib/qml/platform.rb +15 -0
- data/lib/qml/plugin_loader.rb +46 -0
- data/lib/qml/plugins.rb +26 -0
- data/lib/qml/qml.rb +1 -0
- data/lib/qml/qt.rb +6 -0
- data/lib/qml/qt_classes.rb +9 -0
- data/lib/qml/qt_object_base.rb +108 -0
- data/lib/qml/reactive.rb +8 -0
- data/lib/qml/reactive/bindable.rb +79 -0
- data/lib/qml/reactive/chained_signal.rb +25 -0
- data/lib/qml/reactive/error.rb +5 -0
- data/lib/qml/reactive/object.rb +278 -0
- data/lib/qml/reactive/property.rb +19 -0
- data/lib/qml/reactive/signal.rb +116 -0
- data/lib/qml/reactive/signal_spy.rb +27 -0
- data/lib/qml/reactive/signals/map_signal.rb +21 -0
- data/lib/qml/reactive/signals/merge_signal.rb +21 -0
- data/lib/qml/reactive/signals/select_signal.rb +21 -0
- data/lib/qml/reactive/simple_property.rb +17 -0
- data/lib/qml/reactive/unbound_property.rb +42 -0
- data/lib/qml/reactive/unbound_signal.rb +51 -0
- data/lib/qml/root_path.rb +3 -0
- data/lib/qml/test_util.rb +1 -0
- data/lib/qml/test_util/object_life_checker.rb +17 -0
- data/lib/qml/version.rb +3 -0
- data/lib/qml/wrappable.rb +9 -0
- data/qml.gemspec +28 -0
- data/spec/assets/testobj.qml +5 -0
- data/spec/qml/.access_spec.rb.swp +0 -0
- data/spec/qml/access_spec.rb +162 -0
- data/spec/qml/application_spec.rb +43 -0
- data/spec/qml/component_spec.rb +44 -0
- data/spec/qml/context_spec.rb +43 -0
- data/spec/qml/conversion_spec.rb +59 -0
- data/spec/qml/data/array_model_spec.rb +215 -0
- data/spec/qml/dispatchable_spec.rb +26 -0
- data/spec/qml/dispatcher_spec.rb +48 -0
- data/spec/qml/geometry/point_spec.rb +4 -0
- data/spec/qml/geometry/rectangle_spec.rb +4 -0
- data/spec/qml/geometry/size_spec.rb +4 -0
- data/spec/qml/plugin_loader_spec.rb +33 -0
- data/spec/qml/qt_object_base_spec.rb +119 -0
- data/spec/qml/reactive/object_spec.rb +273 -0
- data/spec/qml/reactive/property_spec.rb +70 -0
- data/spec/qml/reactive/signal_spec.rb +191 -0
- data/spec/qml/reactive/signal_spy_spec.rb +26 -0
- data/spec/qml/test_object_spec.rb +186 -0
- data/spec/qml_spec.rb +7 -0
- data/spec/spec_helper.rb +5 -0
- metadata +321 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'qml/reactive/error'
|
|
2
|
+
require 'qml/reactive/simple_property'
|
|
3
|
+
require 'qml/reactive/bindable'
|
|
4
|
+
|
|
5
|
+
module QML
|
|
6
|
+
module Reactive
|
|
7
|
+
class Property < SimpleProperty
|
|
8
|
+
include Bindable
|
|
9
|
+
|
|
10
|
+
# @param initial_value the initial value.
|
|
11
|
+
# @yield the initial property binding (optional).
|
|
12
|
+
def initialize(initial_value = nil, &block)
|
|
13
|
+
super()
|
|
14
|
+
self.value = initial_value if initial_value
|
|
15
|
+
bind(&block) if block
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
module QML
|
|
2
|
+
module Reactive
|
|
3
|
+
|
|
4
|
+
class Signal
|
|
5
|
+
|
|
6
|
+
class Connection
|
|
7
|
+
def initialize(signal, listener)
|
|
8
|
+
@signal = signal
|
|
9
|
+
@listener = listener
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Disconnects the connection.
|
|
13
|
+
def disconnect
|
|
14
|
+
@signal.disconnect(@listener)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
attr_reader :arity
|
|
19
|
+
|
|
20
|
+
# Initializes the Signal.
|
|
21
|
+
# The signal will be variadic if an empty array is given.
|
|
22
|
+
# @param [Array<#to_sym>, Array<()>] params The parameter names.
|
|
23
|
+
def initialize(*params, variadic: false)
|
|
24
|
+
@listeners = []
|
|
25
|
+
if variadic
|
|
26
|
+
@params = nil
|
|
27
|
+
@arity = -1
|
|
28
|
+
else
|
|
29
|
+
@params = params.map(&:to_sym)
|
|
30
|
+
@arity = params.size
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Calls every connected procedure with given arguments.
|
|
35
|
+
# Raises an ArgumentError when the arity is wrong.
|
|
36
|
+
# @param args the arguments.
|
|
37
|
+
def emit(*args)
|
|
38
|
+
if @arity >= 0 && args.size != @arity
|
|
39
|
+
fail ::ArgumentError ,"wrong number of arguments for signal (#{args.size} for #{@arity})"
|
|
40
|
+
end
|
|
41
|
+
@listeners.each do |listener|
|
|
42
|
+
listener.call(*args)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
alias_method :call, :emit
|
|
47
|
+
alias_method :[], :emit
|
|
48
|
+
|
|
49
|
+
# Returns the format of the parameters in the same format as Proc#parameters.
|
|
50
|
+
# @return [Array<Array<Symbol>>]
|
|
51
|
+
def parameters
|
|
52
|
+
@params ? @params.map { |arg| [:req, arg] } : [[:rest, :args]]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Converts the signal into a Proc.
|
|
56
|
+
# @return [Proc]
|
|
57
|
+
def to_proc
|
|
58
|
+
method(:emit).to_proc
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Returns the number of connections.
|
|
62
|
+
# @return [Integer]
|
|
63
|
+
def connection_count
|
|
64
|
+
@listeners.size
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Connects a procedure.
|
|
68
|
+
# @yield called when #emit is called.
|
|
69
|
+
# @return [QML::Reactive::Signal::Connection]
|
|
70
|
+
def connect(&listener)
|
|
71
|
+
@listeners << listener
|
|
72
|
+
connected(listener)
|
|
73
|
+
Connection.new(self, listener)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
alias_method :each, :connect
|
|
77
|
+
|
|
78
|
+
# Disconnects a procedure.
|
|
79
|
+
# @param listener
|
|
80
|
+
# @return [self]
|
|
81
|
+
def disconnect(listener)
|
|
82
|
+
@listeners.delete(listener)
|
|
83
|
+
disconnected(listener)
|
|
84
|
+
self
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Creates a transformed version of the signal.
|
|
88
|
+
# @return [QML::Reactive::Signal]
|
|
89
|
+
def map(&block)
|
|
90
|
+
Signals::MapSignal.new(self, block)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
alias_method :collect, :map
|
|
94
|
+
|
|
95
|
+
# Creates a filtered version of the signal.
|
|
96
|
+
# @return [QML::Reactive::Signal]
|
|
97
|
+
def select(&block)
|
|
98
|
+
Signals::SelectSignal.new(self, block)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Creates a merged signal.
|
|
102
|
+
# @return [QML::Reactive::Signal]
|
|
103
|
+
def merge(*others)
|
|
104
|
+
Signals::MergeSignal.new([self] + others)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def connected(listener)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def disconnected(listener)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module QML
|
|
2
|
+
module Reactive
|
|
3
|
+
|
|
4
|
+
class Signal
|
|
5
|
+
def spy
|
|
6
|
+
SignalSpy.new(self)
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class SignalSpy
|
|
11
|
+
|
|
12
|
+
attr_reader :args
|
|
13
|
+
|
|
14
|
+
def initialize(signal)
|
|
15
|
+
@args = []
|
|
16
|
+
signal.connect(&method(:on_emitted))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def on_emitted(*args)
|
|
22
|
+
@args << args
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'qml/reactive/chained_signal'
|
|
2
|
+
|
|
3
|
+
module QML
|
|
4
|
+
module Reactive
|
|
5
|
+
module Signals
|
|
6
|
+
class MapSignal < ChainedSignal
|
|
7
|
+
def initialize(source, func)
|
|
8
|
+
super(:mapped)
|
|
9
|
+
@source = source
|
|
10
|
+
@func = func
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def connect_to_sources
|
|
14
|
+
@source.connect do |*args|
|
|
15
|
+
emit(@func[*args])
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'qml/reactive/chained_signal'
|
|
2
|
+
|
|
3
|
+
module QML
|
|
4
|
+
module Reactive
|
|
5
|
+
module Signals
|
|
6
|
+
class MergeSignal < ChainedSignal
|
|
7
|
+
def initialize(sources)
|
|
8
|
+
param_count = sources.map(&:arity).max
|
|
9
|
+
super(*param_count.times.map { |i| :"arg#{i}" })
|
|
10
|
+
@sources = sources
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def connect_to_sources
|
|
14
|
+
@sources.each do |source|
|
|
15
|
+
source.connect(&method(:emit))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'qml/reactive/chained_signal'
|
|
2
|
+
|
|
3
|
+
module QML
|
|
4
|
+
module Reactive
|
|
5
|
+
module Signals
|
|
6
|
+
class SelectSignal < ChainedSignal
|
|
7
|
+
def initialize(source, pred)
|
|
8
|
+
super(*source.parameters.map(&:last))
|
|
9
|
+
@source = source
|
|
10
|
+
@pred = pred
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def connect_to_sources
|
|
14
|
+
@source.connect do |*args|
|
|
15
|
+
emit(*args) if @pred.call(*args)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'qml/reactive/signal'
|
|
2
|
+
|
|
3
|
+
module QML
|
|
4
|
+
module Reactive
|
|
5
|
+
class SimpleProperty
|
|
6
|
+
attr_accessor :value
|
|
7
|
+
|
|
8
|
+
# @!attribute [r] changed
|
|
9
|
+
# @return [QML::Reactive::Signal] The notification signal that is emitted when the value is changed
|
|
10
|
+
attr_reader :changed
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@changed = Signal.new(:new_value)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'qml/reactive/property'
|
|
2
|
+
require 'qml/reactive/unbound_signal'
|
|
3
|
+
|
|
4
|
+
module QML
|
|
5
|
+
module Reactive
|
|
6
|
+
class UnboundProperty
|
|
7
|
+
attr_reader :name, :initial_value, :initial_binding, :owner, :notifier_signal, :original
|
|
8
|
+
|
|
9
|
+
def initialize(name, initial_value, initial_binding, owner, factory = nil)
|
|
10
|
+
@name = name
|
|
11
|
+
@initial_value = initial_value
|
|
12
|
+
@initial_binding = initial_binding
|
|
13
|
+
@owner = owner
|
|
14
|
+
@notifier_signal = UnboundSignal.new(:"#{name}_changed", [:new_value], false, owner)
|
|
15
|
+
@factory = factory
|
|
16
|
+
@original = name
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def alias(name)
|
|
20
|
+
notifier_signal_orig = @notifier_signal
|
|
21
|
+
dup.tap do |property|
|
|
22
|
+
property.instance_eval do
|
|
23
|
+
@name = name
|
|
24
|
+
@notifier_signal = notifier_signal_orig.alias(:"#{name}_changed")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def alias?
|
|
30
|
+
@original != @name
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def bind(obj)
|
|
34
|
+
return @factory.call(obj, self) if @factory
|
|
35
|
+
Property.new.tap do |p|
|
|
36
|
+
p.value = @initial_value if @initial_value
|
|
37
|
+
p.bind { obj.instance_eval &@initial_binding } if @initial_binding
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'qml/reactive/signal'
|
|
2
|
+
|
|
3
|
+
module QML
|
|
4
|
+
module Reactive
|
|
5
|
+
class UnboundSignal
|
|
6
|
+
attr_reader :name, :owner, :original
|
|
7
|
+
|
|
8
|
+
def initialize(name, params, variadic, owner, factory = nil)
|
|
9
|
+
@name = name
|
|
10
|
+
@params = params
|
|
11
|
+
@variadic = variadic
|
|
12
|
+
@owner = owner
|
|
13
|
+
@factory = factory
|
|
14
|
+
@original = name
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def alias(name)
|
|
18
|
+
dup.tap do |signal|
|
|
19
|
+
signal.instance_eval do
|
|
20
|
+
@name = name
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def variadic?
|
|
26
|
+
@variadic
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def alias?
|
|
30
|
+
@original != @name
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def arity
|
|
34
|
+
@params ? @params.size : -1
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def parameters
|
|
38
|
+
@params ? @params.map { |arg| [:req, arg] } : [[:rest, :args]]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def bind(obj)
|
|
42
|
+
return @factory.call(obj, self) if @factory
|
|
43
|
+
if @variadic
|
|
44
|
+
Signal.new(variadic: true)
|
|
45
|
+
else
|
|
46
|
+
Signal.new(*@params)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'qml/test_util/object_life_checker'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'qml/plugins'
|
|
2
|
+
|
|
3
|
+
module QML
|
|
4
|
+
module TestUtil
|
|
5
|
+
|
|
6
|
+
ObjectLifeChecker = Plugins.test_util.meta_objects['RubyQml::ObjectLifeChecker'].build_class
|
|
7
|
+
|
|
8
|
+
class ObjectLifeChecker
|
|
9
|
+
|
|
10
|
+
def self.new(obj)
|
|
11
|
+
Plugins.test_util.create_object_life_checker(obj)
|
|
12
|
+
end
|
|
13
|
+
alias_method :alive?, :is_alive
|
|
14
|
+
alias_method :owned_by_qml?, :is_owned_by_qml
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/qml/version.rb
ADDED
data/qml.gemspec
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'qml/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "qml"
|
|
8
|
+
spec.version = QML::VERSION
|
|
9
|
+
spec.authors = ["Ryohei Ikegami"]
|
|
10
|
+
spec.email = ["iofg2100@gmail.com"]
|
|
11
|
+
spec.summary = %q{A QML / Qt Quick wrapper for Ruby}
|
|
12
|
+
spec.description = "ruby-qml provides bindings between QML and Ruby and enables you to use Qt Quick-based GUI from Ruby."
|
|
13
|
+
spec.homepage = "https://github.com/seanchas116/ruby-qml"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
spec.extensions = ["ext/qml/extconf.rb"]
|
|
21
|
+
|
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
|
23
|
+
spec.add_development_dependency "rake", "~> 10.3"
|
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
|
25
|
+
spec.add_development_dependency 'pry'
|
|
26
|
+
spec.add_development_dependency 'celluloid'
|
|
27
|
+
spec.add_development_dependency 'twitter'
|
|
28
|
+
end
|
|
Binary file
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe QML::Access do
|
|
4
|
+
class Foo
|
|
5
|
+
include QML::Access
|
|
6
|
+
|
|
7
|
+
property :text
|
|
8
|
+
signal :some_signal, [:arg]
|
|
9
|
+
|
|
10
|
+
def some_method(a, b)
|
|
11
|
+
a + b
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def variadic_method(*args)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Bar < Foo
|
|
19
|
+
def some_method(a, b)
|
|
20
|
+
'overridden'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def bar_method
|
|
24
|
+
'bar'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
let(:context) { QML::Context.new }
|
|
29
|
+
let(:component) { QML::Component.new context: context, data: data }
|
|
30
|
+
let(:root) { component.create }
|
|
31
|
+
|
|
32
|
+
describe '.register_to_qml' do
|
|
33
|
+
|
|
34
|
+
context 'when namespace, version, name are given' do
|
|
35
|
+
|
|
36
|
+
class Hoge
|
|
37
|
+
include QML::Access
|
|
38
|
+
|
|
39
|
+
register_to_qml under: 'HogeNS', version: '1.2', name: 'Hoge'
|
|
40
|
+
|
|
41
|
+
property :text
|
|
42
|
+
|
|
43
|
+
def some_method(a, b)
|
|
44
|
+
a + b
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
let(:data) do
|
|
49
|
+
<<-EOS
|
|
50
|
+
import QtQuick 2.2
|
|
51
|
+
import HogeNS 1.2
|
|
52
|
+
Item {
|
|
53
|
+
id: root
|
|
54
|
+
property var bound: hoge.text + hoge.text
|
|
55
|
+
Hoge { id: hoge }
|
|
56
|
+
}
|
|
57
|
+
EOS
|
|
58
|
+
end
|
|
59
|
+
it 'registers the class as a QML type' do
|
|
60
|
+
expect { component.create }.not_to raise_error
|
|
61
|
+
end
|
|
62
|
+
describe 'Hoge#some_method' do
|
|
63
|
+
it 'returns value' do
|
|
64
|
+
expect(root.qml_eval('hoge.some_method(100, 200)')).to eq 300
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
describe 'Hoge text property' do
|
|
68
|
+
it 'can be used to property binding' do
|
|
69
|
+
root.qml_eval('hoge').text = "foo"
|
|
70
|
+
expect(root.qml_eval('root').bound).to eq 'foofoo'
|
|
71
|
+
root.qml_eval('hoge').text = "bar"
|
|
72
|
+
expect(root.qml_eval('root').bound).to eq 'barbar'
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'when arguments are omitted' do
|
|
78
|
+
|
|
79
|
+
module HogeModule
|
|
80
|
+
VERSION = '0.1.0'
|
|
81
|
+
class Hoge
|
|
82
|
+
include QML::Access
|
|
83
|
+
register_to_qml
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
let(:data) do
|
|
88
|
+
<<-EOS
|
|
89
|
+
import HogeModule 0.1
|
|
90
|
+
Hoge {}
|
|
91
|
+
EOS
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'guesses them from the Ruby class name, namespace and VERSION constant' do
|
|
95
|
+
expect { component.create }.not_to raise_error
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
context 'when used in context' do
|
|
101
|
+
|
|
102
|
+
let(:data) do
|
|
103
|
+
<<-EOS
|
|
104
|
+
import QtQuick 2.2
|
|
105
|
+
Item {
|
|
106
|
+
id: root
|
|
107
|
+
property string text: foo.text + foo.text
|
|
108
|
+
Connections {
|
|
109
|
+
id: connections
|
|
110
|
+
target: foo
|
|
111
|
+
property var args
|
|
112
|
+
onSome_signal: {
|
|
113
|
+
args = [arg]
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
EOS
|
|
118
|
+
end
|
|
119
|
+
let(:foo) { Foo.new }
|
|
120
|
+
let(:bar) { Bar.new }
|
|
121
|
+
|
|
122
|
+
before do
|
|
123
|
+
context[:foo] = foo
|
|
124
|
+
context[:bar] = bar
|
|
125
|
+
root
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
describe 'Foo#some_method' do
|
|
129
|
+
it 'returns value' do
|
|
130
|
+
expect(root.qml_eval('foo.some_method(100, 200)')).to eq 300
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
describe 'Bar#some_method' do
|
|
134
|
+
it 'returns value' do
|
|
135
|
+
expect(root.qml_eval('bar.some_method(100, 200)')).to eq 'overridden'
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
describe 'Foo#variadic_method' do
|
|
139
|
+
it 'will not be exported' do
|
|
140
|
+
expect { root.qml_eval('foo.variadic_method()') }.to raise_error(QML::QMLError)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
describe 'Foo text property' do
|
|
144
|
+
it 'can get and set value' do
|
|
145
|
+
root.qml_eval('foo').text = 'test'
|
|
146
|
+
expect(root.qml_eval('foo').text).to eq 'test'
|
|
147
|
+
end
|
|
148
|
+
it 'can be used for property binding' do
|
|
149
|
+
foo.text = 'hoge'
|
|
150
|
+
expect(root.qml_eval('root.text')).to eq 'hogehoge'
|
|
151
|
+
foo.text = 'piyo'
|
|
152
|
+
expect(root.qml_eval('root.text')).to eq 'piyopiyo'
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
describe 'Foo some_signal signal' do
|
|
156
|
+
it 'can be connected' do
|
|
157
|
+
foo.some_signal.emit('foo')
|
|
158
|
+
expect(root.qml_eval('connections.args')).to eq ['foo']
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|