qml 0.0.5 → 0.0.6
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 +4 -4
- data/README.md +57 -4
- data/changes.md +8 -0
- data/examples/fizzbuzz/fizzbuzz.rb +1 -1
- data/examples/imageprovider/imageprovider.rb +1 -1
- data/examples/todo_array/todo_array.rb +1 -1
- data/examples/todo_sequel/todo_sequel.rb +1 -1
- data/examples/twitter/twitter.rb +1 -1
- data/ext/qml/accessclass.cpp +5 -9
- data/ext/qml/conversionerror.h +14 -0
- data/ext/qml/ext_metaobject.cpp +30 -41
- data/ext/qml/init.cpp +5 -7
- data/ext/qml/rubyclass.cpp +6 -18
- data/ext/qml/rubyclass.h +22 -26
- data/ext/qml/rubyvalue.cpp +155 -221
- data/ext/qml/rubyvalue.h +30 -63
- data/ext/qml/signalforwarder.cpp +1 -3
- data/ext/qml/util.cpp +2 -25
- data/ext/qml/util.h +1 -21
- data/ext/qml/weakvaluereference.cpp +4 -5
- data/lib/qml/access.rb +9 -17
- data/lib/qml/application.rb +18 -21
- data/lib/qml/context.rb +1 -1
- data/lib/qml/dispatcher.rb +0 -1
- data/lib/qml/error_converter.rb +1 -0
- data/lib/qml/meta_object.rb +3 -3
- data/lib/qml/qt_object_base.rb +130 -5
- data/lib/qml/reactive/object.rb +34 -25
- data/lib/qml/reactive/signal.rb +6 -10
- data/lib/qml/reactive/unbound_property.rb +1 -1
- data/lib/qml/reactive/unbound_signal.rb +2 -2
- data/lib/qml/version.rb +1 -1
- data/spec/qml/reactive/object_spec.rb +14 -38
- data/spec/qml/reactive/signal_spec.rb +1 -1
- data/spec/qml/reactive/unbound_property_spec.rb +40 -0
- data/spec/qml/reactive/unbound_signal_spec.rb +70 -0
- data/spec/{shared_examples → shared}/qml/data/list_model.rb +0 -0
- data/spec/shared/qml/reactive/object.rb +39 -0
- data/spec/spec_helper.rb +1 -1
- metadata +12 -6
- data/lib/qml/class_builder.rb +0 -129
data/ext/qml/rubyvalue.h
CHANGED
@@ -42,11 +42,7 @@ public:
|
|
42
42
|
template <typename ... TArgs>
|
43
43
|
RubyValue send(ID method, TArgs ... args) const
|
44
44
|
{
|
45
|
-
|
46
|
-
std::array<VALUE, argc> argv = {{ VALUE(args)... }};
|
47
|
-
return protect([&] {
|
48
|
-
return rb_funcall2(mValue, method, argc, argv.data());
|
49
|
-
});
|
45
|
+
return rb_funcall(mValue, method, sizeof...(args), args...);
|
50
46
|
}
|
51
47
|
|
52
48
|
template <typename ... TArgs>
|
@@ -59,7 +55,11 @@ public:
|
|
59
55
|
bool operator!=(const RubyValue &other) const { return !operator==(other); }
|
60
56
|
explicit operator bool() const { return RTEST(mValue); }
|
61
57
|
|
62
|
-
bool isKindOf(const
|
58
|
+
bool isKindOf(const RubyValue &module) const
|
59
|
+
{
|
60
|
+
return RTEST(rb_obj_is_kind_of(mValue, module));
|
61
|
+
}
|
62
|
+
|
63
63
|
bool isConvertibleTo(int metaType) const;
|
64
64
|
int defaultMetaType() const;
|
65
65
|
|
@@ -99,16 +99,8 @@ struct Conversion<bool>
|
|
99
99
|
template <typename T>
|
100
100
|
struct Conversion<T, typename std::enable_if<std::is_signed<T>::value && std::is_integral<T>::value>::type>
|
101
101
|
{
|
102
|
-
static T from(RubyValue x)
|
103
|
-
{
|
104
|
-
return protect([&] {
|
105
|
-
return NUM2LL(x);
|
106
|
-
});
|
107
|
-
}
|
108
|
-
static RubyValue to(T x)
|
109
|
-
{
|
110
|
-
return LL2NUM(x);
|
111
|
-
}
|
102
|
+
static T from(RubyValue x) { return NUM2LL(x); }
|
103
|
+
static RubyValue to(T x) { return LL2NUM(x); }
|
112
104
|
};
|
113
105
|
|
114
106
|
// unsigned integers
|
@@ -116,16 +108,8 @@ struct Conversion<T, typename std::enable_if<std::is_signed<T>::value && std::is
|
|
116
108
|
template <typename T>
|
117
109
|
struct Conversion<T, typename std::enable_if<std::is_unsigned<T>::value && std::is_integral<T>::value>::type>
|
118
110
|
{
|
119
|
-
static T from(RubyValue x)
|
120
|
-
{
|
121
|
-
return protect([&] {
|
122
|
-
return NUM2ULL(x);
|
123
|
-
});
|
124
|
-
}
|
125
|
-
static RubyValue to(T x)
|
126
|
-
{
|
127
|
-
return ULL2NUM(x);
|
128
|
-
}
|
111
|
+
static T from(RubyValue x) { return NUM2ULL(x); }
|
112
|
+
static RubyValue to(T x) { return ULL2NUM(x); }
|
129
113
|
};
|
130
114
|
|
131
115
|
// floating point values
|
@@ -135,14 +119,12 @@ struct Conversion<T, typename std::enable_if<std::is_floating_point<T>::value>::
|
|
135
119
|
{
|
136
120
|
static T from(RubyValue x)
|
137
121
|
{
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
}
|
145
|
-
});
|
122
|
+
auto type = rb_type(x);
|
123
|
+
if (type == T_FIXNUM || type == T_BIGNUM) {
|
124
|
+
return double(NUM2LL(x));
|
125
|
+
} else {
|
126
|
+
return RFLOAT_VALUE(VALUE(x));
|
127
|
+
}
|
146
128
|
}
|
147
129
|
static RubyValue to(T x)
|
148
130
|
{
|
@@ -161,9 +143,7 @@ struct Conversion<T<V>, typename std::enable_if<IsQListLike<T<V>>::value>::type>
|
|
161
143
|
{
|
162
144
|
static T<V> from(RubyValue x)
|
163
145
|
{
|
164
|
-
|
165
|
-
x = rb_convert_type(x, T_ARRAY, "Array", "to_ary");
|
166
|
-
});
|
146
|
+
x = rb_convert_type(x, T_ARRAY, "Array", "to_ary");
|
167
147
|
int length = RARRAY_LEN(VALUE(x));
|
168
148
|
T<V> list;
|
169
149
|
list.reserve(length);
|
@@ -174,14 +154,10 @@ struct Conversion<T<V>, typename std::enable_if<IsQListLike<T<V>>::value>::type>
|
|
174
154
|
}
|
175
155
|
static RubyValue to(const T<V> &list)
|
176
156
|
{
|
177
|
-
|
178
|
-
return rb_ary_new();
|
179
|
-
});
|
157
|
+
auto ary = rb_ary_new();
|
180
158
|
for (const auto &elem : list) {
|
181
159
|
auto x = RubyValue::from(elem);
|
182
|
-
|
183
|
-
rb_ary_push(ary, x);
|
184
|
-
});
|
160
|
+
rb_ary_push(ary, x);
|
185
161
|
}
|
186
162
|
return ary;
|
187
163
|
}
|
@@ -198,34 +174,25 @@ struct Conversion<T<K, V>, typename std::enable_if<IsQHashLike<T<K, V>>::value>:
|
|
198
174
|
{
|
199
175
|
static T<K, V> from(RubyValue x)
|
200
176
|
{
|
201
|
-
|
202
|
-
|
203
|
-
});
|
177
|
+
x = rb_convert_type(x, T_HASH, "Hash", "to_hash");
|
178
|
+
|
204
179
|
T<K, V> hash;
|
205
|
-
|
206
|
-
auto
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
};
|
213
|
-
auto eachPtr = (int (*)(VALUE, VALUE, VALUE))each;
|
214
|
-
rb_hash_foreach(x, (int (*)(...))eachPtr, (VALUE)(&hash));
|
215
|
-
});
|
180
|
+
auto each = [](VALUE key, VALUE value, VALUE arg) -> int {
|
181
|
+
auto &hash = *reinterpret_cast<T<K, V> *>(arg);
|
182
|
+
hash[RubyValue(key).to<K>()] = RubyValue(value).to<V>();
|
183
|
+
return ST_CONTINUE;
|
184
|
+
};
|
185
|
+
auto eachPtr = (int (*)(VALUE, VALUE, VALUE))each;
|
186
|
+
rb_hash_foreach(x, (int (*)(...))eachPtr, (VALUE)(&hash));
|
216
187
|
return hash;
|
217
188
|
}
|
218
189
|
static RubyValue to(const T<K, V> &hash)
|
219
190
|
{
|
220
|
-
|
221
|
-
return rb_hash_new();
|
222
|
-
});
|
191
|
+
auto rubyHash = rb_hash_new();
|
223
192
|
for (auto i = hash.begin(); i != hash.end(); ++i) {
|
224
193
|
auto k = RubyValue::from(i.key());
|
225
194
|
auto v = RubyValue::from(i.value());
|
226
|
-
|
227
|
-
rb_hash_aset(rubyHash, k, v);
|
228
|
-
});
|
195
|
+
rb_hash_aset(rubyHash, k, v);
|
229
196
|
}
|
230
197
|
return rubyHash;
|
231
198
|
}
|
data/ext/qml/signalforwarder.cpp
CHANGED
@@ -56,9 +56,7 @@ void SignalForwarder::callProc(const QVariantList &list)
|
|
56
56
|
if (mProcRef.hasValue()) {
|
57
57
|
withGvl([&] {
|
58
58
|
auto args = RubyValue::from(list);
|
59
|
-
|
60
|
-
rb_funcall2(mProcRef.value(), rb_intern("call"), RARRAY_LEN(VALUE(args)), RARRAY_PTR(VALUE(args)));
|
61
|
-
});
|
59
|
+
rb_apply(mProcRef.value(), RUBYQML_INTERN("call"), args);
|
62
60
|
});
|
63
61
|
}
|
64
62
|
}
|
data/ext/qml/util.cpp
CHANGED
@@ -16,32 +16,14 @@ void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_
|
|
16
16
|
|
17
17
|
namespace RubyQml {
|
18
18
|
|
19
|
-
void
|
19
|
+
void convertCppErrors(const std::function<void ()> &doAction) noexcept
|
20
20
|
{
|
21
|
-
auto callback = [](VALUE data) {
|
22
|
-
auto &doAction= *reinterpret_cast<const std::function<void ()> *>(data);
|
23
|
-
doAction();
|
24
|
-
return Qnil;
|
25
|
-
};
|
26
|
-
int state;
|
27
|
-
rb_protect(callback, reinterpret_cast<VALUE>(&doAction), &state);
|
28
|
-
if (state) {
|
29
|
-
throw RubyException(state);
|
30
|
-
}
|
31
|
-
}
|
32
|
-
|
33
|
-
void unprotect(const std::function<void ()> &doAction) noexcept
|
34
|
-
{
|
35
|
-
int state = 0;
|
36
21
|
bool cppErrorOccured= false;
|
37
22
|
VALUE cppErrorClassName = Qnil;
|
38
23
|
VALUE cppErrorMessage = Qnil;
|
39
24
|
try {
|
40
25
|
doAction();
|
41
26
|
}
|
42
|
-
catch (const RubyException &ex) {
|
43
|
-
state = ex.state();
|
44
|
-
}
|
45
27
|
catch (const std::exception &ex) {
|
46
28
|
cppErrorOccured = true;
|
47
29
|
int status;
|
@@ -50,9 +32,6 @@ void unprotect(const std::function<void ()> &doAction) noexcept
|
|
50
32
|
free(classname);
|
51
33
|
cppErrorMessage = rb_str_new_cstr(ex.what());
|
52
34
|
}
|
53
|
-
if (state) {
|
54
|
-
rb_jump_tag(state);
|
55
|
-
}
|
56
35
|
if (cppErrorOccured) {
|
57
36
|
auto patterns = rb_funcall(rb_path2class("QML::ErrorConverter"), rb_intern("patterns"), 0);
|
58
37
|
auto rubyClass = rb_hash_aref(patterns, cppErrorClassName);
|
@@ -127,9 +106,7 @@ void withGvl(const std::function<void ()> &doAction)
|
|
127
106
|
void fail(const char *errorClassName, const QString &message)
|
128
107
|
{
|
129
108
|
auto msg = message.toUtf8();
|
130
|
-
|
131
|
-
rb_raise(rb_path2class(errorClassName), "%s", msg.data());
|
132
|
-
});
|
109
|
+
rb_raise(rb_path2class(errorClassName), "%s", msg.data());
|
133
110
|
}
|
134
111
|
|
135
112
|
}
|
data/ext/qml/util.h
CHANGED
@@ -54,27 +54,7 @@ private:
|
|
54
54
|
int mState = 0;
|
55
55
|
};
|
56
56
|
|
57
|
-
|
58
|
-
// Convert Ruby exceptions into C++ exceptions (RubyException)
|
59
|
-
void protect(const std::function<void()> &doAction);
|
60
|
-
|
61
|
-
template <typename F>
|
62
|
-
typename std::enable_if<
|
63
|
-
!std::is_same<typename std::result_of<F()>::type, void>::value,
|
64
|
-
typename std::result_of<F()>::type>::type
|
65
|
-
protect(const F &doAction)
|
66
|
-
{
|
67
|
-
typename std::result_of<F()>::type ret;
|
68
|
-
protect([&] {
|
69
|
-
ret = doAction();
|
70
|
-
});
|
71
|
-
return ret;
|
72
|
-
}
|
73
|
-
|
74
|
-
// Regenerate Ruby exceptions that are converted into RubyException
|
75
|
-
// and convert std::exception exceptions into Ruby errors.
|
76
|
-
// Other C++ exceptions are not allowed to be thrown out of this function.
|
77
|
-
void unprotect(const std::function<void()> &doAction) noexcept;
|
57
|
+
void convertCppErrors(const std::function<void()> &doAction) noexcept;
|
78
58
|
|
79
59
|
void rescue(const std::function<void ()> &doAction, const std::function<void (RubyValue)> &handleException);
|
80
60
|
void rescueNotify(const std::function<void ()> &doAction);
|
@@ -32,11 +32,10 @@ WeakValueReference::WeakValueReference(RubyValue value) :
|
|
32
32
|
d->mHasValue = true;
|
33
33
|
d->mValue = value;
|
34
34
|
static auto objspace = RubyModule::fromPath("ObjectSpace");
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
});
|
35
|
+
|
36
|
+
auto proc = rb_proc_new((VALUE (*)(...))&Data::finalize, Ext_AnyWrapper::create(QVariant::fromValue(d)));
|
37
|
+
VALUE args[] = { value };
|
38
|
+
rb_funcall_with_block(objspace, RUBYQML_INTERN("define_finalizer"), 1, args, proc);
|
40
39
|
}
|
41
40
|
|
42
41
|
bool WeakValueReference::hasValue() const
|
data/lib/qml/access.rb
CHANGED
@@ -11,13 +11,11 @@ module QML
|
|
11
11
|
include Dispatchable
|
12
12
|
include Wrappable
|
13
13
|
# @!parse include Reactive::Object
|
14
|
-
# @!parse include SignalInitialization
|
15
14
|
# @!parse extend ClassMethods
|
16
15
|
|
17
16
|
def self.included(derived)
|
18
17
|
derived.class_eval do
|
19
18
|
include Reactive::Object
|
20
|
-
include SignalInitialization
|
21
19
|
extend ClassMethods
|
22
20
|
end
|
23
21
|
end
|
@@ -113,26 +111,20 @@ module QML
|
|
113
111
|
end
|
114
112
|
end
|
115
113
|
|
116
|
-
module SignalInitialization
|
117
|
-
def initialize(*args, &block)
|
118
|
-
super
|
119
|
-
signal_names = signals + properties.map { |name| :"#{name}_changed" }
|
120
|
-
signal_names.each do |name|
|
121
|
-
__send__(name).connect do |*args|
|
122
|
-
@access_wrappers.each do |obj|
|
123
|
-
obj.class.meta_object.invoke_method(obj.pointer, name, args)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
114
|
# @api private
|
131
115
|
attr_reader :access_wrappers
|
132
116
|
|
133
117
|
def initialize(*args, &block)
|
134
|
-
|
118
|
+
signal_names = signals + properties.map { |name| :"#{name}_changed" }
|
119
|
+
signal_names.each do |name|
|
120
|
+
__send__(name).connect do |*args|
|
121
|
+
@access_wrappers.each do |obj|
|
122
|
+
obj.class.meta_object.invoke_method(obj.pointer, name, args)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
135
126
|
@access_wrappers = []
|
127
|
+
super
|
136
128
|
end
|
137
129
|
|
138
130
|
def create_wrapper
|
data/lib/qml/application.rb
CHANGED
@@ -106,29 +106,26 @@ module QML
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
-
#
|
110
|
-
#
|
111
|
-
# @return [Application]
|
112
|
-
# @overload application
|
113
|
-
# Call {init} if ruby-qml is not initialized, then yields the application instance and then call {Application#exec}.
|
114
|
-
# @return [Application]
|
115
|
-
# @example
|
116
|
-
# QML.application do |app|
|
117
|
-
# app.context[:foo] = 'foo'
|
118
|
-
# app.load_path Pathname(__FILE__) + '../main.qml'
|
119
|
-
# end
|
120
|
-
# @see Application.instance
|
109
|
+
# Returns the instance of {Application}.
|
110
|
+
# @return [Application]
|
121
111
|
def application
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
112
|
+
Application.instance
|
113
|
+
end
|
114
|
+
|
115
|
+
# Call {init} if ruby-qml is not initialized, then yields the application instance and then call {Application#exec}.
|
116
|
+
# @return [Application]
|
117
|
+
# @example
|
118
|
+
# QML.run do |app|
|
119
|
+
# app.context[:foo] = 'foo'
|
120
|
+
# app.load_path Pathname(__FILE__) + '../main.qml'
|
121
|
+
# end
|
122
|
+
def run
|
123
|
+
QML.init unless QML.initialized?
|
124
|
+
Application.instance.tap do |app|
|
125
|
+
yield app
|
126
|
+
app.exec
|
130
127
|
end
|
131
128
|
end
|
132
129
|
|
133
|
-
module_function :application
|
130
|
+
module_function :application, :run
|
134
131
|
end
|
data/lib/qml/context.rb
CHANGED
data/lib/qml/dispatcher.rb
CHANGED
data/lib/qml/error_converter.rb
CHANGED
data/lib/qml/meta_object.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'qml/qml'
|
2
|
-
require 'qml/
|
2
|
+
require 'qml/qt_object_base'
|
3
3
|
|
4
4
|
module QML
|
5
5
|
class MetaObject
|
@@ -12,9 +12,9 @@ module QML
|
|
12
12
|
def build_class
|
13
13
|
@@classes ||= {}
|
14
14
|
klass = @@classes[name]
|
15
|
-
builder =
|
15
|
+
builder = QtObjectBase::SubclassBuilder.new(self, klass)
|
16
16
|
builder.build
|
17
|
-
@@classes[name] = builder.
|
17
|
+
@@classes[name] = builder.subclass
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
data/lib/qml/qt_object_base.rb
CHANGED
@@ -1,7 +1,50 @@
|
|
1
1
|
require 'qml/dispatchable'
|
2
|
+
require 'qml/name_helper'
|
2
3
|
|
3
4
|
module QML
|
4
5
|
|
6
|
+
class QtPropertyBase
|
7
|
+
attr_reader :changed
|
8
|
+
|
9
|
+
def initialize(metaobj, objptr, name)
|
10
|
+
super()
|
11
|
+
@metaobj = metaobj
|
12
|
+
@objptr = objptr
|
13
|
+
@name = name
|
14
|
+
@changed = QtSignal.new(metaobj, objptr, @metaobj.notify_signal(@name))
|
15
|
+
end
|
16
|
+
|
17
|
+
def value=(newval)
|
18
|
+
@metaobj.set_property(@objptr, @name, newval)
|
19
|
+
end
|
20
|
+
|
21
|
+
def value
|
22
|
+
@metaobj.get_property(@objptr, @name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class QtProperty < QtPropertyBase
|
27
|
+
include Reactive::Bindable
|
28
|
+
end
|
29
|
+
|
30
|
+
class QtSignal < Reactive::Signal
|
31
|
+
def initialize(metaobj, objptr, name)
|
32
|
+
super(nil)
|
33
|
+
@objptr = objptr
|
34
|
+
@metaobj = metaobj
|
35
|
+
@name = name
|
36
|
+
@initialized = false
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def connected(block)
|
42
|
+
return if @initialized
|
43
|
+
@metaobj.connect_signal(@objptr, @name, method(:emit))
|
44
|
+
@initialized = true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
5
48
|
# {QtObjectBase} is the base class for Qt object wrappers.
|
6
49
|
#
|
7
50
|
# In ruby-qml you can access the followings of Qt objects in Ruby.
|
@@ -33,6 +76,93 @@ module QML
|
|
33
76
|
include Dispatchable
|
34
77
|
include Reactive::Object
|
35
78
|
|
79
|
+
# @api private
|
80
|
+
class SubclassBuilder
|
81
|
+
|
82
|
+
attr_reader :subclass
|
83
|
+
|
84
|
+
def initialize(metaobj, klass)
|
85
|
+
@metaobj = metaobj
|
86
|
+
@subclass = klass
|
87
|
+
end
|
88
|
+
|
89
|
+
def build
|
90
|
+
create unless @subclass
|
91
|
+
return if @subclass.meta_object == @metaobj
|
92
|
+
|
93
|
+
@metaobj.method_names.reject { |name| @metaobj.signal?(name) }.each do |name|
|
94
|
+
define_method(name)
|
95
|
+
end
|
96
|
+
@metaobj.method_names.select { |name| @metaobj.signal?(name) }.each do |name|
|
97
|
+
define_signal(name)
|
98
|
+
end
|
99
|
+
@metaobj.property_names.each do |name|
|
100
|
+
define_property(name)
|
101
|
+
end
|
102
|
+
@metaobj.enumerators.each do |k, v|
|
103
|
+
define_enum(k, v)
|
104
|
+
end
|
105
|
+
@subclass.__send__ :meta_object=, @metaobj
|
106
|
+
|
107
|
+
self
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def create
|
113
|
+
super_metaobj = @metaobj.super_class
|
114
|
+
@subclass = Class.new(super_metaobj ? super_metaobj.build_class : QtObjectBase)
|
115
|
+
end
|
116
|
+
|
117
|
+
def define_method(name)
|
118
|
+
metaobj = @metaobj
|
119
|
+
return if metaobj.private?(name)
|
120
|
+
underscore = NameHelper.to_underscore(name)
|
121
|
+
|
122
|
+
@subclass.class_eval do
|
123
|
+
define_method name do |*args|
|
124
|
+
metaobj.invoke_method(@pointer, name, args)
|
125
|
+
end
|
126
|
+
private name if metaobj.protected?(name)
|
127
|
+
alias_method underscore, name unless underscore == name
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def define_signal(name)
|
132
|
+
metaobj = @metaobj
|
133
|
+
underscore = NameHelper.to_underscore(name)
|
134
|
+
@subclass.class_eval do
|
135
|
+
variadic_signal name, signal: -> { QtSignal.new(metaobj, @pointer, name) }
|
136
|
+
alias_signal underscore, name unless underscore == name
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def define_property(name)
|
141
|
+
metaobj = @metaobj
|
142
|
+
underscore = NameHelper.to_underscore(name)
|
143
|
+
@subclass.class_eval do
|
144
|
+
property name, nil, property: -> { QtProperty.new(metaobj, @pointer, name) }
|
145
|
+
alias_property underscore, name unless underscore == name
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def define_enum(name, hash)
|
150
|
+
define_const(name, hash.values.sort)
|
151
|
+
hash.each do |k, v|
|
152
|
+
define_const(k, v)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def define_const(name, value)
|
157
|
+
name = (name[0].capitalize + name[1..-1]).to_sym
|
158
|
+
underscore = NameHelper.to_upper_underscore(name)
|
159
|
+
@subclass.class_eval do
|
160
|
+
const_set name, value
|
161
|
+
const_set underscore, value unless underscore == name
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
36
166
|
class << self
|
37
167
|
attr_accessor :meta_object
|
38
168
|
private :meta_object=
|
@@ -41,11 +171,6 @@ module QML
|
|
41
171
|
attr_accessor :pointer
|
42
172
|
private :pointer=
|
43
173
|
|
44
|
-
# @api private
|
45
|
-
def custom_data
|
46
|
-
@custom_data ||= {}
|
47
|
-
end
|
48
|
-
|
49
174
|
# Evaluates a JavaScript expression on the QML context of the object.
|
50
175
|
# Fails with {QMLError} when the object is not created by QML and does not belong to any context.
|
51
176
|
# @param [String] str
|