fxruby-enhancement 0.0.4 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b794b2f54a98c4013d5b65dac69a9941ed161e67
4
- data.tar.gz: ed4a967374dede324ae343e9db62ee5a0f0c2f9c
3
+ metadata.gz: ee35871b37b12dab95f43e9e0efe47c4eef62ae9
4
+ data.tar.gz: 23dad1cd5a49af520b2af586ea7fb11105c73966
5
5
  SHA512:
6
- metadata.gz: 22536ce016e05481e0ac75d6be53eb04e57298961d42f88e73b6076ae17aed1660d8eaa6389aaa0cac050c581e8ade966b90baf303ac7d5537805e5ad1294a26
7
- data.tar.gz: bbd2e87f25028ffc0b9b74ea7c4a17302ff833a0657411634b712cdd11b7383f16bdee6e90c6526a319ec3cd7e302accb4afbca57072d5916bb9d930d9a0254a
6
+ metadata.gz: e0f580dbe88affcab84a81b8c8ffc669d8a5f46e21c6dc5b59a95bb8d6c28ac4b45f3079dff633caddbeab5a101629b3ee0f76327a8a1702259279e4fef6b6c2
7
+ data.tar.gz: 8fa2425ff455205357d1cfc8e07073223dcda195a6205b6d953205f4e3a68a3120fc847af4781efcbd58335adc17dce9e0ec258bcf06f4172766ec96fd5cfade
data/.semver CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :major: 0
3
- :minor: 0
4
- :patch: 4
3
+ :minor: 1
4
+ :patch: 0
5
5
  :special: ''
@@ -12,7 +12,7 @@ GEM
12
12
  debug_inspector (0.0.2)
13
13
  descendants_tracker (0.0.4)
14
14
  thread_safe (~> 0.3, >= 0.3.1)
15
- diff-lcs (1.2.5)
15
+ diff-lcs (1.3)
16
16
  docile (1.1.5)
17
17
  faraday (0.9.2)
18
18
  multipart-post (>= 1.2, < 3)
data/README.org CHANGED
@@ -13,12 +13,15 @@
13
13
  - [[#the-queue_ding-queues][The Queue_Ding Queues]]
14
14
  - [[#enhancementingress][Enhancement.ingress]]
15
15
  - [[#enhancementegress][Enhancement.egress]]
16
+ - [[#reusable-components-and-dynamic-creation-and-the-reuse-flag][Reusable components and dynamic creation, and the 'reuse' flag]]
16
17
  - [[#api--dsl][API & DSL]]
17
18
  - [[#ref-refc-and-tagging-your-objects][ref(), refc() and tagging your objects]]
18
19
  - [[#fox_component-and-fox_instance][fox_component and fox_instance]]
19
20
  - [[#fx_app][fx_app]]
21
+ - [[#fx_data_target][fx_data_target]]
20
22
  - [[#instance][instance]]
21
23
  - [[#ingress_handler][ingress_handler]]
24
+ - [[#starten-and-stoppen-with-resuable-components][#starten and #stoppen with resuable components]]
22
25
  - [[#deferred_setup][deferred_setup]]
23
26
  - [[#mapping-between-fx_-declarations-and-the-fx-fxruby-objects][Mapping between fx_* declarations and the FX* FXRuby objects]]
24
27
  - [[#bindingfx][binding.fx]]
@@ -27,12 +30,15 @@
27
30
  - [[#hello-world-the-old-fxruby-way][Hello World the old fxruby way:]]
28
31
  - [[#bouncing-ball-example-full][Bouncing Ball example (full):]]
29
32
  - [[#bouncing-ball-the-old-fxruby-way][Bouncing Ball the old fxruby way:]]
33
+ - [[#datatarget-example][DataTarget Example]]
30
34
  - [[#release-notes][Release Notes]]
31
35
  - [[#known-issues][Known Issues]]
32
36
  - [[#contributing-to-fxruby-enhancement][Contributing to fxruby-enhancement]]
33
37
  - [[#copyright-and-licensing][Copyright and Licensing]]
34
38
  - [[#the-junkyard--scratchpad][The Junkyard / Scratchpad]]
35
- - [[#genesis-of-the-meta-meta-programming-whereby-brain-goes-boom][Genesis of the meta-meta programming, whereby brain goes boom]]
39
+ - [[#junkyard-genesis-of-the-meta-meta-programming-whereby-brain-goes-boom][JUNKYARD Genesis of the meta-meta programming, whereby brain goes boom]]
40
+ - [[#junkyard-resuable-components-and-data-targets][JUNKYARD Resuable components and data targets]]
41
+ - [[#junkyard-data-targets][JUNKYARD Data Targets]]
36
42
 
37
43
  * fxruby-enhancement
38
44
  ** Introduction
@@ -49,14 +55,23 @@
49
55
  fxruby-enhancement makes this a snap to do. You simply declare
50
56
  your GUI arrangement in a nested fashion. fxruby-enhancement will
51
57
  take care of passing parents to the nested children, and other issues
52
- as well. You can now focus on creating a good GUI layout that you
58
+ as well. You can now focus on creating your great GUI layout that you
53
59
  can change on the fly without much fuss and bother.
54
60
 
55
- fxruby-enhancement is basically a DSL of sorts, and every effort has
56
- been taken to make it intuitive to use. Once you get the hang of it,
57
- you should be able to look at the FXRuby API documentation and infer
58
- the DSL construct for fxruby-enhancement. Please also see the many
59
- [[file:examples][examples]].
61
+ fxruby-enhancement (also referred to as "Enhancement") is basically a
62
+ DSL of sorts, and every effort has been taken to make it intuitive to
63
+ use. Once you get the hang of it, you should be able to look at the
64
+ FXRuby API documentation and infer the DSL construct for fxruby-enhancement.
65
+ Please also see the many [[file:examples][examples]].
66
+
67
+ Enhancement basically leverages Ruby's singleton feature, and eliminates
68
+ the need to "subclass" the FXRuby objects and the like. In fact, you might
69
+ even consider this Enhancement's own "paradigm" for doing GUI programming.
70
+
71
+ Your input and criticisms are more than welcome. Feel free to raise
72
+ issues on GitHub. I have not anticipated all the ways someone might try
73
+ to use Enhancement. I am making heavy use of Enhancement in my RubyNEAT
74
+ project -- which is why I created it.
60
75
 
61
76
  ** Installation
62
77
  To install the gem from commandline:
@@ -196,7 +211,7 @@
196
211
  And so your handler will most likely act as a dispatcher
197
212
  for the payloads received. For example:
198
213
  #+begin_src ruby
199
- ingress_handler :status do |tag, logline|
214
+ ingress_handler :log_info, :log_error do |tag, logline|
200
215
  puts "received #{tag} => #{payload}"
201
216
  case tag
202
217
  when :log_info
@@ -207,6 +222,14 @@
207
222
  end
208
223
  #+end_src
209
224
 
225
+ Note that this ingress handler is responding to two tags. You can have
226
+ as many tags as you like for your ingress handler, and as many
227
+ ingress handlers as you like.
228
+
229
+ Currently, all the tags should be unique. Later we may support having
230
+ multiple blocks associated with the same tag. Please feel free to generate
231
+ an issue if you want this!!!
232
+
210
233
  ***** Enhancement.egress
211
234
  Wnen your Fox application needs to send a message to other
212
235
  listening threads, You simply push your payload onto the egress queue
@@ -216,9 +239,56 @@
216
239
  #+end_src
217
240
 
218
241
  and your Ruby thread external to Fox would simply do:
219
- #+begin_src
242
+ #+begin_src ruby
243
+ ...
244
+ message = Enhancement.egress.next
245
+ ...
246
+ #+end_src
247
+
248
+ where you'll block pending the arrival of the next message. If you
249
+ do not wish to block, you may do:
250
+ #+begin_src ruby
251
+ ...
252
+ unless Enhancement.egress.empty?
253
+ message = Enhancement.egress.next
254
+ else
255
+ # some action to take
256
+ end
257
+ ...
220
258
  #+end_src
221
259
 
260
+ *** Reusable components and dynamic creation, and the 'reuse' flag
261
+ There are times you may want to be able to create, and popup, say, a dialog
262
+ box, or perhaps you want to create on the fly child components on an
263
+ existing window.
264
+
265
+ This is made possible with the "reuse: true" flag. For example:
266
+ #+begin_src ruby
267
+ fx_dialog_box(:dialog, reuse: true) {
268
+ title "I am a Dialog!"
269
+ opts DECOR_ALL
270
+
271
+ fx_button {
272
+ text "&It Works!"
273
+ instance { |dia|
274
+ dia.sel_command {
275
+ refc(:dialog).stoppen
276
+ }
277
+ }
278
+ }
279
+ instance { |dia| dia.show PLACEMENT_OWNER }
280
+ }
281
+ #+end_src
282
+
283
+ This code snippet can be run in the context of the app or a window.
284
+ If you do it in a window context, that window will become the "owner",
285
+ and will initially be placed hovering over it.
286
+
287
+ With reusable components, you will use the #starten and #stoppen methods
288
+ to create and destroy the component. Please see
289
+ the [[file:examples/dialog_box.rb][Dialog Box]] for a full example, and also
290
+ the docs for #starten and #stoppen.
291
+
222
292
  *** API & DSL
223
293
  **** ref(), refc() and tagging your objects
224
294
  In an effort to eliminate the fuss and bother with
@@ -237,12 +307,25 @@
237
307
  refc(:some_tag).inst
238
308
  #+end_src
239
309
 
240
- There may be some edge cases where you might want to
241
- reference the underlying component ahead of FXRuby object
242
- instaniation, but in the vast majority of the cases, it should
243
- be unnecessary. My goal is to enable to do what you need, not
244
- to restrict you. You may need it for debugging, etc.
245
-
310
+ Where might you want to use refc() instead of ref()? In cases
311
+ where the underlying FXRuby object have not been instantiated yet,
312
+ you'd use refc() instead of ref(), almost always during the component
313
+ configuration. For example:
314
+ #+begin_src ruby
315
+ fx_app :app do
316
+ ...
317
+ fx_button {
318
+ text "&See Ya!"
319
+ selector FXApp::ID_QUIT
320
+ target refc(:app)
321
+ }
322
+ ...
323
+ #+end_src
324
+
325
+ Here, we set the button to exit the application by sending the FXApp object the ID_QUIT
326
+ message. But at the time we set the configuration, the FXApp object has not been instantiated
327
+ yet. So we use refc() instead of ref().
328
+
246
329
  Underlying, the component object is really a subclass of OpenScript.
247
330
  While you may like to stuff some additional data there,
248
331
  this is frowned upon because it might conflict with Enhancement.
@@ -293,6 +376,37 @@
293
376
  Typeically you'd do this inside of a module, but you could do it also
294
377
  in a class body. Please see the examples.
295
378
 
379
+ **** fx_data_target
380
+ FOX (and therefor FXRuby) supports data synchronization among components.
381
+ fx_data_target encapsulates the FXDataTarget class, just like all the
382
+ other fx_* directives do. However, in this case, some special treatment
383
+ is necessary since it is referenced at a time the underlying FXRuby
384
+ object has not been created yet.
385
+
386
+ Enter refc(). You use refc(), instead of ref(), to use it when you are
387
+ configuring the component (really, specifying the initial parameters
388
+ to the underlying FXRuby class!) We illustrate here:
389
+ #+begin_src ruby
390
+ ...
391
+ fx_data_target (:mydata) { value "initial value" }
392
+ ...
393
+ fx_text (:text_3) {
394
+ target refc(:mydata)
395
+ selector FXDataTarget::ID_VALUE
396
+ }
397
+ fx_text (:text_4) {
398
+ target refc(:mydata)
399
+ selector FXDataTarget::ID_VALUE
400
+ }
401
+ #+end_src
402
+
403
+ And so the two text components -- or widgets -- are initially
404
+ set to the value of "initial value", and when one changes, the
405
+ other is instantly updated.
406
+
407
+ Otherwise, you can deal with fx_data_target as expected. See
408
+ the [[#datatarget-example][DataTarget Example]].
409
+
296
410
  **** instance
297
411
  Inside of your component declaration, you will undoubtly
298
412
  want to specify what you want to do once the FXRuby object
@@ -379,6 +493,30 @@
379
493
 
380
494
  The same block is assigned to all the given tags of :warn, :info, and :error.
381
495
 
496
+ **** #starten and #stoppen with resuable components
497
+ To designate a component as reusable, declare it with "reuse: true"
498
+ as in the example:
499
+ #+begin_src ruby
500
+ fx_dialog_box(:dialog, reuse: true) { ... }
501
+ #+end_src
502
+
503
+ Then in the instance clause or to the response to an event,
504
+ you would do:
505
+ #+begin_src ruby
506
+ refc(:dialog).starten
507
+ #+end_src
508
+
509
+ to activate it, and
510
+ #+begin_src ruby
511
+ refc(:dialog).stoppen
512
+ #+end_src
513
+
514
+ to deactive it (and remove the 'server'-side FOX components!)
515
+
516
+ Note that you call refc(), not ref() in this case, because the
517
+ functionality lies in the component object holder for the actual
518
+ FOX component, not within the FXRuby object itself.
519
+
382
520
  **** TODO deferred_setup
383
521
  **** TODO Mapping between fx_* declarations and the FX* FXRuby objects
384
522
  **** binding.fx
@@ -418,7 +556,7 @@
418
556
 
419
557
  https://github.com/flajann2/rubyneat-panel/tree/master/lib/rubyneat-panel
420
558
 
421
- Class-based enhancement (this has not been tested yet!!!):
559
+ Class-based Enhancement (this is currently not supported!!!):
422
560
  #+begin_src ruby
423
561
  class Main < FXMainWindow
424
562
  compose :my_window do
@@ -451,7 +589,7 @@
451
589
  end
452
590
  #+end_src
453
591
 
454
- Class-free enhancement:
592
+ Class-free Enhancement (strongly recommended):
455
593
  #+begin_src ruby
456
594
  mw = fx_main_window :my_window do
457
595
  title "RubyNEAT Panel"
@@ -886,18 +1024,87 @@ end
886
1024
 
887
1025
  More examples can be found [[file:examples][HERE]].
888
1026
 
1027
+ **** DataTarget Example
1028
+ fx_data_target (:some_name) must be referenced as refc(:some_name) and
1029
+ not ref(...). See the example below.
1030
+
1031
+ #+begin_src ruby
1032
+ #!/usr/bin/env ruby
1033
+ require 'fxruby-enhancement'
1034
+
1035
+ include Fox
1036
+ include Fox::Enhancement::Mapper
1037
+
1038
+ fx_app :app do
1039
+ app_name "DataTarget"
1040
+ vendor_name "Example"
1041
+
1042
+ fx_data_target (:textx) { value "x marks the spot!" }
1043
+ fx_data_target (:texty) { value "y do it?" }
1044
+
1045
+ fx_main_window(:main) {
1046
+ title "fx_data_target example"
1047
+ opts DECOR_ALL
1048
+ width 300
1049
+ x 100
1050
+ y 200
1051
+
1052
+ fx_text_field (:text_1) {
1053
+ ncols 40
1054
+ target refc(:textx)
1055
+ selector FXDataTarget::ID_VALUE
1056
+ }
1057
+ fx_text_field (:text_2) {
1058
+ ncols 40
1059
+ target refc(:textx)
1060
+ selector FXDataTarget::ID_VALUE
1061
+ }
1062
+ fx_text (:text_3) {
1063
+ opts LAYOUT_FILL_X
1064
+ target refc(:texty)
1065
+ selector FXDataTarget::ID_VALUE
1066
+ }
1067
+ fx_text (:text_4) {
1068
+ opts LAYOUT_FILL_X
1069
+ target refc(:texty)
1070
+ selector FXDataTarget::ID_VALUE
1071
+ }
1072
+ fx_button {
1073
+ text "&See ya!"
1074
+ selector FXApp::ID_QUIT
1075
+ opts BUTTON_NORMAL|LAYOUT_CENTER_X
1076
+
1077
+ instance { |b|
1078
+ b.target = ref(:app)
1079
+ }
1080
+ }
1081
+
1082
+ instance { |w|
1083
+ w.show PLACEMENT_SCREEN
1084
+ }
1085
+ }
1086
+ end
1087
+
1088
+ # alias for fox_component is fxc
1089
+ fox_component :app do |app|
1090
+ app.launch
1091
+ end
1092
+ #+end_src
1093
+
889
1094
  ** Release Notes
890
- | Version | Date | Notes |
891
- |---------+------------+---------------------------------------------------------|
892
- | 0.0.2 | 2017-01-11 | Initial release |
893
- | 0.0.3 | 2017-01-15 | Needed to require fox16/colors for FXColor to be loaded |
894
- | 0.0.4 | 2017-01-16 | ingress_handler now handles multiple tags. |
1095
+ | Version | Date | Notes |
1096
+ |---------+------------+-------------------------------------------------------------|
1097
+ | 0.0.2 | 2017-01-11 | Initial release |
1098
+ | 0.0.3 | 2017-01-15 | Needed to require fox16/colors for FXColor to be loaded |
1099
+ | 0.0.4 | 2017-01-16 | ingress_handler now handles multiple tags. |
1100
+ | 0.1.0 | 2017-01-18 | special handling for fx_data_target and resuable components |
895
1101
 
896
1102
  ** Known Issues
897
- | Version | Date | Issues |
898
- |---------+------------+-------------------------------------------------------|
899
- | 0.0.2 | 2017-01-11 | Not enough example code!!! Need more documentation!!! |
900
-
1103
+ | Version | Date | Issues |
1104
+ |---------+------------------------+--------------------------------------------------------------------|
1105
+ | 0.0.2 | 2017-01-11 | Not enough example code!!! Need more documentation!!! |
1106
+ | 0.1.0 | Trump Inaguration Day, | deferred_setup not fully implemented, and may go away. |
1107
+ | | 2017-01-20 | compose is not really needed, and is not fully implemented anyway. |
901
1108
 
902
1109
  ** Contributing to fxruby-enhancement
903
1110
 
@@ -917,7 +1124,7 @@ end
917
1124
  You may see some interesting tidbits here, but I am not
918
1125
  gauranteeing anything to be useful or reliable in this
919
1126
  section. YOU HAVE BEEN WARNED.
920
- *** Genesis of the meta-meta programming, whereby brain goes boom
1127
+ *** JUNKYARD Genesis of the meta-meta programming, whereby brain goes boom
921
1128
  #+begin_src ruby
922
1129
  class FXToolBar # monkey patch
923
1130
  include Enhancement
@@ -953,3 +1160,19 @@ end
953
1160
  #+end_src
954
1161
 
955
1162
 
1163
+ *** JUNKYARD Resuable components and data targets
1164
+ We have an issue with needing to have reusable components
1165
+ (dialog boxes, say), and ṕroperly handling data targets designations.
1166
+ **** JUNKYARD Data Targets
1167
+ Data targets cannot be done the same way we are doing the other
1168
+ fxruby components, because they have a different workflow. Basically,
1169
+ they need to be instantiated before the other comonents that uses
1170
+ them, and they are not really "child" objects, either. Referring to them
1171
+ using the ref() or refc() approach simply fails, because they won't
1172
+ be instantiated in time.
1173
+
1174
+ We have ameroliated this problem by checking in the parameter list
1175
+ for an OpenStruct object, and calling #inst on it to pass in the instance,
1176
+ rather than the object itself. So now you simply use refc()
1177
+ in those cases.
1178
+
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fxruby-enhancement'
3
+
4
+ include Fox
5
+ include Fox::Enhancement::Mapper
6
+
7
+ fx_app :app do
8
+ app_name "DataTarget"
9
+ vendor_name "Example"
10
+
11
+ fx_data_target (:textx) { value "x marks the spot!" }
12
+ fx_data_target (:texty) { value "y do it?" }
13
+
14
+ fx_main_window(:main) {
15
+ title "fx_data_target example"
16
+ opts DECOR_ALL
17
+ width 300
18
+ x 100
19
+ y 200
20
+
21
+ fx_text_field (:text_1) {
22
+ ncols 40
23
+ target refc(:textx)
24
+ selector FXDataTarget::ID_VALUE
25
+ }
26
+ fx_text_field (:text_2) {
27
+ ncols 40
28
+ target refc(:textx)
29
+ selector FXDataTarget::ID_VALUE
30
+ }
31
+ fx_text (:text_3) {
32
+ opts LAYOUT_FILL_X
33
+ target refc(:texty)
34
+ selector FXDataTarget::ID_VALUE
35
+ }
36
+ fx_text (:text_4) {
37
+ opts LAYOUT_FILL_X
38
+ target refc(:texty)
39
+ selector FXDataTarget::ID_VALUE
40
+ }
41
+ fx_button {
42
+ text "&See ya!"
43
+ selector FXApp::ID_QUIT
44
+ opts BUTTON_NORMAL|LAYOUT_CENTER_X
45
+
46
+ instance { |b|
47
+ b.target = ref(:app)
48
+ }
49
+ }
50
+
51
+ instance { |w|
52
+ w.show PLACEMENT_SCREEN
53
+ }
54
+ }
55
+ end
56
+
57
+ # alias for fox_component is fxc
58
+ fox_component :app do |app|
59
+ app.launch
60
+ end