glimmer-dsl-libui 0.4.14 → 0.4.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +79 -29
- data/VERSION +1 -1
- data/examples/editable_column_table.rb +5 -0
- data/examples/form_table.rb +9 -3
- data/examples/form_table2.rb +12 -6
- data/examples/form_table3.rb +9 -3
- data/examples/form_table4.rb +9 -3
- data/examples/form_table5.rb +9 -3
- data/examples/meta_example.rb +3 -1
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/libui/attributed_string.rb +17 -8
- data/lib/glimmer/libui/control_proxy/area_proxy.rb +17 -17
- data/lib/glimmer/libui/control_proxy/box.rb +1 -0
- data/lib/glimmer/libui/control_proxy/column/button_column_proxy.rb +1 -29
- data/lib/glimmer/libui/control_proxy/form_proxy.rb +1 -0
- data/lib/glimmer/libui/control_proxy/image_proxy.rb +2 -0
- data/lib/glimmer/libui/control_proxy/menu_item_proxy/quit_menu_item_proxy.rb +18 -8
- data/lib/glimmer/libui/control_proxy/open_type_features_proxy.rb +11 -2
- data/lib/glimmer/libui/control_proxy/open_type_tag_proxy.rb +2 -0
- data/lib/glimmer/libui/control_proxy/path_proxy.rb +2 -0
- data/lib/glimmer/libui/control_proxy/table_proxy.rb +6 -6
- data/lib/glimmer/libui/control_proxy/text_proxy.rb +2 -0
- data/lib/glimmer/libui/control_proxy/window_proxy.rb +34 -35
- data/lib/glimmer/libui/control_proxy.rb +45 -9
- data/lib/glimmer/libui/shape.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34cb8eb1da8d200b96163b3e2a0a607ed32dda75cb0df62088c5fcfaad2e2b18
|
4
|
+
data.tar.gz: 169bb5a5d620cc28606cdb03a7cd1e19544ae14d7c5d11dd2704cca869e3a2fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b00b7729fcc0635faa743f9310d048a132d679d1550033302ee39b13dedd5d5f9e4ab79e5673b2cfceb2d887d87f33c24774a3b5d4f0b2bbfdfd8e366844acb2
|
7
|
+
data.tar.gz: c879ccd0d7f27b08080905669bff25543673e9117d44650dd31a57674596cf09aee3034a49b8af8c73f7976c1143ec0a8f7892a77252eb945318fafcc6f49da2
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.4.15
|
4
|
+
|
5
|
+
- Support ability to attach multiple listeners on a control (e.g. multiple `on_changed {}` on `entry` or multiple `on_clicked` on `button`)
|
6
|
+
- Ensure clearing custom listeners on `#destroy` of a control
|
7
|
+
- Add `on_destroyed` as alias for `on_destroy` listener on `window`
|
8
|
+
- Avoid wasting time on `destroy` of a control (e.g. freeing resources) when the main window is getting destroyed, thus closing entire application instantaneously
|
9
|
+
- Have validation in examples/form_table.rb complain about nil values (no value entered)
|
10
|
+
- Fix Reset button in examples/meta_example.rb when on a version other than version 1
|
11
|
+
- Fix issue with calling `#destroy` on `open_type_features`
|
12
|
+
|
3
13
|
## 0.4.14
|
4
14
|
|
5
15
|
- Support passing width or height alone to `image` keyword, calculating the other dimension automatically while preserving original aspect ratio
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.4.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for LibUI 0.4.15
|
2
2
|
## Prerequisite-Free Ruby Desktop Development GUI Library
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/glimmer-dsl-libui.svg)](http://badge.fury.io/rb/glimmer-dsl-libui)
|
4
4
|
[![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
@@ -100,7 +100,7 @@ class FormTable
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def launch
|
103
|
-
window('Contacts', 600, 600) {
|
103
|
+
window('Contacts', 600, 600) {
|
104
104
|
margined true
|
105
105
|
|
106
106
|
vertical_box {
|
@@ -138,8 +138,8 @@ class FormTable
|
|
138
138
|
|
139
139
|
on_clicked do
|
140
140
|
new_row = [name, email, phone, city, state]
|
141
|
-
if new_row.include?('')
|
142
|
-
msg_box_error(
|
141
|
+
if new_row.map(&:to_s).include?('')
|
142
|
+
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
143
143
|
else
|
144
144
|
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to explicit data-binding
|
145
145
|
@unfiltered_contacts = @contacts.dup
|
@@ -184,6 +184,12 @@ class FormTable
|
|
184
184
|
|
185
185
|
on_changed do |row, type, row_data|
|
186
186
|
puts "Row #{row} #{type}: #{row_data}"
|
187
|
+
$stdout.flush # for Windows
|
188
|
+
end
|
189
|
+
|
190
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
191
|
+
puts "Row #{row} edited: #{row_data}"
|
192
|
+
$stdout.flush # for Windows
|
187
193
|
end
|
188
194
|
}
|
189
195
|
}
|
@@ -500,7 +506,7 @@ gem install glimmer-dsl-libui
|
|
500
506
|
Or install via Bundler `Gemfile`:
|
501
507
|
|
502
508
|
```ruby
|
503
|
-
gem 'glimmer-dsl-libui', '~> 0.4.
|
509
|
+
gem 'glimmer-dsl-libui', '~> 0.4.15'
|
504
510
|
```
|
505
511
|
|
506
512
|
Test that installation worked by running the [Meta-Example](#examples):
|
@@ -769,7 +775,7 @@ data = [
|
|
769
775
|
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'],
|
770
776
|
]
|
771
777
|
|
772
|
-
window('Contacts', 600, 600) {
|
778
|
+
window('Contacts', 600, 600) {
|
773
779
|
margined true
|
774
780
|
|
775
781
|
vertical_box {
|
@@ -802,8 +808,8 @@ window('Contacts', 600, 600) { |w|
|
|
802
808
|
|
803
809
|
on_clicked do
|
804
810
|
new_row = [@name_entry.text, @email_entry.text, @phone_entry.text, @city_entry.text, @state_entry.text]
|
805
|
-
if new_row.include?('')
|
806
|
-
msg_box_error(
|
811
|
+
if new_row.map(&:to_s).include?('')
|
812
|
+
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
807
813
|
else
|
808
814
|
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
809
815
|
@unfiltered_data = data.dup
|
@@ -847,6 +853,12 @@ window('Contacts', 600, 600) { |w|
|
|
847
853
|
|
848
854
|
on_changed do |row, type, row_data|
|
849
855
|
puts "Row #{row} #{type}: #{row_data}"
|
856
|
+
$stdout.flush # for Windows
|
857
|
+
end
|
858
|
+
|
859
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
860
|
+
puts "Row #{row} edited: #{row_data}"
|
861
|
+
$stdout.flush # for Windows
|
850
862
|
end
|
851
863
|
}
|
852
864
|
}
|
@@ -1340,13 +1352,16 @@ Note that `area`, `path`, and nested shapes are all truly declarative, meaning t
|
|
1340
1352
|
- `horizontal_box`, `vertical_box`, `grid`, and `form` controls have `padded` as `true` upon instantiation to ensure more user-friendly GUI by default
|
1341
1353
|
- `group` controls have `margined` as `true` upon instantiation to ensure more user-friendly GUI by default
|
1342
1354
|
- All controls nested under a `horizontal_box`, `vertical_box`, and `form` have `stretchy` property (fill maximum space) as `true` by default (passed to `box_append`/`form_append` method)
|
1355
|
+
- If an event listener is repeated under a control (e.g. two `on_clicked {}` listeners under `button`), it does not overwrite the previous listener, yet it is added to an `Array` of listeners for the event. [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) provides multiple-event-listener support unlike [LibUI](https://github.com/kojix2/LibUI)
|
1343
1356
|
- `window` instatiation args can be left off, having the following defaults when unspecified: `title` as `''`, `width` as `190`, `height` as `150`, and `has_menubar` as `true`)
|
1344
1357
|
- `window` has an `on_closing` listener by default that quits application upon hitting the close button (can be overridden with a manual `on_closing` implementation that returns integer `0` for success)
|
1345
1358
|
- `group` has `title` property default to `''` if not specified in instantiation args, so it can be instantiated without args with `title` property specified in nested block (e.g. `group {title 'Address'; ...}`)
|
1346
1359
|
- `button`, `checkbox`, and `label` have `text` default to `''` if not specified in instantiation args, so they can be instantiated without args with `text` property specified in nested block (e.g. `button {text 'Greet'; on_clicked {puts 'Hello'}}`)
|
1347
1360
|
- `quit_menu_item` has an `on_clicked` listener by default that quits application upon selecting the quit menu item (can be overridden with a manual `on_clicked` implementation that returns integer `0` for success)
|
1348
1361
|
- If an `on_closing` listener was defined on `window` and it does not return an integer, default exit behavior is assumed (`window.destroy` is called followed by `LibUI.quit`, returning `0`).
|
1349
|
-
- If
|
1362
|
+
- If multiple `on_closing` listeners were added for `window`, and none return an integer, they are all executed. On the other hand, if one of them returns an integer, it is counted as the final return value and stops the chain of listener execution.
|
1363
|
+
- If an `on_clicked` listener was defined on `quit_menu_item` and it does not return an integer, default exit behavior is assumed (`quit_menu_item.destroy` and `main_window.destroy` are called followed by `LibUI.quit`, returning `0`).
|
1364
|
+
- If multiple `on_clicked` listeners were added for `quit_menu_item`, and none return an integer, they are all executed. On the other hand, if one of them returns an integer, it is counted as the final return value and stops the chain of listener execution.
|
1350
1365
|
- All boolean property readers return `true` or `false` in Ruby instead of the [libui](https://github.com/andlabs/libui) original `0` or `1` in C.
|
1351
1366
|
- All boolean property writers accept `true`/`false` in addition to `1`/`0` in Ruby
|
1352
1367
|
- All string property readers return a `String` object in Ruby instead of the [libui](https://github.com/andlabs/libui) Fiddle pointer object.
|
@@ -6710,6 +6725,11 @@ window('Editable column animal sounds', 400, 200) {
|
|
6710
6725
|
}
|
6711
6726
|
|
6712
6727
|
cell_rows data
|
6728
|
+
|
6729
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
6730
|
+
puts "Row #{row} edited: #{row_data}"
|
6731
|
+
$stdout.flush
|
6732
|
+
end
|
6713
6733
|
}
|
6714
6734
|
}
|
6715
6735
|
|
@@ -6822,7 +6842,7 @@ class FormTable
|
|
6822
6842
|
end
|
6823
6843
|
|
6824
6844
|
def launch
|
6825
|
-
window('Contacts', 600, 600) {
|
6845
|
+
window('Contacts', 600, 600) {
|
6826
6846
|
margined true
|
6827
6847
|
|
6828
6848
|
vertical_box {
|
@@ -6860,8 +6880,8 @@ class FormTable
|
|
6860
6880
|
|
6861
6881
|
on_clicked do
|
6862
6882
|
new_row = [name, email, phone, city, state]
|
6863
|
-
if new_row.include?('')
|
6864
|
-
msg_box_error(
|
6883
|
+
if new_row.map(&:to_s).include?('')
|
6884
|
+
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
6865
6885
|
else
|
6866
6886
|
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to explicit data-binding
|
6867
6887
|
@unfiltered_contacts = @contacts.dup
|
@@ -6906,6 +6926,12 @@ class FormTable
|
|
6906
6926
|
|
6907
6927
|
on_changed do |row, type, row_data|
|
6908
6928
|
puts "Row #{row} #{type}: #{row_data}"
|
6929
|
+
$stdout.flush # for Windows
|
6930
|
+
end
|
6931
|
+
|
6932
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
6933
|
+
puts "Row #{row} edited: #{row_data}"
|
6934
|
+
$stdout.flush # for Windows
|
6909
6935
|
end
|
6910
6936
|
}
|
6911
6937
|
}
|
@@ -6916,13 +6942,13 @@ end
|
|
6916
6942
|
FormTable.new.launch
|
6917
6943
|
```
|
6918
6944
|
|
6919
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version (with explicit [data-binding](#data-binding)):
|
6945
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 2 (with explicit [data-binding](#data-binding)):
|
6920
6946
|
|
6921
6947
|
```ruby
|
6922
6948
|
require 'glimmer-dsl-libui'
|
6923
6949
|
|
6924
6950
|
class FormTable
|
6925
|
-
Contact = Struct.new(:name, :email, :phone, :city, :
|
6951
|
+
Contact = Struct.new(:name, :email, :phone, :city, :state_province)
|
6926
6952
|
|
6927
6953
|
include Glimmer
|
6928
6954
|
|
@@ -6939,7 +6965,7 @@ class FormTable
|
|
6939
6965
|
end
|
6940
6966
|
|
6941
6967
|
def launch
|
6942
|
-
window('Contacts', 600, 600) {
|
6968
|
+
window('Contacts', 600, 600) {
|
6943
6969
|
margined true
|
6944
6970
|
|
6945
6971
|
vertical_box {
|
@@ -6977,8 +7003,8 @@ class FormTable
|
|
6977
7003
|
|
6978
7004
|
on_clicked do
|
6979
7005
|
new_row = [name, email, phone, city, state]
|
6980
|
-
if new_row.include?('')
|
6981
|
-
msg_box_error(
|
7006
|
+
if new_row.map(&:to_s).include?('')
|
7007
|
+
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
6982
7008
|
else
|
6983
7009
|
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to implicit data-binding
|
6984
7010
|
@unfiltered_contacts = @contacts.dup
|
@@ -7016,13 +7042,19 @@ class FormTable
|
|
7016
7042
|
text_column('Email')
|
7017
7043
|
text_column('Phone')
|
7018
7044
|
text_column('City')
|
7019
|
-
text_column('State
|
7045
|
+
text_column('State')
|
7020
7046
|
|
7021
7047
|
editable true
|
7022
|
-
cell_rows <=> [self, :contacts, column_attributes: {'State
|
7048
|
+
cell_rows <=> [self, :contacts, column_attributes: {'State' => :state_province}] # explicit data-binding to Model Array with column_attributes mapping for a specific column
|
7023
7049
|
|
7024
7050
|
on_changed do |row, type, row_data|
|
7025
7051
|
puts "Row #{row} #{type}: #{row_data}"
|
7052
|
+
$stdout.flush # for Windows
|
7053
|
+
end
|
7054
|
+
|
7055
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
7056
|
+
puts "Row #{row} edited: #{row_data}"
|
7057
|
+
$stdout.flush # for Windows
|
7026
7058
|
end
|
7027
7059
|
}
|
7028
7060
|
}
|
@@ -7033,7 +7065,7 @@ end
|
|
7033
7065
|
FormTable.new.launch
|
7034
7066
|
```
|
7035
7067
|
|
7036
|
-
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version (with explicit [data-binding](#data-binding)):
|
7068
|
+
New [Glimmer DSL for LibUI](https://rubygems.org/gems/glimmer-dsl-libui) Version 3 (with explicit [data-binding](#data-binding)):
|
7037
7069
|
|
7038
7070
|
```ruby
|
7039
7071
|
|
@@ -7057,7 +7089,7 @@ class FormTable
|
|
7057
7089
|
end
|
7058
7090
|
|
7059
7091
|
def launch
|
7060
|
-
window('Contacts', 600, 600) {
|
7092
|
+
window('Contacts', 600, 600) {
|
7061
7093
|
margined true
|
7062
7094
|
|
7063
7095
|
vertical_box {
|
@@ -7095,8 +7127,8 @@ class FormTable
|
|
7095
7127
|
|
7096
7128
|
on_clicked do
|
7097
7129
|
new_row = [name, email, phone, city, state]
|
7098
|
-
if new_row.include?('')
|
7099
|
-
msg_box_error(
|
7130
|
+
if new_row.map(&:to_s).include?('')
|
7131
|
+
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
7100
7132
|
else
|
7101
7133
|
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to implicit data-binding
|
7102
7134
|
@unfiltered_contacts = @contacts.dup
|
@@ -7141,6 +7173,12 @@ class FormTable
|
|
7141
7173
|
|
7142
7174
|
on_changed do |row, type, row_data|
|
7143
7175
|
puts "Row #{row} #{type}: #{row_data}"
|
7176
|
+
$stdout.flush # for Windows
|
7177
|
+
end
|
7178
|
+
|
7179
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
7180
|
+
puts "Row #{row} edited: #{row_data}"
|
7181
|
+
$stdout.flush # for Windows
|
7144
7182
|
end
|
7145
7183
|
}
|
7146
7184
|
}
|
@@ -7172,7 +7210,7 @@ class FormTable
|
|
7172
7210
|
end
|
7173
7211
|
|
7174
7212
|
def launch
|
7175
|
-
window('Contacts', 600, 600) {
|
7213
|
+
window('Contacts', 600, 600) {
|
7176
7214
|
margined true
|
7177
7215
|
|
7178
7216
|
vertical_box {
|
@@ -7210,8 +7248,8 @@ class FormTable
|
|
7210
7248
|
|
7211
7249
|
on_clicked do
|
7212
7250
|
new_row = [name, email, phone, city, state]
|
7213
|
-
if new_row.include?('')
|
7214
|
-
msg_box_error(
|
7251
|
+
if new_row.map(&:to_s).include?('')
|
7252
|
+
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
7215
7253
|
else
|
7216
7254
|
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
7217
7255
|
@unfiltered_data = data.dup
|
@@ -7256,6 +7294,12 @@ class FormTable
|
|
7256
7294
|
|
7257
7295
|
on_changed do |row, type, row_data|
|
7258
7296
|
puts "Row #{row} #{type}: #{row_data}"
|
7297
|
+
$stdout.flush # for Windows
|
7298
|
+
end
|
7299
|
+
|
7300
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
7301
|
+
puts "Row #{row} edited: #{row_data}"
|
7302
|
+
$stdout.flush # for Windows
|
7259
7303
|
end
|
7260
7304
|
}
|
7261
7305
|
}
|
@@ -7281,7 +7325,7 @@ data = [
|
|
7281
7325
|
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'],
|
7282
7326
|
]
|
7283
7327
|
|
7284
|
-
window('Contacts', 600, 600) {
|
7328
|
+
window('Contacts', 600, 600) {
|
7285
7329
|
margined true
|
7286
7330
|
|
7287
7331
|
vertical_box {
|
@@ -7314,8 +7358,8 @@ window('Contacts', 600, 600) { |w|
|
|
7314
7358
|
|
7315
7359
|
on_clicked do
|
7316
7360
|
new_row = [@name_entry.text, @email_entry.text, @phone_entry.text, @city_entry.text, @state_entry.text]
|
7317
|
-
if new_row.include?('')
|
7318
|
-
msg_box_error(
|
7361
|
+
if new_row.map(&:to_s).include?('')
|
7362
|
+
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
7319
7363
|
else
|
7320
7364
|
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
7321
7365
|
@unfiltered_data = data.dup
|
@@ -7359,6 +7403,12 @@ window('Contacts', 600, 600) { |w|
|
|
7359
7403
|
|
7360
7404
|
on_changed do |row, type, row_data|
|
7361
7405
|
puts "Row #{row} #{type}: #{row_data}"
|
7406
|
+
$stdout.flush # for Windows
|
7407
|
+
end
|
7408
|
+
|
7409
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
7410
|
+
puts "Row #{row} edited: #{row_data}"
|
7411
|
+
$stdout.flush # for Windows
|
7362
7412
|
end
|
7363
7413
|
}
|
7364
7414
|
}
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.15
|
data/examples/form_table.rb
CHANGED
@@ -18,7 +18,7 @@ class FormTable
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def launch
|
21
|
-
window('Contacts', 600, 600) {
|
21
|
+
window('Contacts', 600, 600) {
|
22
22
|
margined true
|
23
23
|
|
24
24
|
vertical_box {
|
@@ -56,8 +56,8 @@ class FormTable
|
|
56
56
|
|
57
57
|
on_clicked do
|
58
58
|
new_row = [name, email, phone, city, state]
|
59
|
-
if new_row.include?('')
|
60
|
-
msg_box_error(
|
59
|
+
if new_row.map(&:to_s).include?('')
|
60
|
+
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
61
61
|
else
|
62
62
|
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to explicit data-binding
|
63
63
|
@unfiltered_contacts = @contacts.dup
|
@@ -102,6 +102,12 @@ class FormTable
|
|
102
102
|
|
103
103
|
on_changed do |row, type, row_data|
|
104
104
|
puts "Row #{row} #{type}: #{row_data}"
|
105
|
+
$stdout.flush # for Windows
|
106
|
+
end
|
107
|
+
|
108
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
109
|
+
puts "Row #{row} edited: #{row_data}"
|
110
|
+
$stdout.flush # for Windows
|
105
111
|
end
|
106
112
|
}
|
107
113
|
}
|
data/examples/form_table2.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'glimmer-dsl-libui'
|
2
2
|
|
3
3
|
class FormTable
|
4
|
-
Contact = Struct.new(:name, :email, :phone, :city, :
|
4
|
+
Contact = Struct.new(:name, :email, :phone, :city, :state_province)
|
5
5
|
|
6
6
|
include Glimmer
|
7
7
|
|
@@ -18,7 +18,7 @@ class FormTable
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def launch
|
21
|
-
window('Contacts', 600, 600) {
|
21
|
+
window('Contacts', 600, 600) {
|
22
22
|
margined true
|
23
23
|
|
24
24
|
vertical_box {
|
@@ -56,8 +56,8 @@ class FormTable
|
|
56
56
|
|
57
57
|
on_clicked do
|
58
58
|
new_row = [name, email, phone, city, state]
|
59
|
-
if new_row.include?('')
|
60
|
-
msg_box_error(
|
59
|
+
if new_row.map(&:to_s).include?('')
|
60
|
+
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
61
61
|
else
|
62
62
|
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to implicit data-binding
|
63
63
|
@unfiltered_contacts = @contacts.dup
|
@@ -95,13 +95,19 @@ class FormTable
|
|
95
95
|
text_column('Email')
|
96
96
|
text_column('Phone')
|
97
97
|
text_column('City')
|
98
|
-
text_column('State
|
98
|
+
text_column('State')
|
99
99
|
|
100
100
|
editable true
|
101
|
-
cell_rows <=> [self, :contacts, column_attributes: {'State
|
101
|
+
cell_rows <=> [self, :contacts, column_attributes: {'State' => :state_province}] # explicit data-binding to Model Array with column_attributes mapping for a specific column
|
102
102
|
|
103
103
|
on_changed do |row, type, row_data|
|
104
104
|
puts "Row #{row} #{type}: #{row_data}"
|
105
|
+
$stdout.flush # for Windows
|
106
|
+
end
|
107
|
+
|
108
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
109
|
+
puts "Row #{row} edited: #{row_data}"
|
110
|
+
$stdout.flush # for Windows
|
105
111
|
end
|
106
112
|
}
|
107
113
|
}
|
data/examples/form_table3.rb
CHANGED
@@ -19,7 +19,7 @@ class FormTable
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def launch
|
22
|
-
window('Contacts', 600, 600) {
|
22
|
+
window('Contacts', 600, 600) {
|
23
23
|
margined true
|
24
24
|
|
25
25
|
vertical_box {
|
@@ -57,8 +57,8 @@ class FormTable
|
|
57
57
|
|
58
58
|
on_clicked do
|
59
59
|
new_row = [name, email, phone, city, state]
|
60
|
-
if new_row.include?('')
|
61
|
-
msg_box_error(
|
60
|
+
if new_row.map(&:to_s).include?('')
|
61
|
+
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
62
62
|
else
|
63
63
|
@contacts << Contact.new(*new_row) # automatically inserts a row into the table due to implicit data-binding
|
64
64
|
@unfiltered_contacts = @contacts.dup
|
@@ -103,6 +103,12 @@ class FormTable
|
|
103
103
|
|
104
104
|
on_changed do |row, type, row_data|
|
105
105
|
puts "Row #{row} #{type}: #{row_data}"
|
106
|
+
$stdout.flush # for Windows
|
107
|
+
end
|
108
|
+
|
109
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
110
|
+
puts "Row #{row} edited: #{row_data}"
|
111
|
+
$stdout.flush # for Windows
|
106
112
|
end
|
107
113
|
}
|
108
114
|
}
|
data/examples/form_table4.rb
CHANGED
@@ -16,7 +16,7 @@ class FormTable
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def launch
|
19
|
-
window('Contacts', 600, 600) {
|
19
|
+
window('Contacts', 600, 600) {
|
20
20
|
margined true
|
21
21
|
|
22
22
|
vertical_box {
|
@@ -54,8 +54,8 @@ class FormTable
|
|
54
54
|
|
55
55
|
on_clicked do
|
56
56
|
new_row = [name, email, phone, city, state]
|
57
|
-
if new_row.include?('')
|
58
|
-
msg_box_error(
|
57
|
+
if new_row.map(&:to_s).include?('')
|
58
|
+
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
59
59
|
else
|
60
60
|
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
61
61
|
@unfiltered_data = data.dup
|
@@ -100,6 +100,12 @@ class FormTable
|
|
100
100
|
|
101
101
|
on_changed do |row, type, row_data|
|
102
102
|
puts "Row #{row} #{type}: #{row_data}"
|
103
|
+
$stdout.flush # for Windows
|
104
|
+
end
|
105
|
+
|
106
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
107
|
+
puts "Row #{row} edited: #{row_data}"
|
108
|
+
$stdout.flush # for Windows
|
103
109
|
end
|
104
110
|
}
|
105
111
|
}
|
data/examples/form_table5.rb
CHANGED
@@ -10,7 +10,7 @@ data = [
|
|
10
10
|
['Melody Hanheimer', 'melody@hanheimer.com', '213-493-8274', 'Los Angeles', 'CA'],
|
11
11
|
]
|
12
12
|
|
13
|
-
window('Contacts', 600, 600) {
|
13
|
+
window('Contacts', 600, 600) {
|
14
14
|
margined true
|
15
15
|
|
16
16
|
vertical_box {
|
@@ -43,8 +43,8 @@ window('Contacts', 600, 600) { |w|
|
|
43
43
|
|
44
44
|
on_clicked do
|
45
45
|
new_row = [@name_entry.text, @email_entry.text, @phone_entry.text, @city_entry.text, @state_entry.text]
|
46
|
-
if new_row.include?('')
|
47
|
-
msg_box_error(
|
46
|
+
if new_row.map(&:to_s).include?('')
|
47
|
+
msg_box_error('Validation Error!', 'All fields are required! Please make sure to enter a value for all fields.')
|
48
48
|
else
|
49
49
|
data << new_row # automatically inserts a row into the table due to implicit data-binding
|
50
50
|
@unfiltered_data = data.dup
|
@@ -88,6 +88,12 @@ window('Contacts', 600, 600) { |w|
|
|
88
88
|
|
89
89
|
on_changed do |row, type, row_data|
|
90
90
|
puts "Row #{row} #{type}: #{row_data}"
|
91
|
+
$stdout.flush # for Windows
|
92
|
+
end
|
93
|
+
|
94
|
+
on_edited do |row, row_data| # only fires on direct table editing
|
95
|
+
puts "Row #{row} edited: #{row_data}"
|
96
|
+
$stdout.flush # for Windows
|
91
97
|
end
|
92
98
|
}
|
93
99
|
}
|
data/examples/meta_example.rb
CHANGED
@@ -180,7 +180,9 @@ class MetaExample
|
|
180
180
|
}
|
181
181
|
button('Reset') {
|
182
182
|
on_clicked do
|
183
|
-
|
183
|
+
version_number = @version_spinbox.value == 1 ? '' : @version_spinbox.value
|
184
|
+
example = "#{selected_example}#{version_number}"
|
185
|
+
self.code_text = File.read(file_path_for(example))
|
184
186
|
end
|
185
187
|
}
|
186
188
|
}
|
data/glimmer-dsl-libui.gemspec
CHANGED
Binary file
|
@@ -22,7 +22,6 @@
|
|
22
22
|
require 'glimmer/libui/control_proxy'
|
23
23
|
require 'glimmer/libui/control_proxy/area_proxy'
|
24
24
|
require 'glimmer/libui/parent'
|
25
|
-
require 'glimmer/libui/control_proxy/transformable'
|
26
25
|
require 'glimmer/libui/data_bindable'
|
27
26
|
|
28
27
|
module Glimmer
|
@@ -48,7 +47,7 @@ module Glimmer
|
|
48
47
|
@string
|
49
48
|
else
|
50
49
|
@string = value
|
51
|
-
|
50
|
+
request_auto_redraw
|
52
51
|
end
|
53
52
|
end
|
54
53
|
alias string= string
|
@@ -59,7 +58,7 @@ module Glimmer
|
|
59
58
|
@font
|
60
59
|
else
|
61
60
|
@font = value
|
62
|
-
|
61
|
+
request_auto_redraw
|
63
62
|
end
|
64
63
|
end
|
65
64
|
alias font= font
|
@@ -70,7 +69,7 @@ module Glimmer
|
|
70
69
|
@color
|
71
70
|
else
|
72
71
|
@color = Glimmer::LibUI.interpret_color(value)
|
73
|
-
|
72
|
+
request_auto_redraw
|
74
73
|
end
|
75
74
|
end
|
76
75
|
alias color= color
|
@@ -81,7 +80,7 @@ module Glimmer
|
|
81
80
|
@background
|
82
81
|
else
|
83
82
|
@background = Glimmer::LibUI.interpret_color(value)
|
84
|
-
|
83
|
+
request_auto_redraw
|
85
84
|
end
|
86
85
|
end
|
87
86
|
alias background= background
|
@@ -92,7 +91,7 @@ module Glimmer
|
|
92
91
|
@underline
|
93
92
|
else
|
94
93
|
@underline = value
|
95
|
-
|
94
|
+
request_auto_redraw
|
96
95
|
end
|
97
96
|
end
|
98
97
|
alias underline= underline
|
@@ -103,7 +102,7 @@ module Glimmer
|
|
103
102
|
@underline_color
|
104
103
|
else
|
105
104
|
@underline_color = value
|
106
|
-
|
105
|
+
request_auto_redraw
|
107
106
|
end
|
108
107
|
end
|
109
108
|
alias underline_color= underline_color
|
@@ -114,12 +113,21 @@ module Glimmer
|
|
114
113
|
@open_type_features
|
115
114
|
else
|
116
115
|
@open_type_features = value
|
117
|
-
|
116
|
+
request_auto_redraw
|
118
117
|
end
|
119
118
|
end
|
120
119
|
alias open_type_features= open_type_features
|
121
120
|
alias set_open_type_features open_type_features
|
122
121
|
|
122
|
+
def remove_open_type_features
|
123
|
+
return if @removing_open_type_features
|
124
|
+
@removing_open_type_features = true
|
125
|
+
@open_type_features&.destroy
|
126
|
+
@open_type_features = nil
|
127
|
+
request_auto_redraw
|
128
|
+
@removing_open_type_features = false
|
129
|
+
end
|
130
|
+
|
123
131
|
def post_add_content(block = nil)
|
124
132
|
block ||= @block
|
125
133
|
block_result = block&.call
|
@@ -189,6 +197,7 @@ module Glimmer
|
|
189
197
|
end
|
190
198
|
|
191
199
|
def destroy
|
200
|
+
return if ControlProxy.main_window_proxy&.destroying?
|
192
201
|
open_type_features.destroy unless open_type_features.nil?
|
193
202
|
@parent_proxy&.children&.delete(self)
|
194
203
|
end
|
@@ -36,9 +36,9 @@ module Glimmer
|
|
36
36
|
attr_accessor :current_area_draw_params
|
37
37
|
end
|
38
38
|
|
39
|
-
|
39
|
+
CUSTOM_LISTENER_NAMES = ['on_draw', 'on_mouse_event', 'on_mouse_move', 'on_mouse_down', 'on_mouse_up', 'on_mouse_drag_start', 'on_mouse_drag', 'on_mouse_drop', 'on_mouse_crossed', 'on_mouse_enter', 'on_mouse_exit', 'on_drag_broken', 'on_key_event', 'on_key_down', 'on_key_up']
|
40
40
|
|
41
|
-
|
41
|
+
CUSTOM_LISTENER_NAME_ALIASES = {
|
42
42
|
on_drawn: 'on_draw',
|
43
43
|
on_mouse_moved: 'on_mouse_move',
|
44
44
|
on_mouse_drag_started: 'on_mouse_drag_start',
|
@@ -105,7 +105,7 @@ module Glimmer
|
|
105
105
|
|
106
106
|
def draw(area_draw_params)
|
107
107
|
children.dup.each {|child| child.draw(area_draw_params)}
|
108
|
-
on_draw
|
108
|
+
notify_custom_listeners('on_draw', area_draw_params)
|
109
109
|
end
|
110
110
|
|
111
111
|
def redraw
|
@@ -156,37 +156,37 @@ module Glimmer
|
|
156
156
|
@area_handler.MouseEvent = fiddle_closure_block_caller(0, [1, 1, 1]) do |_, _, area_mouse_event|
|
157
157
|
area_mouse_event = ::LibUI::FFI::AreaMouseEvent.new(area_mouse_event)
|
158
158
|
area_mouse_event = area_mouse_event_hash(area_mouse_event)
|
159
|
-
on_mouse_event
|
160
|
-
on_mouse_move
|
159
|
+
notify_custom_listeners('on_mouse_event', area_mouse_event)
|
160
|
+
notify_custom_listeners('on_mouse_move', area_mouse_event) if area_mouse_event[:x].between?(0, area_mouse_event[:area_width]) && area_mouse_event[:y].between?(0, area_mouse_event[:area_height])
|
161
161
|
unless @last_area_mouse_event.nil?
|
162
|
-
on_mouse_down
|
163
|
-
on_mouse_up
|
164
|
-
on_mouse_drag_start
|
165
|
-
on_mouse_drag
|
166
|
-
on_mouse_drop
|
162
|
+
notify_custom_listeners('on_mouse_down', area_mouse_event) if area_mouse_event[:down] > 0 && @last_area_mouse_event[:down] == 0
|
163
|
+
notify_custom_listeners('on_mouse_up', area_mouse_event) if area_mouse_event[:up] > 0 && @last_area_mouse_event[:up] == 0
|
164
|
+
notify_custom_listeners('on_mouse_drag_start', area_mouse_event) if area_mouse_event[:held] > 0 && @last_area_mouse_event[:held] == 0
|
165
|
+
notify_custom_listeners('on_mouse_drag', area_mouse_event) if area_mouse_event[:held] > 0
|
166
|
+
notify_custom_listeners('on_mouse_drop', area_mouse_event) if area_mouse_event[:held] == 0 && @last_area_mouse_event[:held] > 0
|
167
167
|
end
|
168
168
|
@last_area_mouse_event = area_mouse_event
|
169
169
|
end
|
170
170
|
@area_handler.MouseCrossed = fiddle_closure_block_caller(0, [1, 1, 4]) do |_, _, left|
|
171
171
|
left = Glimmer::LibUI.integer_to_boolean(left)
|
172
|
-
on_mouse_crossed
|
172
|
+
notify_custom_listeners('on_mouse_crossed', left)
|
173
173
|
if left
|
174
|
-
on_mouse_exit
|
174
|
+
notify_custom_listeners('on_mouse_exit', left)
|
175
175
|
else
|
176
|
-
on_mouse_enter
|
176
|
+
notify_custom_listeners('on_mouse_enter', left)
|
177
177
|
end
|
178
178
|
end
|
179
179
|
@area_handler.DragBroken = fiddle_closure_block_caller(0, [1, 1]) do |_, _|
|
180
|
-
on_drag_broken
|
180
|
+
notify_custom_listeners('on_drag_broken')
|
181
181
|
end
|
182
182
|
@area_handler.KeyEvent = fiddle_closure_block_caller(0, [1, 1, 1]) do |_, _, area_key_event|
|
183
183
|
area_key_event = ::LibUI::FFI::AreaKeyEvent.new(area_key_event)
|
184
184
|
area_key_event = area_key_event_hash(area_key_event)
|
185
|
-
on_key_event
|
185
|
+
notify_custom_listeners('on_key_event', area_key_event)
|
186
186
|
if area_key_event[:up]
|
187
|
-
on_key_up
|
187
|
+
notify_custom_listeners('on_key_up', area_key_event)
|
188
188
|
else
|
189
|
-
on_key_down
|
189
|
+
notify_custom_listeners('on_key_down', area_key_event)
|
190
190
|
end
|
191
191
|
end
|
192
192
|
@listeners_installed = true
|
@@ -34,36 +34,8 @@ module Glimmer
|
|
34
34
|
include Column
|
35
35
|
include EnableableColumn
|
36
36
|
|
37
|
-
|
38
|
-
# TODO consider generalizing into custom listeners and moving to ControlProxy
|
39
|
-
@on_clicked_procs ||= []
|
40
|
-
if block.nil?
|
41
|
-
@on_clicked_procs
|
42
|
-
else
|
43
|
-
@on_clicked_procs << block
|
44
|
-
block
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def can_handle_listener?(listener_name)
|
49
|
-
listener_name == 'on_clicked' || super
|
50
|
-
end
|
37
|
+
CUSTOM_LISTENER_NAMES = ['on_clicked']
|
51
38
|
|
52
|
-
def handle_listener(listener_name, &listener)
|
53
|
-
case listener_name
|
54
|
-
when 'on_clicked'
|
55
|
-
on_clicked(&listener)
|
56
|
-
else
|
57
|
-
super
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def notify_listeners(listener_name, *args)
|
62
|
-
@on_clicked_procs&.each do |on_clicked_proc|
|
63
|
-
on_clicked_proc.call(*args)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
39
|
private
|
68
40
|
|
69
41
|
def build_control
|
@@ -35,29 +35,39 @@ module Glimmer
|
|
35
35
|
|
36
36
|
def handle_listener(listener_name, &listener)
|
37
37
|
if listener_name == 'on_clicked'
|
38
|
-
@
|
39
|
-
|
38
|
+
@on_clicked_listeners ||= []
|
39
|
+
@on_clicked_listeners << listener
|
40
|
+
@default_behavior_listener ||= Proc.new do
|
41
|
+
return_value = nil
|
42
|
+
@on_clicked_listeners.each do |l|
|
43
|
+
return_value = l.call(self)
|
44
|
+
break if return_value.is_a?(Numeric)
|
45
|
+
end
|
40
46
|
if return_value.is_a?(Numeric)
|
41
47
|
return_value
|
42
48
|
else
|
43
49
|
destroy
|
50
|
+
ControlProxy.main_window_proxy&.destroy
|
44
51
|
::LibUI.quit
|
45
52
|
0
|
46
53
|
end
|
54
|
+
end.tap do |default_behavior_listener|
|
55
|
+
::LibUI.on_should_quit(&default_behavior_listener)
|
47
56
|
end
|
48
|
-
::LibUI.on_should_quit(&@default_behavior_listener)
|
49
57
|
end
|
50
58
|
end
|
59
|
+
|
60
|
+
def destroy
|
61
|
+
@on_clicked_listeners&.clear
|
62
|
+
super
|
63
|
+
end
|
51
64
|
|
52
65
|
private
|
53
66
|
|
54
67
|
def build_control
|
55
68
|
@libui = @parent_proxy.append_quit_item(*@args)
|
56
|
-
|
57
|
-
|
58
|
-
::LibUI.quit
|
59
|
-
0
|
60
|
-
end
|
69
|
+
# setup default on_clicked listener if no on_clicked listeners are setup
|
70
|
+
handle_listener('on_clicked') {} if @on_clicked_listeners.nil? || @on_clicked_listeners.empty?
|
61
71
|
end
|
62
72
|
end
|
63
73
|
end
|
@@ -33,15 +33,24 @@ module Glimmer
|
|
33
33
|
include Parent
|
34
34
|
|
35
35
|
def destroy
|
36
|
+
return if ControlProxy.main_window_proxy&.destroying?
|
37
|
+
return if @destroying
|
38
|
+
@destroying = true
|
39
|
+
deregister_all_custom_listeners
|
36
40
|
::LibUI.free_open_type_features(@libui)
|
37
|
-
@parent_proxy&.
|
41
|
+
@parent_proxy&.remove_open_type_features
|
38
42
|
ControlProxy.control_proxies.delete(self)
|
43
|
+
@destroying = false
|
39
44
|
end
|
40
45
|
|
41
46
|
def redraw
|
42
|
-
@parent_proxy
|
47
|
+
@parent_proxy&.redraw
|
43
48
|
end
|
44
49
|
|
50
|
+
def request_auto_redraw
|
51
|
+
@parent_proxy&.request_auto_redraw
|
52
|
+
end
|
53
|
+
|
45
54
|
private
|
46
55
|
|
47
56
|
def build_control
|
@@ -31,6 +31,8 @@ module Glimmer
|
|
31
31
|
# Follows the Proxy Design Pattern
|
32
32
|
class OpenTypeTagProxy < ControlProxy
|
33
33
|
def destroy
|
34
|
+
return if ControlProxy.main_window_proxy&.destroying?
|
35
|
+
deregister_all_custom_listeners
|
34
36
|
@parent_proxy&.children&.delete(self)
|
35
37
|
ControlProxy.control_proxies.delete(self)
|
36
38
|
end
|
@@ -36,7 +36,7 @@ module Glimmer
|
|
36
36
|
class TableProxy < ControlProxy
|
37
37
|
include Glimmer::FiddleConsumer
|
38
38
|
|
39
|
-
|
39
|
+
CUSTOM_LISTENER_NAMES = ['on_changed', 'on_edited']
|
40
40
|
|
41
41
|
attr_reader :model_handler, :model, :table_params, :columns, :column_attributes
|
42
42
|
|
@@ -91,18 +91,18 @@ module Glimmer
|
|
91
91
|
if @cell_rows.size < @last_cell_rows.size && @last_cell_rows.include_all?(*@cell_rows)
|
92
92
|
@last_cell_rows.array_diff_indexes(@cell_rows).reverse.each do |row|
|
93
93
|
::LibUI.table_model_row_deleted(model, row)
|
94
|
-
on_changed
|
94
|
+
notify_custom_listeners('on_changed', row, :deleted, @last_cell_rows[row])
|
95
95
|
end
|
96
96
|
elsif @cell_rows.size > @last_cell_rows.size && @cell_rows.include_all?(*@last_cell_rows)
|
97
97
|
@cell_rows.array_diff_indexes(@last_cell_rows).each do |row|
|
98
98
|
::LibUI.table_model_row_inserted(model, row)
|
99
|
-
on_changed
|
99
|
+
notify_custom_listeners('on_changed', row, :inserted, @cell_rows[row])
|
100
100
|
end
|
101
101
|
else
|
102
102
|
@cell_rows.each_with_index do |new_row_data, row|
|
103
103
|
if new_row_data != @last_cell_rows[row]
|
104
104
|
::LibUI.table_model_row_changed(model, row)
|
105
|
-
on_changed
|
105
|
+
notify_custom_listeners('on_changed', row, :changed, @cell_rows[row])
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
@@ -270,7 +270,7 @@ module Glimmer
|
|
270
270
|
@cell_rows[row].send(attribute)[1] = ::LibUI.table_value_string(val).to_s
|
271
271
|
end
|
272
272
|
when Column::ButtonColumnProxy
|
273
|
-
@columns[column].
|
273
|
+
@columns[column].notify_custom_listeners('on_clicked', row)
|
274
274
|
when Column::CheckboxColumnProxy
|
275
275
|
column = @columns[column].index
|
276
276
|
@cell_rows[row] ||= []
|
@@ -292,7 +292,7 @@ module Glimmer
|
|
292
292
|
@cell_rows[row].send(attribute)[0] = ::LibUI.table_value_int(val).to_i == 1
|
293
293
|
end
|
294
294
|
end
|
295
|
-
on_edited
|
295
|
+
notify_custom_listeners('on_edited', row, @cell_rows[row])
|
296
296
|
end
|
297
297
|
|
298
298
|
@model = ::LibUI.new_table_model(@model_handler)
|
@@ -29,6 +29,10 @@ module Glimmer
|
|
29
29
|
#
|
30
30
|
# Follows the Proxy Design Pattern
|
31
31
|
class WindowProxy < ControlProxy
|
32
|
+
CUSTOM_LISTENER_NAMES = ['on_destroy']
|
33
|
+
CUSTOM_LISTENER_NAME_ALIASES = {
|
34
|
+
on_destroyed: 'on_destroy',
|
35
|
+
}
|
32
36
|
DEFAULT_TITLE = ''
|
33
37
|
DEFAULT_WIDTH = 190
|
34
38
|
DEFAULT_HEIGHT = 150
|
@@ -44,22 +48,20 @@ module Glimmer
|
|
44
48
|
end
|
45
49
|
|
46
50
|
def destroy
|
51
|
+
return if @destroying
|
52
|
+
@destroying = true
|
53
|
+
@on_closing_listeners&.clear
|
47
54
|
super
|
48
55
|
ControlProxy.image_proxies.each { |image_proxy| ::LibUI.free_image(image_proxy.libui) unless image_proxy.area_image? }
|
49
|
-
|
56
|
+
notify_custom_listeners('on_destroy', self)
|
57
|
+
deregister_custom_listeners('on_destroy')
|
58
|
+
@destroying = false
|
50
59
|
end
|
51
60
|
|
52
|
-
def
|
53
|
-
|
54
|
-
@on_destroy_procs ||= []
|
55
|
-
if block.nil?
|
56
|
-
@on_destroy_procs
|
57
|
-
else
|
58
|
-
@on_destroy_procs << block
|
59
|
-
block
|
60
|
-
end
|
61
|
+
def destroying?
|
62
|
+
@destroying
|
61
63
|
end
|
62
|
-
|
64
|
+
|
63
65
|
def show
|
64
66
|
super
|
65
67
|
unless @shown_at_least_once
|
@@ -69,29 +71,29 @@ module Glimmer
|
|
69
71
|
end
|
70
72
|
end
|
71
73
|
|
72
|
-
def can_handle_listener?(listener_name)
|
73
|
-
listener_name == 'on_destroy' || super
|
74
|
-
end
|
75
|
-
|
76
74
|
def handle_listener(listener_name, &listener)
|
77
75
|
case listener_name
|
78
|
-
when '
|
79
|
-
|
80
|
-
|
81
|
-
default_behavior_listener
|
82
|
-
|
83
|
-
|
84
|
-
return_value =
|
85
|
-
if return_value.is_a?(Numeric)
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
76
|
+
when 'on_closing'
|
77
|
+
@on_closing_listeners ||= []
|
78
|
+
@on_closing_listeners << listener
|
79
|
+
@default_behavior_listener ||= Proc.new do
|
80
|
+
return_value = nil
|
81
|
+
@on_closing_listeners.each do |l|
|
82
|
+
return_value = l.call(self)
|
83
|
+
break if return_value.is_a?(Numeric)
|
84
|
+
end
|
85
|
+
if return_value.is_a?(Numeric)
|
86
|
+
return_value
|
87
|
+
else
|
88
|
+
destroy
|
89
|
+
::LibUI.quit
|
90
|
+
0
|
92
91
|
end
|
92
|
+
end.tap do |default_behavior_listener|
|
93
|
+
super(listener_name, &default_behavior_listener)
|
93
94
|
end
|
94
|
-
|
95
|
+
else
|
96
|
+
super
|
95
97
|
end
|
96
98
|
end
|
97
99
|
|
@@ -168,11 +170,8 @@ module Glimmer
|
|
168
170
|
@height = construction_args[2]
|
169
171
|
@libui = ControlProxy.new_control(@keyword, construction_args)
|
170
172
|
@libui.tap do
|
171
|
-
|
172
|
-
|
173
|
-
::LibUI.quit
|
174
|
-
0
|
175
|
-
end
|
173
|
+
# setup default on_closing listener if no on_closing listeners are setup
|
174
|
+
handle_listener('on_closing') {} if @on_closing_listeners.nil? || @on_closing_listeners.empty?
|
176
175
|
end
|
177
176
|
end
|
178
177
|
end
|
@@ -169,31 +169,49 @@ module Glimmer
|
|
169
169
|
def handle_listener(listener_name, &listener)
|
170
170
|
safe_listener = Proc.new { listener.call(self) }
|
171
171
|
if ::LibUI.respond_to?("#{libui_api_keyword}_#{listener_name}")
|
172
|
-
|
172
|
+
if listeners[listener_name].nil?
|
173
|
+
::LibUI.send("#{libui_api_keyword}_#{listener_name}", @libui) do
|
174
|
+
listeners_for(listener_name).map { |listener| listener.call }.last
|
175
|
+
end
|
176
|
+
end
|
177
|
+
listeners_for(listener_name) << safe_listener
|
173
178
|
elsif ::LibUI.respond_to?("control_#{listener_name}")
|
174
|
-
|
179
|
+
if listeners[listener_name].nil?
|
180
|
+
::LibUI.send("control_#{listener_name}", @libui) do
|
181
|
+
listeners_for(listener_name).map { |listener| listener.call }.last
|
182
|
+
end
|
183
|
+
end
|
184
|
+
listeners_for(listener_name) << safe_listener
|
175
185
|
elsif has_custom_listener?(listener_name)
|
176
186
|
handle_custom_listener(listener_name, &listener)
|
177
187
|
end
|
178
188
|
end
|
179
189
|
|
190
|
+
def listeners
|
191
|
+
@listeners ||= {}
|
192
|
+
end
|
193
|
+
|
194
|
+
def listeners_for(listener_name)
|
195
|
+
listeners[listener_name] ||= []
|
196
|
+
end
|
197
|
+
|
180
198
|
def has_custom_listener?(listener_name)
|
181
199
|
listener_name = listener_name.to_s
|
182
|
-
|
200
|
+
custom_listener_names.include?(listener_name) || custom_listener_name_aliases.stringify_keys.keys.include?(listener_name)
|
183
201
|
end
|
184
202
|
|
185
|
-
def
|
186
|
-
self.class.constants.include?(:
|
203
|
+
def custom_listener_names
|
204
|
+
self.class.constants.include?(:CUSTOM_LISTENER_NAMES) ? self.class::CUSTOM_LISTENER_NAMES : []
|
187
205
|
end
|
188
206
|
|
189
|
-
def
|
190
|
-
self.class.constants.include?(:
|
207
|
+
def custom_listener_name_aliases
|
208
|
+
self.class.constants.include?(:CUSTOM_LISTENER_NAME_ALIASES) ? self.class::CUSTOM_LISTENER_NAME_ALIASES : {}
|
191
209
|
end
|
192
210
|
|
193
211
|
def handle_custom_listener(listener_name, &listener)
|
194
212
|
listener_name = listener_name.to_s
|
195
|
-
listener_name =
|
196
|
-
instance_variable_name = "@#{listener_name}_procs"
|
213
|
+
listener_name = custom_listener_name_aliases.stringify_keys[listener_name] || listener_name
|
214
|
+
instance_variable_name = "@#{listener_name}_procs" # TODO ensure clearing custom listeners on destroy of a control
|
197
215
|
instance_variable_set(instance_variable_name, []) if instance_variable_get(instance_variable_name).nil?
|
198
216
|
if listener.nil?
|
199
217
|
instance_variable_get(instance_variable_name)
|
@@ -203,6 +221,21 @@ module Glimmer
|
|
203
221
|
end
|
204
222
|
end
|
205
223
|
|
224
|
+
def notify_custom_listeners(listener_name, *args)
|
225
|
+
handle_custom_listener(listener_name).each do |listener|
|
226
|
+
listener.call(*args)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def deregister_custom_listeners(listener_name)
|
231
|
+
handle_custom_listener(listener_name).clear
|
232
|
+
end
|
233
|
+
|
234
|
+
# deregisters all custom listeners except on_destroy, which can only be deregistered after destruction of a control, using deregister_custom_listeners
|
235
|
+
def deregister_all_custom_listeners
|
236
|
+
(custom_listener_names - ['on_destroy']).each { |listener_name| deregister_custom_listeners(listener_name) }
|
237
|
+
end
|
238
|
+
|
206
239
|
def respond_to?(method_name, *args, &block)
|
207
240
|
respond_to_libui?(method_name, *args, &block) ||
|
208
241
|
(
|
@@ -289,6 +322,8 @@ module Glimmer
|
|
289
322
|
end
|
290
323
|
|
291
324
|
def destroy
|
325
|
+
# TODO exclude menus from this initial return
|
326
|
+
return if !is_a?(ControlProxy::WindowProxy) && ControlProxy.main_window_proxy&.destroying?
|
292
327
|
data_binding_model_attribute_observer_registrations.each(&:deregister)
|
293
328
|
if parent_proxy.nil?
|
294
329
|
default_destroy
|
@@ -302,6 +337,7 @@ module Glimmer
|
|
302
337
|
end
|
303
338
|
|
304
339
|
def default_destroy
|
340
|
+
deregister_all_custom_listeners
|
305
341
|
send_to_libui('destroy')
|
306
342
|
ControlProxy.control_proxies.delete(self)
|
307
343
|
end
|
data/lib/glimmer/libui/shape.rb
CHANGED
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.
|
4
|
+
version: 0.4.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|