glimmer-dsl-libui 0.9.6 → 0.10.0
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/CHANGELOG.md +12 -0
- data/README.md +439 -178
- data/VERSION +1 -1
- data/docs/examples/GLIMMER-DSL-LIBUI-ADVANCED-EXAMPLES.md +5 -5
- data/docs/examples/GLIMMER-DSL-LIBUI-BASIC-EXAMPLES.md +23 -0
- data/examples/basic_composite_shape.rb +2 -0
- data/examples/basic_custom_shape.rb +168 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/dsl/libui/custom_shape_expression.rb +58 -0
- data/lib/glimmer/dsl/libui/dsl.rb +1 -0
- data/lib/glimmer/dsl/libui/listener_expression.rb +6 -1
- data/lib/glimmer/launcher.rb +2 -5
- data/lib/glimmer/libui/custom_control.rb +25 -19
- data/lib/glimmer/libui/custom_shape.rb +258 -0
- data/lib/glimmer/rake_task/scaffold.rb +19 -18
- data/lib/glimmer/rake_task.rb +13 -13
- data/lib/glimmer-dsl-libui.rb +1 -1
- metadata +8 -4
@@ -0,0 +1,258 @@
|
|
1
|
+
# Copyright (c) 2021-2023 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'super_module'
|
23
|
+
require 'glimmer'
|
24
|
+
require 'glimmer/error'
|
25
|
+
require 'glimmer/proc_tracker'
|
26
|
+
require 'glimmer/data_binding/observer'
|
27
|
+
require 'glimmer/data_binding/observable_model'
|
28
|
+
|
29
|
+
module Glimmer
|
30
|
+
module LibUI
|
31
|
+
module CustomShape
|
32
|
+
include SuperModule
|
33
|
+
include DataBinding::ObservableModel
|
34
|
+
|
35
|
+
# This module was only created to prevent Glimmer from checking method_missing first
|
36
|
+
module GlimmerSupersedable
|
37
|
+
def method_missing(method_name, *args, &block)
|
38
|
+
# TODO Consider supporting a glimmer error silencing option for methods defined here
|
39
|
+
# but fail the glimmer DSL for the right reason to avoid seeing noise in the log output
|
40
|
+
if block && can_handle_listener?(method_name)
|
41
|
+
handle_listener(method_name, &block)
|
42
|
+
elsif @body_root.respond_to?(method_name, true)
|
43
|
+
@body_root.send(method_name, *args, &block)
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def respond_to?(method_name, *args, &block)
|
50
|
+
result = false
|
51
|
+
result ||= super
|
52
|
+
result ||= can_handle_listener?(method_name)
|
53
|
+
result ||= @body_root.respond_to?(method_name, *args, &block)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
super_module_included do |klass|
|
58
|
+
# TODO clear memoization of Shape.libui_class_for for a keyword if a custom shape was defined with that keyword
|
59
|
+
klass.include(Glimmer)
|
60
|
+
klass.include(GlimmerSupersedable) # prevent Glimmer from running method_missing first
|
61
|
+
Glimmer::LibUI::CustomShape.add_custom_shape_namespaces_for(klass)
|
62
|
+
end
|
63
|
+
|
64
|
+
class << self
|
65
|
+
def for(keyword)
|
66
|
+
unless flyweight_custom_shape_classes.keys.include?(keyword)
|
67
|
+
begin
|
68
|
+
extracted_namespaces = keyword.
|
69
|
+
to_s.
|
70
|
+
split(/__/).map do |namespace|
|
71
|
+
namespace.camelcase(:upper)
|
72
|
+
end
|
73
|
+
custom_shape_namespaces.each do |base|
|
74
|
+
extracted_namespaces.reduce(base) do |result, namespace|
|
75
|
+
if !result.constants.include?(namespace)
|
76
|
+
namespace = result.constants.detect {|c| c.to_s.upcase == namespace.to_s.upcase } || namespace
|
77
|
+
end
|
78
|
+
begin
|
79
|
+
flyweight_custom_shape_classes[keyword] = constant = result.const_get(namespace)
|
80
|
+
return constant if constant.ancestors.include?(Glimmer::LibUI::CustomShape)
|
81
|
+
flyweight_custom_shape_classes[keyword] = constant
|
82
|
+
rescue => e
|
83
|
+
# Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
|
84
|
+
flyweight_custom_shape_classes[keyword] = result
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
raise "#{keyword} has no custom shape class!"
|
89
|
+
rescue => e
|
90
|
+
Glimmer::Config.logger.debug {e.message}
|
91
|
+
Glimmer::Config.logger.debug {"#{e.message}\n#{e.backtrace.join("\n")}"}
|
92
|
+
flyweight_custom_shape_classes[keyword] = nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
flyweight_custom_shape_classes[keyword]
|
96
|
+
end
|
97
|
+
|
98
|
+
# Flyweight Design Pattern memoization cache. Can be cleared if memory is needed.
|
99
|
+
def flyweight_custom_shape_classes
|
100
|
+
@flyweight_custom_shape_classes ||= {}
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns keyword to use for this custom shape
|
104
|
+
def keyword
|
105
|
+
self.name.underscore.gsub('::', '__')
|
106
|
+
end
|
107
|
+
|
108
|
+
# Returns shortcut keyword to use for this custom shape (keyword minus namespace)
|
109
|
+
def shortcut_keyword
|
110
|
+
self.name.underscore.gsub('::', '__').split('__').last
|
111
|
+
end
|
112
|
+
|
113
|
+
def add_custom_shape_namespaces_for(klass)
|
114
|
+
Glimmer::LibUI::CustomShape.namespaces_for_class(klass).drop(1).each do |namespace|
|
115
|
+
Glimmer::LibUI::CustomShape.custom_shape_namespaces << namespace
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def namespaces_for_class(m)
|
120
|
+
return [m] if m.name.nil?
|
121
|
+
namespace_constants = m.name.split(/::/).map(&:to_sym)
|
122
|
+
namespace_constants.reduce([Object]) do |output, namespace_constant|
|
123
|
+
output += [output.last.const_get(namespace_constant)]
|
124
|
+
end[1..-1].uniq.reverse
|
125
|
+
end
|
126
|
+
|
127
|
+
def custom_shape_namespaces
|
128
|
+
@custom_shape_namespaces ||= reset_custom_shape_namespaces
|
129
|
+
end
|
130
|
+
|
131
|
+
def reset_custom_shape_namespaces
|
132
|
+
@custom_shape_namespaces = Set[Object, Glimmer::LibUI]
|
133
|
+
end
|
134
|
+
|
135
|
+
# Allows defining convenience option accessors for an array of option names
|
136
|
+
# Example: `options :color1, :color2` defines `#color1` and `#color2`
|
137
|
+
# where they return the instance values `options[:color1]` and `options[:color2]`
|
138
|
+
# respectively.
|
139
|
+
# Can be called multiple times to set more options additively.
|
140
|
+
# When passed no arguments, it returns list of all option names captured so far
|
141
|
+
def options(*new_options)
|
142
|
+
new_options = new_options.compact.map(&:to_s).map(&:to_sym)
|
143
|
+
if new_options.empty?
|
144
|
+
@options ||= {} # maps options to defaults
|
145
|
+
else
|
146
|
+
new_options = new_options.reduce({}) {|new_options_hash, new_option| new_options_hash.merge(new_option => nil)}
|
147
|
+
@options = options.merge(new_options)
|
148
|
+
def_option_attr_accessors(new_options)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def option(new_option, default: nil)
|
153
|
+
new_option = new_option.to_s.to_sym
|
154
|
+
new_options = {new_option => default}
|
155
|
+
@options = options.merge(new_options)
|
156
|
+
def_option_attr_accessors(new_options)
|
157
|
+
end
|
158
|
+
|
159
|
+
def def_option_attr_accessors(new_options)
|
160
|
+
new_options.each do |option, default|
|
161
|
+
class_eval <<-end_eval, __FILE__, __LINE__
|
162
|
+
def #{option}
|
163
|
+
options[:#{option}]
|
164
|
+
end
|
165
|
+
|
166
|
+
def #{option}=(option_value)
|
167
|
+
self.options[:#{option}] = option_value
|
168
|
+
end
|
169
|
+
end_eval
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def before_body(&block)
|
174
|
+
@before_body_block = block
|
175
|
+
end
|
176
|
+
|
177
|
+
def body(&block)
|
178
|
+
@body_block = block
|
179
|
+
end
|
180
|
+
|
181
|
+
def after_body(&block)
|
182
|
+
@after_body_block = block
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
attr_reader :body_root, :parent, :parent_proxy, :args, :keyword, :content, :options
|
187
|
+
|
188
|
+
def initialize(keyword, parent, args, options, &content)
|
189
|
+
@parent_proxy = @parent = parent
|
190
|
+
options ||= {}
|
191
|
+
@options = self.class.options.merge(options)
|
192
|
+
@content = ProcTracker.new(content) if content
|
193
|
+
execute_hook('before_body')
|
194
|
+
body_block = self.class.instance_variable_get("@body_block")
|
195
|
+
raise Glimmer::Error, 'Invalid custom shape for having no body! Please define body block!' if body_block.nil?
|
196
|
+
@body_root = instance_exec(&body_block)
|
197
|
+
raise Glimmer::Error, 'Invalid custom shape for having an empty body! Please fill body block!' if @body_root.nil?
|
198
|
+
execute_hook('after_body')
|
199
|
+
# TODO deregister all observer_registrations on destroy of the shape once that listener is supported
|
200
|
+
# (on_destroy) unless it is the last window closing, in which case exit faster
|
201
|
+
post_add_content if content.nil?
|
202
|
+
end
|
203
|
+
|
204
|
+
# Subclasses may override to perform post initialization work on an added child
|
205
|
+
def post_initialize_child(child)
|
206
|
+
# No Op by default
|
207
|
+
end
|
208
|
+
|
209
|
+
def post_add_content
|
210
|
+
# No Op by default
|
211
|
+
end
|
212
|
+
|
213
|
+
def observer_registrations
|
214
|
+
@observer_registrations ||= []
|
215
|
+
end
|
216
|
+
|
217
|
+
def can_handle_listener?(listener)
|
218
|
+
body_root&.can_handle_listener?(listener.to_s)
|
219
|
+
end
|
220
|
+
|
221
|
+
def handle_listener(listener, &block)
|
222
|
+
body_root.handle_listener(listener.to_s, &block)
|
223
|
+
end
|
224
|
+
|
225
|
+
# This method ensures it has an instance method not coming from Glimmer DSL
|
226
|
+
def has_instance_method?(method_name)
|
227
|
+
respond_to?(method_name) and
|
228
|
+
!@body_root.respond_to_libui?(method_name) and
|
229
|
+
(method(method_name) rescue nil) and
|
230
|
+
!method(method_name)&.source_location&.first&.include?('glimmer/dsl/engine.rb') and
|
231
|
+
!method(method_name)&.source_location&.first&.include?('glimmer/libui/shape.rb')
|
232
|
+
end
|
233
|
+
|
234
|
+
# Returns content block if used as an attribute reader (no args)
|
235
|
+
# Otherwise, if a block is passed, it adds it as content to this custom shape
|
236
|
+
def content(&block)
|
237
|
+
if block_given?
|
238
|
+
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Libui::CustomShapeExpression.new, self.class.keyword, &block)
|
239
|
+
else
|
240
|
+
@content
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
private
|
245
|
+
|
246
|
+
def execute_hook(hook_name)
|
247
|
+
hook_block = self.class.instance_variable_get("@#{hook_name}_block")
|
248
|
+
return if hook_block.nil?
|
249
|
+
temp_method_name = "#{hook_name}_block_#{hook_block.hash.abs}_#{(Time.now.to_f * 1_000_000).to_i}"
|
250
|
+
singleton_class.define_method(temp_method_name, &hook_block)
|
251
|
+
send(temp_method_name)
|
252
|
+
singleton_class.send(:remove_method, temp_method_name)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
Dir[File.expand_path("./#{File.basename(__FILE__, '.rb')}/*.rb", __dir__)].each {|f| require f}
|
@@ -219,7 +219,7 @@ module Glimmer
|
|
219
219
|
end
|
220
220
|
|
221
221
|
def custom_window_gem(custom_window_name, namespace)
|
222
|
-
gem_name = "glimmer-libui-cw-#{
|
222
|
+
gem_name = "glimmer-libui-cw-#{custom_window_name.underscore}"
|
223
223
|
gem_summary = "#{human_name(custom_window_name)} - Glimmer Custom Window"
|
224
224
|
begin
|
225
225
|
custom_window_keyword = dsl_control_name(custom_window_name)
|
@@ -229,7 +229,7 @@ module Glimmer
|
|
229
229
|
# No Op (keyword is not taken by a built in Ruby method)
|
230
230
|
end
|
231
231
|
if namespace
|
232
|
-
gem_name += "-#{
|
232
|
+
gem_name += "-#{namespace.underscore}"
|
233
233
|
gem_summary += " (#{human_name(namespace)})"
|
234
234
|
else
|
235
235
|
return puts('Namespace is required! Usage: glimmer scaffold:gem:customwindow[name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
|
@@ -292,10 +292,10 @@ module Glimmer
|
|
292
292
|
end
|
293
293
|
|
294
294
|
def custom_control_gem(custom_control_name, namespace)
|
295
|
-
gem_name = "glimmer-libui-cc-#{
|
295
|
+
gem_name = "glimmer-libui-cc-#{custom_control_name.underscore}"
|
296
296
|
gem_summary = "#{human_name(custom_control_name)} - Glimmer Custom Control"
|
297
297
|
if namespace
|
298
|
-
gem_name += "-#{
|
298
|
+
gem_name += "-#{namespace.underscore}"
|
299
299
|
gem_summary += " (#{human_name(namespace)})"
|
300
300
|
else
|
301
301
|
return puts('Namespace is required! Usage: glimmer scaffold:custom_control_gem[custom_control_name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
|
@@ -331,10 +331,10 @@ module Glimmer
|
|
331
331
|
end
|
332
332
|
|
333
333
|
def custom_shape_gem(custom_shape_name, namespace)
|
334
|
-
gem_name = "glimmer-libui-cs-#{
|
334
|
+
gem_name = "glimmer-libui-cs-#{custom_shape_name.underscore}"
|
335
335
|
gem_summary = "#{human_name(custom_shape_name)} - Glimmer Custom Shape"
|
336
336
|
if namespace
|
337
|
-
gem_name += "-#{
|
337
|
+
gem_name += "-#{namespace.underscore}"
|
338
338
|
gem_summary += " (#{human_name(namespace)})"
|
339
339
|
else
|
340
340
|
return puts('Namespace is required! Usage: glimmer scaffold:custom_shape_gem[custom_shape_name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
|
@@ -414,10 +414,6 @@ module Glimmer
|
|
414
414
|
app_name.underscore.titlecase
|
415
415
|
end
|
416
416
|
|
417
|
-
def compact_name(gem_name)
|
418
|
-
gem_name.underscore.camelcase.downcase
|
419
|
-
end
|
420
|
-
|
421
417
|
def gemfile(window_type)
|
422
418
|
APP_GEMFILE
|
423
419
|
end
|
@@ -436,8 +432,6 @@ module Glimmer
|
|
436
432
|
end
|
437
433
|
|
438
434
|
class #{class_name(app_name)}
|
439
|
-
include Glimmer
|
440
|
-
|
441
435
|
APP_ROOT = File.expand_path('../..', __FILE__)
|
442
436
|
VERSION = File.read(File.join(APP_ROOT, 'VERSION'))
|
443
437
|
LICENSE = File.read(File.join(APP_ROOT, 'LICENSE.txt'))
|
@@ -645,12 +639,11 @@ require '#{window_type == :app ? current_dir_name : namespace}/model/greeting'
|
|
645
639
|
|
646
640
|
margined true
|
647
641
|
|
648
|
-
vertical_box {
|
649
642
|
MULTI_LINE_STRING
|
650
643
|
|
651
644
|
if window_type == :gem
|
652
645
|
custom_window_file_content += <<-MULTI_LINE_STRING
|
653
|
-
|
646
|
+
vertical_box {
|
654
647
|
button('Preferences...') {
|
655
648
|
stretchy false
|
656
649
|
|
@@ -658,14 +651,21 @@ require '#{window_type == :app ? current_dir_name : namespace}/model/greeting'
|
|
658
651
|
display_preferences_dialog
|
659
652
|
end
|
660
653
|
}
|
661
|
-
|
662
|
-
end
|
663
|
-
|
664
|
-
custom_window_file_content += <<-MULTI_LINE_STRING
|
654
|
+
|
665
655
|
label {
|
666
656
|
#{%i[gem app].include?(window_type) ? "text <= [@greeting, :text]" : "text '#{human_name(custom_window_name)}'"}
|
667
657
|
}
|
668
658
|
}
|
659
|
+
MULTI_LINE_STRING
|
660
|
+
else
|
661
|
+
custom_window_file_content += <<-MULTI_LINE_STRING
|
662
|
+
label {
|
663
|
+
#{%i[gem app].include?(window_type) ? "text <= [@greeting, :text]" : "text '#{human_name(custom_window_name)}'"}
|
664
|
+
}
|
665
|
+
MULTI_LINE_STRING
|
666
|
+
end
|
667
|
+
|
668
|
+
custom_window_file_content += <<-MULTI_LINE_STRING
|
669
669
|
}
|
670
670
|
}
|
671
671
|
MULTI_LINE_STRING
|
@@ -833,6 +833,7 @@ end
|
|
833
833
|
namespace_type = class_name(namespace) == class_name(current_dir_name) ? 'class' : 'module'
|
834
834
|
|
835
835
|
<<-MULTI_LINE_STRING
|
836
|
+
# Delete this example model and replace with your own model
|
836
837
|
#{namespace_type} #{class_name(namespace)}
|
837
838
|
module Model
|
838
839
|
class #{class_name(model_name)}
|
data/lib/glimmer/rake_task.rb
CHANGED
@@ -113,7 +113,7 @@ namespace :glimmer do
|
|
113
113
|
task :cc, [:name, :namespace] => :customcontrol
|
114
114
|
task :custom_control, [:name, :namespace] => :customcontrol
|
115
115
|
task :"custom-control", [:name, :namespace] => :customcontrol
|
116
|
-
|
116
|
+
|
117
117
|
# desc 'Scaffold Glimmer::UI::CustomShape subclass (part of a view) under app/views (namespace is optional) [alt: scaffold:cs]'
|
118
118
|
# task :customshape, [:name, :namespace] do |t, args|
|
119
119
|
# require_relative 'rake_task/scaffold'
|
@@ -123,7 +123,7 @@ namespace :glimmer do
|
|
123
123
|
# task :cs, [:name, :namespace] => :customshape
|
124
124
|
# task :custom_shape, [:name, :namespace] => :customshape
|
125
125
|
# task :"custom-shape", [:name, :namespace] => :customshape
|
126
|
-
|
126
|
+
|
127
127
|
namespace :gem do
|
128
128
|
desc 'Scaffold Glimmer::UI::CustomWindow subclass (full window view) under its own Ruby gem + app project (namespace is required) [alt: scaffold:gem:cw]'
|
129
129
|
task :customwindow, [:name, :namespace] do |t, args|
|
@@ -134,17 +134,17 @@ namespace :glimmer do
|
|
134
134
|
task :cw, [:name, :namespace] => :customwindow
|
135
135
|
task :custom_window, [:name, :namespace] => :customwindow
|
136
136
|
task :"custom-window", [:name, :namespace] => :customwindow
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
137
|
+
|
138
|
+
desc 'Scaffold Glimmer::UI::CustomControl subclass (part of a view) under its own Ruby gem project (namespace is required) [alt: scaffold:gem:cc]'
|
139
|
+
task :customcontrol, [:name, :namespace] do |t, args|
|
140
|
+
require_relative 'rake_task/scaffold'
|
141
|
+
Glimmer::RakeTask::Scaffold.custom_control_gem(args[:name], args[:namespace])
|
142
|
+
end
|
143
|
+
|
144
|
+
task :cc, [:name, :namespace] => :customcontrol
|
145
|
+
task :custom_control, [:name, :namespace] => :customcontrol
|
146
|
+
task :"custom-control", [:name, :namespace] => :customcontrol
|
147
|
+
|
148
148
|
# desc 'Scaffold Glimmer::UI::CustomShape subclass (part of a view) under its own Ruby gem project (namespace is required) [alt: scaffold:gem:cs]'
|
149
149
|
# task :customshape, [:name, :namespace] do |t, args|
|
150
150
|
# require_relative 'rake_task/scaffold'
|
data/lib/glimmer-dsl-libui.rb
CHANGED
@@ -25,7 +25,7 @@ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
|
|
25
25
|
require 'glimmer'
|
26
26
|
require 'perfect-shape'
|
27
27
|
# require 'logging'
|
28
|
-
|
28
|
+
require 'puts_debuggerer' if (ENV['PD'] || ENV['pd']).to_s.downcase == 'true'
|
29
29
|
# require 'super_module'
|
30
30
|
require 'color'
|
31
31
|
require 'os'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-libui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-10-
|
11
|
+
date: 2023-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|
@@ -353,8 +353,9 @@ description: Glimmer DSL for LibUI (Fukuoka Award Winning Prerequisite-Free Ruby
|
|
353
353
|
GUI that just works on Mac, Windows, and Linux! Glimmer DSL for LibUI aims to provide
|
354
354
|
declarative DSL syntax that visually maps to GUI control hierarchy, convention over
|
355
355
|
configuration via smart defaults, automation of low-level details, requiring the
|
356
|
-
least amount of syntax possible to build GUI, bidirectional data-binding,
|
357
|
-
|
356
|
+
least amount of syntax possible to build GUI, bidirectional data-binding, custom
|
357
|
+
control/window support, and application/gem/window/control scaffolding. If you liked
|
358
|
+
Shoes, You'll love Glimmer!
|
358
359
|
email: andy.am@gmail.com
|
359
360
|
executables:
|
360
361
|
- glimmer
|
@@ -388,6 +389,7 @@ files:
|
|
388
389
|
- examples/basic_child_window.rb
|
389
390
|
- examples/basic_code_area.rb
|
390
391
|
- examples/basic_composite_shape.rb
|
392
|
+
- examples/basic_custom_shape.rb
|
391
393
|
- examples/basic_draw_text.rb
|
392
394
|
- examples/basic_draw_text2.rb
|
393
395
|
- examples/basic_entry.rb
|
@@ -500,6 +502,7 @@ files:
|
|
500
502
|
- lib/glimmer/dsl/libui/bind_expression.rb
|
501
503
|
- lib/glimmer/dsl/libui/control_expression.rb
|
502
504
|
- lib/glimmer/dsl/libui/custom_control_expression.rb
|
505
|
+
- lib/glimmer/dsl/libui/custom_shape_expression.rb
|
503
506
|
- lib/glimmer/dsl/libui/data_binding_expression.rb
|
504
507
|
- lib/glimmer/dsl/libui/dsl.rb
|
505
508
|
- lib/glimmer/dsl/libui/file_expression.rb
|
@@ -586,6 +589,7 @@ files:
|
|
586
589
|
- lib/glimmer/libui/custom_control.rb
|
587
590
|
- lib/glimmer/libui/custom_control/code_area.rb
|
588
591
|
- lib/glimmer/libui/custom_control/refined_table.rb
|
592
|
+
- lib/glimmer/libui/custom_shape.rb
|
589
593
|
- lib/glimmer/libui/custom_window.rb
|
590
594
|
- lib/glimmer/libui/data_bindable.rb
|
591
595
|
- lib/glimmer/libui/image_path_renderer.rb
|