wxruby3 0.9.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. checksums.yaml +4 -4
  2. data/INSTALL.md +183 -42
  3. data/README.md +40 -48
  4. data/ext/mkrf_conf_ext.rb +72 -0
  5. data/lib/wx/core/app.rb +16 -0
  6. data/lib/wx/core/colour.rb +36 -28
  7. data/lib/wx/core/const.rb +19 -0
  8. data/lib/wx/core/enum.rb +17 -1
  9. data/lib/wx/core/geometry.rb +121 -0
  10. data/lib/wx/core/graphics_pen_info.rb +18 -0
  11. data/lib/wx/core/image.rb +49 -0
  12. data/lib/wx/core/menu_bar.rb +11 -0
  13. data/lib/wx/core/paintdc.rb +9 -3
  14. data/lib/wx/core/secret_store.rb +38 -0
  15. data/lib/wx/doc/app.rb +97 -41
  16. data/lib/wx/doc/bitmap.rb +4 -0
  17. data/lib/wx/doc/client_dc.rb +2 -2
  18. data/lib/wx/doc/clipboard.rb +1 -1
  19. data/lib/wx/doc/colour.rb +12 -0
  20. data/lib/wx/doc/const.rb +16 -0
  21. data/lib/wx/doc/cursor.rb +4 -0
  22. data/lib/wx/doc/dc_overlay.rb +34 -0
  23. data/lib/wx/doc/enum.rb +7 -1
  24. data/lib/wx/doc/event_blocker.rb +1 -1
  25. data/lib/wx/doc/evthandler.rb +25 -3
  26. data/lib/wx/doc/functions.rb +3 -6
  27. data/lib/wx/doc/gc_dc.rb +13 -4
  28. data/lib/wx/doc/geometry.rb +136 -0
  29. data/lib/wx/doc/graphics_context.rb +25 -7
  30. data/lib/wx/doc/icon.rb +4 -0
  31. data/lib/wx/doc/image.rb +56 -0
  32. data/lib/wx/doc/list_ctrl.rb +6 -6
  33. data/lib/wx/doc/memory_dc.rb +2 -11
  34. data/lib/wx/doc/mirror_dc.rb +1 -1
  35. data/lib/wx/doc/pen.rb +26 -0
  36. data/lib/wx/doc/persistence_manager.rb +1 -1
  37. data/lib/wx/doc/persistent_object.rb +1 -1
  38. data/lib/wx/doc/pg/property_grid_interface.rb +3 -3
  39. data/lib/wx/doc/prt/printer_dc.rb +2 -2
  40. data/lib/wx/doc/region_iterator.rb +1 -1
  41. data/lib/wx/doc/scaled_dc.rb +1 -1
  42. data/lib/wx/doc/screen_dc.rb +1 -1
  43. data/lib/wx/doc/secret_store.rb +55 -0
  44. data/lib/wx/doc/svg_file_dc.rb +1 -1
  45. data/lib/wx/doc/textctrl.rb +1 -1
  46. data/lib/wx/doc/tree_ctrl.rb +2 -2
  47. data/lib/wx/doc/validator.rb +6 -6
  48. data/lib/wx/doc/variant.rb +2 -2
  49. data/lib/wx/doc/window.rb +5 -4
  50. data/lib/wx/grid/keyword_defs.rb +1 -1
  51. data/lib/wx/html/keyword_defs.rb +3 -3
  52. data/lib/wx/keyword_defs.rb +76 -71
  53. data/lib/wx/pg/keyword_defs.rb +2 -2
  54. data/lib/wx/pg/pg_property.rb +12 -0
  55. data/lib/wx/rbn/keyword_defs.rb +1 -1
  56. data/lib/wx/rtc/keyword_defs.rb +1 -1
  57. data/lib/wx/stc/keyword_defs.rb +1 -1
  58. data/lib/wx/version.rb +1 -1
  59. data/lib/wx/wxruby/base.rb +3 -5
  60. data/lib/wx/wxruby/cmd/check.rb +182 -0
  61. data/lib/wx/wxruby/cmd/sampler.rb +1 -1
  62. data/lib/wx/wxruby/cmd/setup.rb +9 -3
  63. data/lib/wx/wxruby/cmd/test.rb +1 -1
  64. data/rakelib/configure.rb +67 -52
  65. data/rakelib/gem.rake +97 -66
  66. data/rakelib/gem.rb +294 -41
  67. data/rakelib/install.rb +3 -3
  68. data/rakelib/lib/config/{cygwin.rb → freebsd.rb} +1 -1
  69. data/rakelib/lib/config/linux.rb +4 -2
  70. data/rakelib/lib/config/macosx.rb +42 -11
  71. data/rakelib/lib/config/mingw.rb +2 -2
  72. data/rakelib/lib/config/pkgman/{base.rb → linux.rb} +36 -61
  73. data/rakelib/lib/config/pkgman/macosx.rb +17 -78
  74. data/rakelib/lib/config/unixish.rb +17 -8
  75. data/rakelib/lib/config/{netbsd.rb → unknown.rb} +3 -2
  76. data/rakelib/lib/config.rb +74 -33
  77. data/rakelib/lib/core/include/enum.inc +31 -1
  78. data/rakelib/lib/director/affine_matrix.rb +51 -0
  79. data/rakelib/lib/director/app.rb +29 -13
  80. data/rakelib/lib/director/art_provider.rb +4 -0
  81. data/rakelib/lib/director/aui_manager.rb +1 -1
  82. data/rakelib/lib/director/cursor.rb +6 -2
  83. data/rakelib/lib/director/dc.rb +1 -6
  84. data/rakelib/lib/director/derived_dc.rb +88 -31
  85. data/rakelib/lib/director/geometry.rb +142 -0
  86. data/rakelib/lib/director/graphics_context.rb +3 -2
  87. data/rakelib/lib/director/graphics_object.rb +18 -25
  88. data/rakelib/lib/director/grid_ctrl.rb +2 -2
  89. data/rakelib/lib/director/image.rb +59 -0
  90. data/rakelib/lib/director/menu.rb +2 -3
  91. data/rakelib/lib/director/menu_bar.rb +0 -3
  92. data/rakelib/lib/director/pen.rb +1 -1
  93. data/rakelib/lib/director/richtext_composite_object.rb +2 -4
  94. data/rakelib/lib/director/richtext_ctrl.rb +1 -1
  95. data/rakelib/lib/director/secret_store.rb +117 -0
  96. data/rakelib/lib/director/system_settings.rb +1 -1
  97. data/rakelib/lib/director/tree_event.rb +2 -2
  98. data/rakelib/lib/director/window.rb +4 -3
  99. data/rakelib/lib/extractor/function.rb +1 -1
  100. data/rakelib/lib/generate/doc/animation_ctrl.yaml +10 -0
  101. data/rakelib/lib/generate/doc/banner_window.yaml +35 -0
  102. data/rakelib/lib/generate/doc/graphics_context.yaml +12 -0
  103. data/rakelib/lib/generate/doc/graphics_object.yaml +12 -0
  104. data/rakelib/lib/generate/doc/grid_ctrl.yaml +25 -0
  105. data/rakelib/lib/generate/doc/header_ctrl.yaml +91 -0
  106. data/rakelib/lib/generate/doc/icon.yaml +10 -0
  107. data/rakelib/lib/generate/doc/info_bar.yaml +27 -0
  108. data/rakelib/lib/generate/doc/log.yaml +1 -1
  109. data/rakelib/lib/generate/doc/media_ctrl.yaml +27 -0
  110. data/rakelib/lib/generate/doc/persistent_window.yaml +22 -0
  111. data/rakelib/lib/generate/doc/pg_editor.yaml +1 -1
  112. data/rakelib/lib/generate/doc/pg_property.yaml +4 -4
  113. data/rakelib/lib/generate/doc/rearrange_list.yaml +14 -0
  114. data/rakelib/lib/generate/doc/ribbon_panel.yaml +15 -0
  115. data/rakelib/lib/generate/doc/rich_text_formatting_dialog.yaml +26 -0
  116. data/rakelib/lib/generate/doc/secret_store.yaml +55 -0
  117. data/rakelib/lib/generate/doc/text_ctrl.yaml +1 -1
  118. data/rakelib/lib/generate/doc/wizard.yaml +27 -0
  119. data/rakelib/lib/generate/doc.rb +5 -5
  120. data/rakelib/lib/generate/interface.rb +1 -1
  121. data/rakelib/lib/specs/interfaces.rb +4 -0
  122. data/rakelib/lib/swig_runner.rb +24 -3
  123. data/rakelib/lib/typemap/common.rb +10 -0
  124. data/rakelib/lib/typemap/points_list.rb +8 -2
  125. data/rakelib/lib/typemap/richtext.rb +17 -0
  126. data/rakelib/prepost.rake +8 -1
  127. data/rakelib/yard/templates/default/fulldoc/html/css/wxruby3.css +4 -0
  128. data/rakelib/yard/templates/default/fulldoc/html/setup.rb +3 -3
  129. data/samples/dialogs/wizard.rb +20 -19
  130. data/samples/drawing/art/drawing/image.bmp +0 -0
  131. data/samples/drawing/art/drawing/mask.bmp +0 -0
  132. data/samples/drawing/art/drawing/pat35.bmp +0 -0
  133. data/samples/drawing/art/drawing/pat36.bmp +0 -0
  134. data/samples/drawing/art/drawing/pat4.bmp +0 -0
  135. data/samples/drawing/art/drawing/smile.xpm +42 -0
  136. data/samples/drawing/drawing.rb +2276 -0
  137. data/samples/drawing/tn_drawing.png +0 -0
  138. data/samples/html/html.rb +1 -1
  139. data/samples/propgrid/propgrid.rb +1 -1
  140. data/samples/propgrid/propgrid_minimal.rb +1 -1
  141. data/samples/propgrid/sample_props.rb +1 -1
  142. data/samples/sampler/editor.rb +13 -11
  143. data/samples/sampler/sample.rb +2 -0
  144. data/samples/sampler.rb +14 -10
  145. data/samples/text/richtext.rb +53 -0
  146. data/samples/text/scintilla.rb +1 -1
  147. data/samples/text/unicode.rb +4 -4
  148. data/tests/lib/wxapp_runner.rb +1 -1
  149. data/tests/test_config.rb +7 -4
  150. data/tests/test_ext_controls.rb +12 -5
  151. data/tests/test_secret_store.rb +83 -0
  152. data/tests/test_std_controls.rb +12 -12
  153. metadata +66 -47
  154. data/lib/wx/doc/extra/00_starting.md +0 -154
  155. data/lib/wx/doc/extra/01_packages.md +0 -180
  156. data/lib/wx/doc/extra/02_lifecycles.md +0 -166
  157. data/lib/wx/doc/extra/03_dialogs.md +0 -57
  158. data/lib/wx/doc/extra/04_enums.md +0 -143
  159. data/lib/wx/doc/extra/05_event-handling.md +0 -191
  160. data/lib/wx/doc/extra/06_geometry.md +0 -62
  161. data/lib/wx/doc/extra/07_colour_and_font.md +0 -52
  162. data/lib/wx/doc/extra/08_extensions.md +0 -144
  163. data/lib/wx/doc/extra/09_exceptions.md +0 -54
  164. data/lib/wx/doc/extra/10_art.md +0 -111
  165. data/lib/wx/doc/extra/11_drawing_and_dc.md +0 -62
  166. data/lib/wx/doc/extra/12_client_data.md +0 -89
  167. data/lib/wx/doc/extra/13_validators.md +0 -139
  168. data/lib/wx/doc/extra/14_config.md +0 -101
  169. data/lib/wx/doc/extra/15_persistence.md +0 -148
  170. data/rakefile +0 -14
  171. data/rakelib/lib/config/pkgman/arch.rb +0 -53
  172. data/rakelib/lib/config/pkgman/debian.rb +0 -66
  173. data/rakelib/lib/config/pkgman/rhel.rb +0 -54
  174. data/rakelib/lib/config/pkgman/suse.rb +0 -54
  175. data/samples/sampler/back.xpm +0 -21
  176. data/samples/sampler/copy.xpm +0 -44
  177. data/samples/sampler/cut.xpm +0 -46
  178. data/samples/sampler/filesave.xpm +0 -42
  179. data/samples/sampler/find.xpm +0 -62
  180. data/samples/sampler/findrepl.xpm +0 -63
  181. data/samples/sampler/forward.xpm +0 -21
  182. data/samples/sampler/paste.xpm +0 -46
  183. data/samples/sampler/redo.xpm +0 -58
  184. data/samples/sampler/undo.xpm +0 -58
@@ -1,166 +0,0 @@
1
- <!--
2
- # @markup markdown
3
- # @title 2. wxRuby Life Cycles
4
- -->
5
-
6
- # 2. wxRuby Life Cycles
7
-
8
- ## Introduction
9
-
10
- Managing the life cycles of native objects in Ruby extension libraries is tricky business because of the disparity
11
- between common C++ dynamic memory management and the GC management scheme of the Ruby language and this certainly applies
12
- to an event based environment like the wxRuby extension for wxWidgets.
13
- That said, the wxRuby library should provide you with a fairly worry-free API in that respect.
14
-
15
- The wxRuby extension manages to provide water-tight GC management for just about all mapped wxWidget objects.
16
-
17
- There are just a few, fairly specific, things to take notice of.
18
-
19
- ## Application instance
20
-
21
- Any wxWidgets application typically creates a single application instance and the same goes for wxRuby applications.
22
- We already saw [here](00_starting.md) how to start a wxRuby application. Important to note is that any reference to the
23
- (global) application instance will ever only be valid as long as the application is still active.<br>
24
- In essence this means the reference is valid from the moment the constructor (`#initialize`) is called to the moment
25
- any available `#on_exit` method has finished.
26
-
27
- There are some caveats to that however.
28
-
29
- 1. Although the application instance is valid in the constructor, the wxWidgets
30
- framework will only be fully initialized the moment the `#on_init` method starts. This means that all kinds of methods
31
- requiring initialized GUI resources (like window creation) will fail if called before that moment.
32
-
33
- 2. The global application instance returned by `Wx.get_app` will only be set from the moment the `#on_init` method
34
- starts to the moment the `#on_exit` method finishes. Outside that timespan the method will return `nil`.
35
-
36
- Also be careful with storing your own application instance variables. Code like
37
-
38
- ```ruby
39
- class MyApp < Wx::App
40
- def initialize
41
- super
42
- # ...
43
- end
44
- def on_init
45
- # ...
46
- end
47
- end
48
- $app = MyApp.new
49
- $app.run
50
- ```
51
-
52
- is entirely valid but for the fact that you **should** remember that after the `#run` method returns the `$app` variable
53
- does **not** reference a valid application instance anymore. Calling methods on that instance may result in unexpected
54
- behavior.<br>
55
- It is actually easier and safer to rewrite this code as:
56
-
57
- ```ruby
58
- class MyApp < Wx::App
59
- def initialize
60
- super
61
- # ...
62
- end
63
- def on_init
64
- # ...
65
- end
66
- end
67
- MyApp.run # or MyApp.new.run
68
- ```
69
-
70
- This way there is no reference to accidentally use after `#run` returns and `Wx.get_app` will return `nil` after that
71
- moment.
72
-
73
- ## Framework (re-)initialization
74
-
75
- As mentioned above the wxWidgets GUI framework resources will only be fully initialized after the `#on_init` method
76
- starts. Likewise the framework resources will be de-initialized (deleted) after `#on_exit` method ends which means that
77
- your application should not attempt to access any of these resources (windows, fonts, colours etc.) after that moment.
78
-
79
- Also, largely because of the way the wxWidgets framework is designed but also because of the way this meshes with Ruby
80
- GC, there is no safe way to re-initialize the framework after an application instance ends it run. This means you
81
- **cannot** safely attempt to start another application instance after a previous (first) one has ended.
82
-
83
- ## Windows
84
-
85
- Window instances (and it's derivatives) are fully managed by the wxWidget framework and cannot (are not) managed by
86
- Ruby GC handling. This means on the one hand that a window instances life time is not controlled by any reference
87
- a Ruby variable may hold and on the other hand that the Ruby object linked to that native window object is kept alive
88
- (marked in GC) as long as the window instance is alive.<br>
89
- Generally speaking window lifetimes are dependent on the (toplevel) window (or it's parent) being closed. In case of a
90
- toplevel window this result in automatic destruction of the window and all it's child windows (controls). There are
91
- however exceptions to this where explicit calling of a window's `#destroy` method is required to prevent memory leaks
92
- (when a window is not a child window but also not a toplevel window for example or in case of dialogs; see
93
- [here](03_dialogs.md)). Please check out the wxWidgets documentation for more detailed information.
94
-
95
- This has several consequences you need to be aware of.
96
-
97
- First of, in cases where you keep a reference to any window (control) instance in a local or instance variable in Ruby
98
- (which is fairly common practice) you need to be aware that the reference is only valid as long as the window has not
99
- been destroyed. In most cases this will not be an issue as most references are kept as instance variables of parent
100
- windows for child windows where the instance variables will only ever be used as long the parent window is alive itself.
101
- In other circumstances you should take care to track the lifetime of the window that is referenced.
102
-
103
- Secondly, as already indicated above not all window instances will be automatically destroyed. It is for example fairly
104
- common in more complex applications to create and show other windows as response to events triggered in the toplevel
105
- window. These windows will not (and should not) be automatically designated as toplevel window but they are also not
106
- owned (i.e. not child windows). Closing these windows will not automatically destroy them (which is a good thing as
107
- these are often re-shown after renewed events from the toplevel window) and will also not be automatically destroyed
108
- when any parent window is destroyed. This means they pose a threat for potential memory leaks.<br>
109
- In case it concerns a fairly simple application which creates one or two of these sub-windows and needs to keep these
110
- around for most or all of the lifetime of the application this is not really an issue as the window will be cleaned up
111
- at application exit eventually. If however it concerns a more complex application which potentially could create a large
112
- number of these sub windows (probably each only used for limited purposes) it would be advisable to track instances and
113
- destroy these on a regular basis when not used (closed) possibly re-creating them as needed.
114
-
115
- Dialogs are special cases of toplevel windows which are not automatically destroyed when closed. The wxRuby library
116
- therefor provides special support to ease handling the destruction of these. See [here](03_dialogs.md) for more details.
117
-
118
- ## Object identities
119
-
120
- One of the trickier things to handle correctly in the kind of native extensions like wxRuby is maintaining object
121
- identities i.e. keeping native instances synced with their Ruby wrapper counter parts.
122
-
123
- Whenever a native extension is allowed to call back into Ruby space we encounter the problem that we need to map any
124
- native object data provided for the call to the right Ruby types and when necessary to the right Ruby instance (object
125
- identity).
126
-
127
- Objects that are considered POD types (*plain old data* types) like numerics, booleans, strings, arrays and hashes do
128
- not require maintaining *object identity*. For these objects it is enough to map them to the right Ruby type before
129
- passing them on to Ruby space.
130
-
131
- For a lot of other objects though it is essential to not only map to the right **most derived** class type but also to
132
- the exact Ruby instance which was originally instantiated as wrapper for the native object if any exists (in case no
133
- Ruby instance existed yet a new instance of the correct **most derived** class should be instantiated at that point).
134
- The reason this is important is **1.** because the Ruby instance may have been used to identify, link to or otherwise
135
- reference other data and/or functionality related to that specific Ruby/native pair and **2.** the Ruby instance could
136
- contain data elements (instance variables) related to that specific Ruby/native pair.<br>
137
- In the case of wxRuby Window instance for example it is common to derive custom Window classes with custom behaviour and
138
- corresponding instance variables that drive that behaviour. When an event handler or an overloaded native method is passed
139
- a native window object we absolutely need to be able to map that native object to the correct Ruby wrapper instance so
140
- all information stays in sync.
141
-
142
- For this purpose wxRuby uses *object tracking* i.e. maintaining hash tables mapping native object pointers to Ruby object
143
- values. Whenever a tracked object is instantiated it is registered and can from than on be resolved whenever needed to map
144
- from native object to Ruby object.<br>
145
- Of course this also means wxRuby has to track object destruction so mappings can be removed when a native object is
146
- destructed.<br>
147
- Additionally the tracking tables are also used to mark Ruby objects during the GC marking phase so they do not get garbage
148
- collected whenever they are not referenced in Ruby space anymore but still functioning in native space (this is for example
149
- a common situation for many child windows created but not permanently referenced in Ruby space).
150
-
151
- Tracking and resolving mappings from tracking tables produces a certain computing overhead but testing has shown this to be
152
- absolutely acceptable for normal applications.
153
-
154
- There are however quite a lot of wrapped native objects in wxRuby for which *object identity* is not essential. For these
155
- object tracking has been disabled for their classes. This means these kind of classes/object should **not** be derived from
156
- (if even possible and/or useful) to add functionality/information or their identity used as key to link other information.<br>
157
- These classes include:
158
- * classes considered POD types like Wx::Size, Wx::Point, Wx::RealPoint, Wx::Rect, Wx::GBSpan, Wx::GBPosition, Wx::BusyInfoFlags,
159
- Wx::AboutDialogInfo
160
- * final non-instantiatable classes like the Wx::DC (Device Context) class family, Wx::GraphicsContext, Wx::WindowsDisabler,
161
- Wx::EventBlocker, Wx::BusyInfo
162
- * classes with native singleton objects like Wx::Clipboard
163
- * the reference counted GDI objects like Wx::Pen, Wx::Brush, Wx::Colour, Wx::Cursor, Wx::Bitmap, Wx::Icon and similar
164
- reference counted objects like Wx::Font
165
-
166
- The reference documentation will note untracked object classes.
@@ -1,57 +0,0 @@
1
- <!--
2
- # @markup markdown
3
- # @title 3. wxRuby Dialogs
4
- -->
5
-
6
- # 3. wxRuby Dialogs
7
-
8
- Dialogs are a special class of window which are never automatically destroyed in wxWidgets.
9
- In C++ this does not cause a lot of management overhead for application programmers because of the possibility of
10
- static declaration of dialogs instances where the statically declared object is automatically destructed as execution
11
- leaves the declaration scope.<br>
12
- This kind of construct does not exist in Ruby where everything is dynamically allocated and garbage collection normally
13
- takes care of releasing objects that have gone *'out of scope'*.
14
-
15
- Like any non-owned, non-toplevel windows as discussed [here](02_lifecycles.md) this means dialogs should be explicitly
16
- destroyed in program code as appropriate like:
17
-
18
- ```ruby
19
- dlg = Wx::MessageDialog.new(parent, 'Select Yes or No', "Confirmation", Wx::YES_NO)
20
- if dlg.show_modal == Wx::ID_YES
21
- # do something
22
- end
23
- dlg.destroy
24
- ```
25
-
26
- Although this is sometimes useful (for example in cases where a dialog is repeatedly used), most of the time this makes
27
- for somewhat bothersome programming.
28
-
29
- Luckily wxRuby has a solution for this.
30
-
31
- For all dialog classes (which includes Wx::Dialog and all it's derivatives, including user defined) the library defines
32
- a module function which is identically named to the dialog class in the same scope as where the dialog class has been
33
- first defined. This is similar to the module functions Ruby itself defines for the basic object classes like `Integer`,
34
- `String`, `Array`, `Hash` and such for the `Kernel` module.<br>
35
- These dialog *functors* accept the same arguments as the dialog class's constructor with the addition of a block. The
36
- *functor* will call the class constructor and pass the created dialog instance as argument to the block. After returning
37
- from the block the dialog instance will automatically be destroyed. So, using this approach we could write the previous
38
- example like:
39
-
40
- ```ruby
41
- Wx.MessageDialog(parent, 'Select Yes or No', "Confirmation", Wx::YES_NO) do |dlg|
42
- if dlg.show_modal == Wx::ID_YES
43
- # do something
44
- end
45
- end
46
- ```
47
-
48
- Even better, if the only purpose is to show the dialog until closed without caring for the result we can leave out the
49
- block. In that case the *functor* will simply create the dialog instance, call `#show_modal` on it and destroy the
50
- instance after returning from `#show_modal` like:
51
-
52
- ```ruby
53
- Wx.MessageDialog(parent, 'Hello world!', 'Information', Wx::OK)
54
- ```
55
-
56
- Regular dialog constructors are still usable for situations where the dialog instance should have a
57
- prolonged lifetime or where different modeless behavior is required.
@@ -1,143 +0,0 @@
1
- <!--
2
- # @markup markdown
3
- # @title 4. wxRuby Enum values
4
- -->
5
-
6
- # 4. wxRuby Enum values
7
-
8
- The wxWidget library liberally mixes integer constants and enum values for things like IDs, style flags
9
- and option flags and such without much consistency.<br>
10
- In previous wxRuby versions these were all mapped to integer constants which had 2 distinct disadvantages.
11
-
12
- - **loss of scoping**<br>
13
- Integer constants for enum values would all be declared in the enclosing scope for the enum declaration loosing
14
- the naming scope which originally existed in C++ (excepting anonymous enums).
15
-
16
- - **loss of type-safety**<br>
17
- Constants for enum values with identical integer values are indistinguishable from each other.
18
-
19
- The wxRuby3 project attempts to provide a solution to that by introducing the `Wx::Enum` class which
20
- is used as a base class for mapping all (named) wxWidget enums to Ruby.
21
- The reference documentation for the `Wx::Enum` class can be found [here](https://mcorino.github.io/wxRuby3/Wx/Enum.html).
22
-
23
- Any named wxWidget enum is mapped to a similarly named (Rubified C++ name) derived Enum class with each enum value
24
- defined as a constant of the enum class referencing an instance of the enum class with the corresponding
25
- integer value like for example the 'wxSystemFont' enum which is defined in wxRuby as:
26
-
27
- ```ruby
28
- module Wx
29
- class SystemFont < Wx::Enum
30
-
31
- # Original equipment manufacturer dependent fixed-pitch font.
32
- #
33
- SYS_OEM_FIXED_FONT = Wx::SystemFont.new(10)
34
-
35
- # Windows fixed-pitch (monospaced) font.
36
- #
37
- SYS_ANSI_FIXED_FONT = Wx::SystemFont.new(11)
38
-
39
- # Windows variable-pitch (proportional) font.
40
- #
41
- SYS_ANSI_VAR_FONT = Wx::SystemFont.new(12)
42
-
43
- # System font.
44
- #
45
- SYS_SYSTEM_FONT = Wx::SystemFont.new(13)
46
-
47
- # Device-dependent font.
48
- #
49
- SYS_DEVICE_DEFAULT_FONT = Wx::SystemFont.new(14)
50
-
51
- # Default font for user interface objects such as menus and dialog boxes.
52
- #
53
- SYS_DEFAULT_GUI_FONT = Wx::SystemFont.new(17)
54
-
55
- end # SystemFont
56
- end
57
- ```
58
-
59
- or the 'wxBorder' enum which is defined in wxRuby as:
60
-
61
- ```ruby
62
- module Wx
63
- # Border flags for {Wx::Window}.
64
- class Border < Wx::Enum
65
-
66
- # This is different from {Wx::Border::BORDER_NONE} as by default the controls do have a border.
67
- #
68
- BORDER_DEFAULT = Wx::Border.new(0)
69
-
70
- #
71
- #
72
- BORDER_NONE = Wx::Border.new(2097152)
73
-
74
- #
75
- #
76
- BORDER_STATIC = Wx::Border.new(16777216)
77
-
78
- #
79
- #
80
- BORDER_SIMPLE = Wx::Border.new(33554432)
81
-
82
- #
83
- #
84
- BORDER_RAISED = Wx::Border.new(67108864)
85
-
86
- #
87
- #
88
- BORDER_SUNKEN = Wx::Border.new(134217728)
89
-
90
- #
91
- #
92
- BORDER_DOUBLE = Wx::Border.new(268435456)
93
-
94
- #
95
- #
96
- BORDER_THEME = Wx::Border.new(268435456)
97
-
98
- #
99
- #
100
- BORDER_MASK = Wx::Border.new(522190848)
101
-
102
- end # Border
103
- end
104
- ```
105
-
106
- Enum instances are interchangeable with integer constants in wxRuby with respect to arithmetic or logical
107
- operations. This make it possible to use enum values to construct integer bitflag arguments like:
108
-
109
- ```ruby
110
- Wx::TextCtrl.new(pane, Wx::ID_ANY, sample_desc.description, style: Wx::TE_MULTILINE|Wx::TE_READONLY|Wx::BORDER_NONE)
111
- ```
112
-
113
- where `Wx::ID_ANY` is a `Wx::StandardID` enum instance passed to provide an integer argument value, `Wx::TE_MULTILINE`
114
- and `Wx::TE_READONLY` are simple integer constants and `Wx::BORDER_NONE` is a `Wx::Border` enum instance.
115
-
116
- In other cases however enum values can provide just the right kind of type safety where explicit enum values are
117
- expected like for example with:
118
-
119
- ```ruby
120
- Wx::Font.new(36, Wx::FONTFAMILY_SWISS, Wx::FONTSTYLE_NORMAL, Wx::FONTWEIGHT_NORMAL)
121
- ```
122
-
123
- where the `Wx::Font` constructor definition is:
124
-
125
- > initialize(pointSize, family, style, weight, underline = false, faceName = `Wx::EMPTY_STRING`, encoding = `Wx::FONTENCODING_DEFAULT`) ⇒ `Wx::Font`
126
-
127
- with the following parameter specification:
128
-
129
- > - pointSize (`Integer`)
130
- > - family (`Wx::FontFamily`)
131
- > - style (`Wx::FontStyle`)
132
- > - weight (`Wx::FontWeight`)
133
- > - underline (`true`, `false`) (defaults to: `false`)
134
- > - faceName (`String`) (defaults to: `Wx::EMPTY_STRING`)
135
- > - encoding (`Wx::FontEncoding`) (defaults to: `Wx::FONTENCODING_DEFAULT`)
136
-
137
- In this case the constructor explicitly expects specific enum value types for *family*, *style* and *weigth* and
138
- providing the integer literal value `74` instead of `Wx::FONTFAMILY_SWISS` (or any other constant representing the same
139
- integer value) will not work (raises an exception) although the integer values for the two are equal.
140
-
141
- As you have probably noticed it is not required to use the full naming for an enum instance constant (like
142
- `Wx::FontFamily::FONTFAMILY_SWISS`). All enum value constants are accessible from the naming scope where the enum class
143
- to which they belong has been declared.
@@ -1,191 +0,0 @@
1
- <!--
2
- # @markup markdown
3
- # @title 5. wxRuby Event Handling
4
- -->
5
-
6
- # 5. wxRuby Event Handling
7
-
8
- ## Introduction
9
-
10
- Event handling is the core of runtime code execution in event based frameworks like wxWidgets which means it needs to
11
- be fully supported by wxRuby. Fortunately it is.<br>
12
- As Ruby is a fully dynamic language though the statically declared event tables typical for wxWidgets application are not.<br>
13
- Instead wxRuby offers a dynamic solution that is just as easy to use and even offers more flexibility in a typical Ruby-way.
14
-
15
- ## Event handlers
16
-
17
- Instead of the `EVT_XXX` event handler declaration macros used in wxWidgets wxRuby provides similarly named event handler
18
- definition methods for each of the known event declarations which are inherited by **all** classes derived from {Wx::
19
- EvtHandler}
20
- (which includes all window classes, the {Wx::App} class and {Wx::Timer} as well as various other classes).<br>
21
-
22
- Naming is (mostly) identical but rubified. So `EVT_MENU` becomes `evt_menu`, `EVT_IDLE` becomes `evt_idle`, `EVT_UPDATE_UI`
23
- becomes `evt_update_ui` etc.
24
-
25
- Like the event handler macros some of these methods require a single (window) id (like `evt_menu`) or a range of of ids
26
- (specified through a first and last id like for `evt_update_ui_range`) and some require only a handler definition (like
27
- `evt_idle`).
28
-
29
- Event handler setup is typically something done during the initialization of an event handler object (like a window) but
30
- this is not required. As all event handlers are assigned dynamically in wxRuby you can setup (some) event handlers at a
31
- later moment. You could also disconnect earlier activated handlers at any time (see {Wx::EvtHandler#disconnect}).
32
-
33
- In case of some frame class `MyForm` including a menu a wxWidgets static event handling table like:
34
-
35
- ```c++
36
- wxBEGIN_EVENT_TABLE(MyForm, wxFrame)
37
- EVT_IDLE(MyForm::OnIdle)
38
- EVT_MOVE(MyForm::OnMove)
39
- EVT_SIZE(MyForm::OnResize)
40
-
41
- EVT_MENU( wxID_ABOUT, MyForm::OnAbout )
42
- EVT_MENU( wxID_EXIT, MyForm::OnCloseClick )
43
- wxEND_EVENT_TABLE()
44
- ```
45
-
46
- could translate to event handler initializations in wxRuby like this:
47
-
48
- ```ruby
49
- class MyForm < Wx::Frame
50
-
51
- def initialize(title)
52
- super(nil, title: title)
53
-
54
- # initialize frame elements
55
- # ...
56
-
57
- # setup event handlers
58
- evt_idle do |evt|
59
- # do something
60
- evt.skip
61
- end
62
- evt_move :on_move
63
-
64
- evt_size method(:on_size)
65
-
66
- evt_menu(Wx::ID_ABOUT, Proc.new { on_about })
67
- evt_menu(Wx::ID_EXIT) { close(false) }
68
- end
69
-
70
- def on_idle(evt)
71
- #...
72
- end
73
-
74
- def on_move(evt)
75
- #...
76
- end
77
-
78
- def on_resize(evt)
79
- #...
80
- end
81
-
82
- def on_about
83
- #...
84
- end
85
-
86
- end
87
- ```
88
-
89
- As you can see there are multiple options for specifying the actual handler. Any event handler definition method will
90
- accept either a `Symbol` (or `String`) specifying a method of the receiver (the event handler instance), a `Proc` object
91
- (or lambda) or a `Method` object.
92
-
93
- Event handler methods are not required to declare the single event object argument. The event handler definition method
94
- will take care of checking and handling method arity.
95
-
96
- ## Custom Events
97
-
98
- Custom event definitions are fully supported in wxRuby including the definition of new event types.
99
-
100
- New event classes can be registered with {Wx::EvtHandler#register_class} which returns the new event type for the event
101
- class like this:
102
-
103
- ```ruby
104
- # A custom type of event associated with a target control. Note that for
105
- # user-defined controls, the associated event should inherit from
106
- # Wx::CommandEvent rather than Wx::Event.
107
- class ProgressUpdateEvent < Wx::CommandEvent
108
- # Create a new unique constant identifier, associate this class
109
- # with events of that identifier and create an event handler definition method 'evt_update_progress'
110
- # for setting up this handler.
111
- EVT_UPDATE_PROGRESS = Wx::EvtHandler.register_class(self, nil, 'evt_update_progress', 0)
112
-
113
- def initialize(value, gauge)
114
- # The constant id is the arg to super
115
- super(EVT_UPDATE_PROGRESS)
116
- # simply use instance variables to store custom event associated data
117
- @value = value
118
- @gauge = gauge
119
- end
120
-
121
- attr_reader :value, :gauge
122
- end
123
- ```
124
-
125
- Check the reference documentation [here](https://mcorino.github.io/wxRuby3/Wx/EvtHandler.html) for more information.
126
-
127
- ## Event processing
128
-
129
- In wxRuby overruling the normal chain of event handling has been limited to being able to override the default
130
- {Wx::EvtHandler#try_before} and {Wx::EvtHandler#try_after} methods. These are the advised interception points for events
131
- when you really need to do this.<br>
132
- Overriding {Wx::EvtHandler#process_event} is not considered to be efficient (or desired)
133
- for wxRuby applications and has therefor been blocked.
134
-
135
- ## Event insertion
136
-
137
- Use of {Wx::EvtHandler#process_event} or {Wx::EvtHandler#queue_event} and {Wx::EvtHandler#add_pending_event} in wxRuby to
138
- trigger event processing of user generated (possibly custom) events is fully supported.
139
-
140
- As with wxWidgets {Wx::EvtHandler#process_event} will trigger immediate processing of the given event, not returning before
141
- this has finished.<br>
142
- {Wx::EvtHandler#queue_event} and {Wx::EvtHandler#add_pending_event} on the other hand will post (append) the given event
143
- to the event queue and return immediately after that is done. The event will than be processed after any other events in
144
- the queue. Unlike in wxWidgets in wxRuby there is no practical difference between `queue_event` and `add_pending_event`.
145
-
146
- ## Asynchronous execution
147
-
148
- In addition to {Wx::EvtHandler#queue_event} and {Wx::EvtHandler#add_pending_event} to trigger asynchronous processing
149
- wxRuby also supports {Wx::EvtHandler#call_after}.
150
-
151
- This method provides the means to trigger asynchronous execution of arbitrary code and because it has been rubified is
152
- easy and powerful to use. Like with event handler definition this method accepts a `Symbol` or `String` (identifying a
153
- method of the receiver), a `Proc` object (or lambda), a `Method` object or a block. Unlike an event handler method no
154
- event object will be passed but rather any arguments passed to the `call_after` method in addition to the 'handler'.
155
-
156
- Given an event handler object `call_after` could be used like:
157
-
158
- ```ruby
159
- # sync call to method of event handler (no args)
160
- evt_handler.call_after :async_method
161
-
162
- # async call of lambda (single arg)
163
- evt_handler.call_after(->(txt) { Wx.log_info(txt) }, "Hello")
164
-
165
- # async call of block
166
- evt_handler.call_after('Call nr. %d', 1) { |fmt, num| Wx.log_info(fmt, num) }
167
- ```
168
-
169
- ## Event life cycles!
170
-
171
- Like in C++ the wxRuby Event objects passed to the event handlers are (in general) references to **temporary** objects
172
- which are only safe to access within the execution scope of the event handler that received the reference.
173
- If you *need* (really?) to store a reference to such an object do so to a cloned version (see {Wx::Event#clone}) and **not**
174
- to the original object otherwise you **will** run into 'Object already deleted' exceptions.
175
-
176
- Only user defined events instantiated in Ruby code (or cloned Event objects) will be subject to Ruby's normal life cycle
177
- rules (GC).
178
- This means that when you instantiate a user defined event and pass it to {Wx::EvtHandler#process_event} it would be possible
179
- to directly store the reference to such an Event object passed to it's event handler. You have to **know** for sure though
180
- (see below). So, in case of doubt (or to be safe) use {Wx::Event#clone}.
181
-
182
- Another 'feature' to be aware of is the fact that when passing an (user instantiated) Event object to {Wx::
183
- EvtHandler#queue_event}
184
- or {Wx::EvtHandler#add_pending_event} the Ruby event instance is unlinked from it's C++ counterpart (or in the case of user
185
- defined events a cloned instance is associated with it's C++ counterpart) before being queued and the C++ side now takes ownership
186
- (and will delete the Event object when handled).
187
- As a result this means that even in the case of a user defined Event object any event handler triggered by a asynchronously
188
- processed event will be handling a temporary Event object.
189
- Additionally this also means that any Event object passed to {Wx::EvtHandler#queue_event} or {Wx::
190
- EvtHandler#add_pending_event}
191
- is essentially invalidated after these methods return and should not be referenced anymore.
@@ -1,62 +0,0 @@
1
- <!--
2
- # @markup markdown
3
- # @title 6. wxRuby geometry classes
4
- -->
5
-
6
- # 6. wxRuby Geometry classes
7
-
8
- ## Size (Wx::Size) and position (Wx::Point and Wx::RealPoint)
9
-
10
- The wxWidgets API has a lot methods that require either `wxSize`, `wxPoint` or both type of value as argument. Although
11
- this can be specified in C++ still relatively concise like
12
- ```ruby
13
- new wxFrame(nullptr, -1, "title", wxPoint(0,0), wxSize(500,400))
14
- ```
15
- in Ruby this expands to the more verbose
16
- ```ruby
17
- Wx::Frame.new(nil, -1, 'title', Wx::Point.new(0,0), Wx::Size.new(500,400))
18
- ```
19
- which starts to feel awkward to specify what are in essence just pairs of integers.
20
-
21
- To provide a simpler, more compact and more Ruby-like, alternative the wxRuby API therefor supports specifying arrays
22
- of integer (or float in case of {Wx::RealPoint}) pairs in (almost) all cases where {Wx::Size} or {Wx::Point}
23
- (or {Wx::RealPoint}) is expected. So the following code is equivalent to the previous code:
24
- ```ruby
25
- Wx::Frame.new(nil, -1, 'title', [0,0], [500,400])
26
- ```
27
-
28
- In addition {Wx::Size}, {Wx::Point} and {Wx::RealPoint} support parallel assignment semantics such that you can write code like
29
- ```ruby
30
- win.paint do | dc |
31
- # ...
32
- x, y = win.get_position
33
- dc.draw_circle(x, y, 4)
34
- dc.draw_rectangle(x-4, y-4, 8, 8)
35
- end
36
- ```
37
- instead of
38
- ```ruby
39
- win.paint do | dc |
40
- # ...
41
- pos = win.get_position
42
- dc.draw_circle(pos.x, pos.y, 4)
43
- dc.draw_rectangle(pos.x-4, pos.y-4, 8, 8)
44
- end
45
- ```
46
-
47
- Instances of these classes can also be converted (back) to arrays with their `#to_ary` methods.
48
-
49
- Lastly wxRuby also extends the standard Ruby Array class with conversion methods to explicitly convert
50
- arrays to {Wx::Size}, {Wx::Point} or {Wx::RealPoint}; respectively the `#to_size`, `#to_point` and `#to_real_point`
51
- methods.
52
-
53
- ## Areas (Wx::Rect)
54
-
55
- Like {Wx::Size} and {Wx::Point} wxRuby supports parallel assignment for {Wx::Rect} such that you can write code like
56
- ```ruby
57
- x, y, width, height = win.get_client_rect
58
- ```
59
-
60
- Providing arrays of integers as alternative for `Wx::Rect` arguments is not supported as specifying `[0, 0, 20, 40]` is
61
- ambiguous. This could either mean a rectangle with origin `x=0,y=0` and size `width=20,height=40` (`Wx::Rect.new(0,0,20,40)`)
62
- or a rectangle from origin top left `x=0,y=0` to point bottom right `x=20,y=40` (`Wx::Rect.new(Wx::Point.new(0,0), Wx::Point.new(20,40))`).
@@ -1,52 +0,0 @@
1
- <!--
2
- # @markup markdown
3
- # @title 7. wxRuby Colour and Font
4
- -->
5
-
6
- # 6. wxRuby Colour and Font
7
-
8
- ## Introduction
9
-
10
- The wxWidgets API makes use of typical C++ features to support automatic conversion of certain types providing
11
- user friendly options for argument specifications. This way for example a developer does not need to explicitly
12
- declare a colour object construction where a colour instance value is expected but rather can specify a simple string
13
- constant like:
14
-
15
- ```C++
16
- wxPen pen;
17
- pen.SetColour("CYAN"); // instead of pen.SetColour(wxColour("CYAN"));
18
- ```
19
-
20
- For the wxRuby API similar support has been achieved for various much used argument types.
21
-
22
- ## Colour
23
-
24
- Wherever a {Wx::Colour} object is expected as an argument wxRuby supports the specification of `String` or `Symbol`
25
- values as a developer friendly alternative. This way the following code is equivalent:
26
-
27
- ```ruby
28
- pen = Wx::Pen.new
29
- pen.set_colour(Wx::Colour.new("CYAN"))
30
-
31
- pen = Wx::Pen.new
32
- pen.set_colour("CYAN")
33
-
34
- pen = Wx::Pen.new
35
- pen.set_colour(:CYAN)
36
- ```
37
-
38
- ## Font
39
-
40
- Wherever a {Wx::Font} object is expected as an argument wxRuby supports the specification of a {Wx::FontInfo} object.
41
- This way the following code is equivalent:
42
-
43
- ```ruby
44
- title = Wx::StaticText.new(self, -1, "Title")
45
- title.set_font(Wx::Font.new(18, Wx::FontFamily::FONTFAMILY_SWISS, Wx::FontStyle::FONTSTYLE_NORMAL, Wx::FontWeight::FONTWEIGHT_BOLD))
46
-
47
- title = Wx::StaticText.new(self, -1, "Title")
48
- title.set_font(Wx::FontInfo.new(18)
49
- .family(Wx::FontFamily::FONTFAMILY_SWISS)
50
- .style(Wx::FontStyle::FONTSTYLE_NORMAL)
51
- .bold())
52
- ```