wxruby3 0.9.8 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/INSTALL.md +23 -1
- data/README.md +13 -27
- data/ext/mkrf_conf_ext.rb +11 -7
- data/lib/wx/core/app.rb +16 -0
- data/lib/wx/core/colour.rb +36 -28
- data/lib/wx/core/const.rb +19 -0
- data/lib/wx/core/enum.rb +17 -1
- data/lib/wx/core/geometry.rb +121 -0
- data/lib/wx/core/graphics_pen_info.rb +18 -0
- data/lib/wx/core/image.rb +49 -0
- data/lib/wx/core/menu_bar.rb +11 -0
- data/lib/wx/core/paintdc.rb +9 -3
- data/lib/wx/doc/app.rb +97 -41
- data/lib/wx/doc/bitmap.rb +4 -0
- data/lib/wx/doc/client_dc.rb +2 -2
- data/lib/wx/doc/clipboard.rb +1 -1
- data/lib/wx/doc/colour.rb +12 -0
- data/lib/wx/doc/const.rb +16 -0
- data/lib/wx/doc/cursor.rb +4 -0
- data/lib/wx/doc/dc_overlay.rb +34 -0
- data/lib/wx/doc/enum.rb +7 -1
- data/lib/wx/doc/event_blocker.rb +1 -1
- data/lib/wx/doc/evthandler.rb +25 -3
- data/lib/wx/doc/functions.rb +3 -6
- data/lib/wx/doc/gc_dc.rb +13 -4
- data/lib/wx/doc/geometry.rb +136 -0
- data/lib/wx/doc/graphics_context.rb +25 -7
- data/lib/wx/doc/icon.rb +4 -0
- data/lib/wx/doc/image.rb +56 -0
- data/lib/wx/doc/list_ctrl.rb +6 -6
- data/lib/wx/doc/memory_dc.rb +2 -11
- data/lib/wx/doc/mirror_dc.rb +1 -1
- data/lib/wx/doc/pen.rb +26 -0
- data/lib/wx/doc/persistence_manager.rb +1 -1
- data/lib/wx/doc/persistent_object.rb +1 -1
- data/lib/wx/doc/pg/property_grid_interface.rb +3 -3
- data/lib/wx/doc/prt/printer_dc.rb +2 -2
- data/lib/wx/doc/region_iterator.rb +1 -1
- data/lib/wx/doc/scaled_dc.rb +1 -1
- data/lib/wx/doc/screen_dc.rb +1 -1
- data/lib/wx/doc/svg_file_dc.rb +1 -1
- data/lib/wx/doc/textctrl.rb +1 -1
- data/lib/wx/doc/tree_ctrl.rb +2 -2
- data/lib/wx/doc/validator.rb +6 -6
- data/lib/wx/doc/variant.rb +2 -2
- data/lib/wx/doc/window.rb +5 -4
- data/lib/wx/grid/keyword_defs.rb +1 -1
- data/lib/wx/html/keyword_defs.rb +3 -3
- data/lib/wx/keyword_defs.rb +76 -71
- data/lib/wx/pg/keyword_defs.rb +2 -2
- data/lib/wx/pg/pg_property.rb +12 -0
- data/lib/wx/rbn/keyword_defs.rb +1 -1
- data/lib/wx/rtc/keyword_defs.rb +1 -1
- data/lib/wx/stc/keyword_defs.rb +1 -1
- data/lib/wx/version.rb +1 -1
- data/lib/wx/wxruby/cmd/setup.rb +3 -0
- data/rakelib/configure.rb +7 -0
- data/rakelib/gem.rake +3 -2
- data/rakelib/gem.rb +3 -2
- data/rakelib/lib/config/linux.rb +1 -1
- data/rakelib/lib/config/mingw.rb +4 -101
- data/rakelib/lib/config/pkgman/linux.rb +31 -8
- data/rakelib/lib/config/pkgman/mingw.rb +112 -0
- data/rakelib/lib/config/unixish.rb +6 -7
- data/rakelib/lib/config.rb +25 -4
- data/rakelib/lib/core/include/enum.inc +31 -1
- data/rakelib/lib/director/affine_matrix.rb +51 -0
- data/rakelib/lib/director/app.rb +29 -13
- data/rakelib/lib/director/art_provider.rb +4 -0
- data/rakelib/lib/director/cursor.rb +6 -2
- data/rakelib/lib/director/dc.rb +1 -6
- data/rakelib/lib/director/derived_dc.rb +88 -31
- data/rakelib/lib/director/dialog.rb +0 -8
- data/rakelib/lib/director/geometry.rb +142 -0
- data/rakelib/lib/director/graphics_context.rb +3 -2
- data/rakelib/lib/director/graphics_object.rb +18 -25
- data/rakelib/lib/director/image.rb +59 -0
- data/rakelib/lib/director/menu.rb +2 -3
- data/rakelib/lib/director/menu_bar.rb +0 -3
- data/rakelib/lib/director/pen.rb +1 -1
- data/rakelib/lib/director/richtext_ctrl.rb +1 -1
- data/rakelib/lib/director/system_settings.rb +1 -1
- data/rakelib/lib/director/window.rb +9 -3
- data/rakelib/lib/extractor/function.rb +1 -1
- data/rakelib/lib/generate/doc/animation_ctrl.yaml +10 -0
- data/rakelib/lib/generate/doc/banner_window.yaml +35 -0
- data/rakelib/lib/generate/doc/graphics_context.yaml +12 -0
- data/rakelib/lib/generate/doc/graphics_object.yaml +12 -0
- data/rakelib/lib/generate/doc/grid_ctrl.yaml +25 -0
- data/rakelib/lib/generate/doc/header_ctrl.yaml +91 -0
- data/rakelib/lib/generate/doc/icon.yaml +10 -0
- data/rakelib/lib/generate/doc/info_bar.yaml +27 -0
- data/rakelib/lib/generate/doc/log.yaml +1 -1
- data/rakelib/lib/generate/doc/media_ctrl.yaml +27 -0
- data/rakelib/lib/generate/doc/persistent_window.yaml +22 -0
- data/rakelib/lib/generate/doc/pg_editor.yaml +1 -1
- data/rakelib/lib/generate/doc/pg_property.yaml +4 -4
- data/rakelib/lib/generate/doc/rearrange_list.yaml +14 -0
- data/rakelib/lib/generate/doc/ribbon_panel.yaml +15 -0
- data/rakelib/lib/generate/doc/rich_text_formatting_dialog.yaml +26 -0
- data/rakelib/lib/generate/doc/text_ctrl.yaml +1 -1
- data/rakelib/lib/generate/doc/wizard.yaml +27 -0
- data/rakelib/lib/generate/doc.rb +4 -4
- data/rakelib/lib/generate/interface.rb +1 -1
- data/rakelib/lib/specs/interfaces.rb +3 -0
- data/rakelib/lib/swig_runner.rb +24 -3
- data/rakelib/lib/typemap/points_list.rb +8 -2
- data/rakelib/lib/typemap/richtext.rb +17 -0
- data/rakelib/yard/templates/default/fulldoc/html/setup.rb +3 -3
- data/samples/dialogs/wizard.rb +20 -19
- data/samples/drawing/art/drawing/image.bmp +0 -0
- data/samples/drawing/art/drawing/mask.bmp +0 -0
- data/samples/drawing/art/drawing/pat35.bmp +0 -0
- data/samples/drawing/art/drawing/pat36.bmp +0 -0
- data/samples/drawing/art/drawing/pat4.bmp +0 -0
- data/samples/drawing/art/drawing/smile.xpm +42 -0
- data/samples/drawing/drawing.rb +2276 -0
- data/samples/drawing/tn_drawing.png +0 -0
- data/samples/html/html.rb +1 -1
- data/samples/propgrid/propgrid.rb +1 -1
- data/samples/propgrid/propgrid_minimal.rb +1 -1
- data/samples/propgrid/sample_props.rb +1 -1
- data/samples/sampler/editor.rb +13 -11
- data/samples/sampler.rb +14 -10
- data/samples/text/richtext.rb +53 -0
- data/samples/text/scintilla.rb +1 -1
- data/samples/text/unicode.rb +4 -4
- data/tests/test_ext_controls.rb +12 -5
- data/tests/test_gdi_object.rb +2 -2
- data/tests/test_std_controls.rb +12 -12
- metadata +33 -32
- data/lib/wx/doc/extra/00_starting.md +0 -154
- data/lib/wx/doc/extra/01_packages.md +0 -180
- data/lib/wx/doc/extra/02_lifecycles.md +0 -166
- data/lib/wx/doc/extra/03_dialogs.md +0 -57
- data/lib/wx/doc/extra/04_enums.md +0 -143
- data/lib/wx/doc/extra/05_event-handling.md +0 -191
- data/lib/wx/doc/extra/06_geometry.md +0 -62
- data/lib/wx/doc/extra/07_colour_and_font.md +0 -52
- data/lib/wx/doc/extra/08_extensions.md +0 -144
- data/lib/wx/doc/extra/09_exceptions.md +0 -54
- data/lib/wx/doc/extra/10_art.md +0 -111
- data/lib/wx/doc/extra/11_drawing_and_dc.md +0 -62
- data/lib/wx/doc/extra/12_client_data.md +0 -89
- data/lib/wx/doc/extra/13_validators.md +0 -139
- data/lib/wx/doc/extra/14_config.md +0 -101
- data/lib/wx/doc/extra/15_persistence.md +0 -148
- data/samples/sampler/back.xpm +0 -21
- data/samples/sampler/copy.xpm +0 -44
- data/samples/sampler/cut.xpm +0 -46
- data/samples/sampler/filesave.xpm +0 -42
- data/samples/sampler/find.xpm +0 -62
- data/samples/sampler/findrepl.xpm +0 -63
- data/samples/sampler/forward.xpm +0 -21
- data/samples/sampler/paste.xpm +0 -46
- data/samples/sampler/redo.xpm +0 -58
- data/samples/sampler/undo.xpm +0 -58
data/lib/wx/doc/extra/10_art.md
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
<!--
|
2
|
-
# @markup markdown
|
3
|
-
# @title 10. wxRuby Locating and loading art
|
4
|
-
-->
|
5
|
-
|
6
|
-
# 10. wxRuby Locating and loading art
|
7
|
-
|
8
|
-
## Introduction
|
9
|
-
|
10
|
-
With C++ wxWidgets applications art (icons, bitmaps, cursors, images) can be loaded in a variety
|
11
|
-
of ways from embedded resources (platform specific binary resources or embedded XPM files) or from
|
12
|
-
binary datasets retrieved from some data source.
|
13
|
-
|
14
|
-
With wxRuby that is for various reasons not a viable option so we are left with the option to
|
15
|
-
load art from files. In and of itself that option is not really too bad but for the issue of locating
|
16
|
-
the art files.
|
17
|
-
Art that is part of the application's design will preferably be stored with the source code but there
|
18
|
-
is not standard for this nor is there any standard support for locating those files from the application
|
19
|
-
code like there is for `require`-s of other code modules.
|
20
|
-
|
21
|
-
The wxRuby framework provides a convenience module {Wx::ArtLocator} to assist in that respect.
|
22
|
-
{Wx::ArtLocator} aims on the one side to standardize folder structures for storing art files and on the
|
23
|
-
other side to provide runtime support for locating those files from code.
|
24
|
-
|
25
|
-
The main locator method provided is:
|
26
|
-
|
27
|
-
```ruby
|
28
|
-
module Wx::Locator
|
29
|
-
def self.find_art(art_name, art_type: nil, art_path: nil, art_section: nil, bmp_type: nil)
|
30
|
-
# ...
|
31
|
-
end
|
32
|
-
end
|
33
|
-
```
|
34
|
-
|
35
|
-
The 'art_name' argument should provide the base name for matching art files and can be specified as either
|
36
|
-
String or Symbol.
|
37
|
-
|
38
|
-
## Storage locations
|
39
|
-
|
40
|
-
Wx::ArtLocator defines a standardized directory structure that is assumed to be used for application art
|
41
|
-
file storage.
|
42
|
-
Working from a certain (application defined) base search path ('art_path' argument) this structure looks like this:
|
43
|
-
|
44
|
-
<art_path>
|
45
|
-
\art
|
46
|
-
\<art_section>
|
47
|
-
\<art_type>
|
48
|
-
|
49
|
-
Where '<art_path>' is an application supplied search path, 'art' is the default name for Art folders (this can be overridden by an application specific name),
|
50
|
-
'<art_section>' is an application defined id allowing sub-categorizing art and '<art_type>' is the type of art indicator
|
51
|
-
(which can be 'icon', 'bitmap', 'cursor', 'image').
|
52
|
-
Art files can be located at any level in this hierarchy and all sub levels in this hierarchy are optional.
|
53
|
-
When locating files the art locator will test a file's existence at all levels starting with the
|
54
|
-
deepest level working it's way up returning the absolute path of the first file found this way.
|
55
|
-
|
56
|
-
So locating an art file would involve testing for the file at the following paths:
|
57
|
-
1. \<art_path>/art/<art_section>/<art_type>/
|
58
|
-
2. \<art_path>/art/<art_section>/
|
59
|
-
3. \<art_path>/art/
|
60
|
-
4. \<art_path>/
|
61
|
-
|
62
|
-
The first location can be skipped by specifying `nil` for 'art_type'.
|
63
|
-
|
64
|
-
## Bitmap types
|
65
|
-
|
66
|
-
Based on platform and specified '<art_type>' (and optionally a specific {Wx::BitmapType}) art files with a specific
|
67
|
-
range of extensions will be tested in a specific order.
|
68
|
-
For example for locating an `:icon` (<art_type>) on platform 'WXGTK' the locator will test the preferred extension
|
69
|
-
'.xpm' followed by any of supported extensions of all other supported bitmap types.
|
70
|
-
For platform 'WXMSW' however the same search would test only the extensions '.ico' and '.xpm' (in that
|
71
|
-
order).
|
72
|
-
Specifying a specific {Wx::BitmapType} for a search will restrict the search to testing only the extensions supported
|
73
|
-
for the specified {Wx::BitmapType}.
|
74
|
-
|
75
|
-
## Search paths
|
76
|
-
|
77
|
-
To prevent having to specify base search path for every location request {Wx::Locator} provides 2 options.
|
78
|
-
|
79
|
-
When an explicit specification of a base search path ('art_path) is omitted from a location request the locator
|
80
|
-
will determine one by using `Kernel#caller_locations` to extract the absolute path for the source file containing
|
81
|
-
the caller's code. The result of `File.dirname(src_path)` is than used as base search path.
|
82
|
-
If 'art_section' is also omitted the result of `File.basename(src_path, '.*')` will be used instead.
|
83
|
-
|
84
|
-
This means that calling {Wx::ArtLocator.find_art} from some code in file `/some/lib/path/to/ruby/code.rb` without
|
85
|
-
specifying both 'art_path' and 'art_section' would result in looking for an art file with the base search path
|
86
|
-
being `/some/lib/path/to/ruby/` and using `code` as 'art_section'.
|
87
|
-
|
88
|
-
It is also possible to add 'application global' search paths with the method {Wx::ArtLocator.add_search_path}.
|
89
|
-
Search paths added in this way will be tested after failing to find any matching art file at the initial 'art_path'
|
90
|
-
location. The same location steps apply to these search paths as with the initial 'art_path' (see above).
|
91
|
-
|
92
|
-
## Convenience methods
|
93
|
-
|
94
|
-
Based on the {Wx::ArtLocator} implementation wxRuby additionally provides a number of convenience methods to
|
95
|
-
easily create Icons, Bitmaps, Cursors and Images from simple ids (symbols):
|
96
|
-
|
97
|
-
- {Wx.Bitmap}
|
98
|
-
- {Wx.Cursor}
|
99
|
-
- {Wx.Icon}
|
100
|
-
- {Wx.Image}
|
101
|
-
|
102
|
-
These methods mimic the ease of use of the `wxICON` and `wxBITMAP` macros used with C++ wxWidgets such that
|
103
|
-
creating an {Wx::Icon} instance could be as easy as:
|
104
|
-
|
105
|
-
```ruby
|
106
|
-
frame.icon = Wx.Icon(:sample)
|
107
|
-
```
|
108
|
-
|
109
|
-
As these methods apply the same search path 'automagic' as `Wx::ArtLocator.find_art` (see [Search paths](#Search-paths))
|
110
|
-
this would search for an art file with base name 'sample' and an appropriate extension (like '.xpm' for the 'WXGTK' platform)
|
111
|
-
in a location starting at the directory in which the caller's code is stored (applying the steps described above).
|
@@ -1,62 +0,0 @@
|
|
1
|
-
<!--
|
2
|
-
# @markup markdown
|
3
|
-
# @title 11. wxRuby Drawing and Device Contexts
|
4
|
-
-->
|
5
|
-
|
6
|
-
# 11. wxRuby Drawing and Device Contexts (DC)
|
7
|
-
|
8
|
-
In wxRuby the Wx::DC class family provides functionality for drawing to windows, bitmaps, printers etc.
|
9
|
-
|
10
|
-
What most of these classes have in common is that actual drawing output is buffered until the time the
|
11
|
-
device context object is destroyed.
|
12
|
-
For this reason the common practice in wxWidgets C++ code would be to create temporary DC objects on the
|
13
|
-
stack and draw on them while they are in scope (for several classes it is even strongly advised to never create
|
14
|
-
them any other way and to never keep objects alive out of scope). When leaving the scope these object would than be
|
15
|
-
automatically destroyed and any buffered output flushed to the final target.
|
16
|
-
|
17
|
-
In Ruby this approach is impossible as Ruby is a purely dynamic language and does not support **this kind** of scope bound
|
18
|
-
life cycles. Any DC object created would have to be dynamically created and due to the properties of the GC driven
|
19
|
-
life cycles could well be kept alive beyond the scope of it's creation. This will not always cause problems but could
|
20
|
-
and does not really have an upside.
|
21
|
-
|
22
|
-
To prevent confusion and potential problems wxRuby defines all {Wx::DC} derived classes to be abstract classes that
|
23
|
-
cannot be instantiated using `new`. Rather all {Wx::DC} derived classes provide `::draw_on` factory methods to create
|
24
|
-
temporary dc objects that will be passed on to blocks given and will only exist for the duration of the execution of
|
25
|
-
the block. This will guarantee proper DC cleanup when leaving it's usage scope.
|
26
|
-
|
27
|
-
> Note that it is a **BAD** idea to think about storing the dc reference provided to the block for later access!
|
28
|
-
|
29
|
-
A typical usage of a `::draw_on` method would be:
|
30
|
-
|
31
|
-
```ruby
|
32
|
-
myTestBitmap1x = Wx::Bitmap.new(60, 15, 32)
|
33
|
-
Wx::MemoryDC.draw_on(myTestBitmap1x) do |mdc|
|
34
|
-
mdc.set_background(Wx::WHITE_BRUSH)
|
35
|
-
mdc.clear
|
36
|
-
mdc.set_pen(Wx::BLACK_PEN)
|
37
|
-
mdc.set_brush(Wx::WHITE_BRUSH)
|
38
|
-
mdc.draw_rectangle(0, 0, 60, 15)
|
39
|
-
mdc.draw_line(0, 0, 59, 14)
|
40
|
-
mdc.set_text_foreground(Wx::BLACK)
|
41
|
-
mdc.draw_text("x1", 0, 0)
|
42
|
-
end
|
43
|
-
```
|
44
|
-
|
45
|
-
## Windows, Wx::PaintDC and Wx::AutoBufferedPaintDC
|
46
|
-
|
47
|
-
The {Wx::PaintDC} and {Wx::AutoBufferedPaintDC} classes provide `::draw_on` methods just like all other DC classes but
|
48
|
-
this is mostly to be consistent.
|
49
|
-
|
50
|
-
In this case it is recommended to instead use the {Wx::Window#paint} or {Wx::Window#paint_buffered} methods as these
|
51
|
-
provide some optimizations with regard to automatically detecting if the methods are called inside `Wx::EVT_PAINT`
|
52
|
-
handlers (which should normally be the case) or not.
|
53
|
-
|
54
|
-
So the typical way to do buffered painting inside a windows `Wx::EVT_PAINT` handler would be something like:
|
55
|
-
|
56
|
-
```ruby
|
57
|
-
def on_paint(_event)
|
58
|
-
self.paint_buffered do |dc|
|
59
|
-
# ... do some drawing ...
|
60
|
-
end
|
61
|
-
end
|
62
|
-
```
|
@@ -1,89 +0,0 @@
|
|
1
|
-
<!--
|
2
|
-
# @markup markdown
|
3
|
-
# @title 12. Client/User data with wxRuby
|
4
|
-
-->
|
5
|
-
|
6
|
-
# 12. Client/User data with wxRuby
|
7
|
-
|
8
|
-
## Introduction
|
9
|
-
|
10
|
-
The wxWidgets library has widespread support for attaching arbitrary client (or user) data to GUI elements like
|
11
|
-
windows (all event handlers actually), window items, sizer items etc.
|
12
|
-
To cater to various C++ use cases in most instances this support covers both specific wxWidgets defined types (like
|
13
|
-
wxClientData and wxObject instances) and untyped data pointers (represented as `void *`) with subtle but essential
|
14
|
-
differences.
|
15
|
-
|
16
|
-
wxRuby implements a fully compatible version of this support.
|
17
|
-
|
18
|
-
## Everything is an Object
|
19
|
-
|
20
|
-
As Ruby does not do untyped data (everything is an Object), and having two different options is confusing anyway,
|
21
|
-
wxRuby provides only a single option and more or less unifies the interface across the entire library.
|
22
|
-
In Ruby anywhere the original wxWidgets library supports some type of client (or user) data attachment wxRuby will
|
23
|
-
support the attachment of any arbitrary Ruby `Object` by either the method `#set_client_object` (where C++ supports
|
24
|
-
`SetClientData` and `SetClientObject`) or `#set_user_data` (where C++ supports `SetUserData`). Data retrieval
|
25
|
-
is supported by complementary `#get_client_object` or `#get_user_data` methods in all cases.
|
26
|
-
Wherever C++ supports `SetClientObject` wxRuby also provides the method aliases `#set_client_data` and `#get_client_data`.
|
27
|
-
|
28
|
-
Another difference with C++ is that for typed client data in wxWidgets developers could leverage object destruction as
|
29
|
-
callback trigger (through the implementation of virtual destructors) to handle any required 'unlinking' logic. This
|
30
|
-
obviously does not apply to untyped data (one of the 'subtle' differences).
|
31
|
-
As Ruby does not provide any usable object destruction hooks this does not work there.
|
32
|
-
Ruby however has 'Duck-typing' which is what wxRuby uses to provide support for a unlinking callback 'hook' for attached
|
33
|
-
client data.
|
34
|
-
|
35
|
-
> Any attached Ruby Object implementing (responding to) the method `#client_data_unlinked` will have that method called after the
|
36
|
-
> attached object has been detached from the element it was attached to (either because of data replacement or element
|
37
|
-
> deletion).
|
38
|
-
|
39
|
-
Regard the following example.
|
40
|
-
|
41
|
-
```ruby
|
42
|
-
frame = Wx::Frame.new(nil, Wx::ID_ANY)
|
43
|
-
|
44
|
-
# attach a hash with user data
|
45
|
-
frame.set_client_data({ text: 'A string', float: 3.14 })
|
46
|
-
|
47
|
-
# ... do something with frame
|
48
|
-
|
49
|
-
# replace the user data
|
50
|
-
frame.set_client_data([1,2,3,4])
|
51
|
-
|
52
|
-
# ... do something else with frame
|
53
|
-
```
|
54
|
-
|
55
|
-
In this case standard Ruby object are attached. After attachment the object can be retrieved using a call to `get_client_data`
|
56
|
-
anywhere access to the frame instance is available.
|
57
|
-
|
58
|
-
Using a specially derived (or adapted) object a developer can handle specific logic after the object has been unlinked
|
59
|
-
like in this example:
|
60
|
-
|
61
|
-
```ruby
|
62
|
-
# define a user data class
|
63
|
-
class MyUserData
|
64
|
-
def initialize(payload)
|
65
|
-
@payload = payload
|
66
|
-
end
|
67
|
-
attr_reader :payload
|
68
|
-
|
69
|
-
def client_data_unlinked
|
70
|
-
# handle some logic
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# ...
|
75
|
-
|
76
|
-
# attach data to some window
|
77
|
-
win.set_client_data(MyUserData.new(some_payload_data))
|
78
|
-
|
79
|
-
# ...
|
80
|
-
|
81
|
-
# reset user data for some reason (will call MyUserData#client_data_unlinked after replacement)
|
82
|
-
win.set_client_data(nil)
|
83
|
-
```
|
84
|
-
|
85
|
-
# CommandEvent data
|
86
|
-
|
87
|
-
wxRuby also fully supports the propagation of attached client data to Wx::CommandEvent objects (see
|
88
|
-
{Wx::CommandEvent#get_client_object} and {Wx::CommandEvent#set_client_object}).
|
89
|
-
As mentioned above wxRuby provides the method aliases `#set_client_data` and `#get_client_data` here also.
|
@@ -1,139 +0,0 @@
|
|
1
|
-
<!--
|
2
|
-
# @markup markdown
|
3
|
-
# @title 13. Validators and data binding
|
4
|
-
-->
|
5
|
-
|
6
|
-
# 13. Validators and data binding
|
7
|
-
|
8
|
-
## Introduction
|
9
|
-
|
10
|
-
wxRuby fully supports validator classes offering input validation and/or data binding and/or event filtering.
|
11
|
-
|
12
|
-
## Validation
|
13
|
-
|
14
|
-
The base Wx::Validator class defines the method {Wx::Validator#validate} which is called when validation of the
|
15
|
-
value or content of the associated window is required.
|
16
|
-
|
17
|
-
The implementation of this method should (somehow) retrieve the value of the associated window and validate that
|
18
|
-
value, returning `true` if valid or `false` otherwise. The default implementation always returns `false`.
|
19
|
-
|
20
|
-
An example would be:
|
21
|
-
|
22
|
-
```ruby
|
23
|
-
# define custom validator
|
24
|
-
class MyTextValidator < Wx::Validator
|
25
|
-
|
26
|
-
def validate(_parent)
|
27
|
-
txt = get_window.value
|
28
|
-
# validate that the control text starts with a capital if not empty
|
29
|
-
txt.empty? || (?A..?Z).include?(txt[0])
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
# ...
|
35
|
-
|
36
|
-
# assign custom validator to text control
|
37
|
-
text = Wx::TextCtrl.new(parent, MY_TEXT_ID)
|
38
|
-
text.set_validator(MyTextValidator.new)
|
39
|
-
```
|
40
|
-
|
41
|
-
The derived, specialized, validator classes {Wx::TextValidator}, {Wx::IntegerValidator}, {Wx::IntegerValidator} and
|
42
|
-
{Wx::FloatValidator} all have implementations that can be configured through specific options and do not
|
43
|
-
normally require an override to be defined.
|
44
|
-
|
45
|
-
Examples of using the standard validators would be:
|
46
|
-
|
47
|
-
```ruby
|
48
|
-
text = Wx::TextCtrl.new(parent, MY_TEXT_ID)
|
49
|
-
|
50
|
-
# accept only hexadecimal characters
|
51
|
-
text.set_validator(Wx::TextValidator.new(Wx::TextValidatorStyle::FILTER_XDIGITS))
|
52
|
-
|
53
|
-
# or only numbers between -20 and 20
|
54
|
-
text.set_validator(Wx::IntegerValidator.new(-20, 20))
|
55
|
-
```
|
56
|
-
|
57
|
-
## Event filtering
|
58
|
-
|
59
|
-
All validator classes are event handlers and can have event handling routines defined (see
|
60
|
-
[Event Handling](05_event-handling.md)).
|
61
|
-
When processing events the core implementation will allow any validator associated with a window to handle an event
|
62
|
-
before the associated window itself thereby allowing it to filter events (see {Wx::EvtHandler#process_event} for more
|
63
|
-
details).
|
64
|
-
|
65
|
-
The standard specialized validators use this functionality to filter entry of allowable characters (by handling
|
66
|
-
Wx::EVT_CHAR events).
|
67
|
-
|
68
|
-
## Data binding
|
69
|
-
|
70
|
-
Data binding concerns the transfer of a validator's associated window's value to or from a user definable storage (a
|
71
|
-
variable, memory cache entry, persistent storage ...).
|
72
|
-
|
73
|
-
To integrate with the core C++ implementation but allow for Ruby specific differences the scheme implemented for this
|
74
|
-
differs somewhat (in naming and functionality) from the original wxWidgets interface.
|
75
|
-
|
76
|
-
The responsibilities of the standard wxRuby interface for handling validator data binding is distributed over 2 base
|
77
|
-
methods and a mixin module.
|
78
|
-
|
79
|
-
- The protected {Wx::Validator#do_transfer_from_window} and {Wx::Validator#do_transfer_to_window} methods are
|
80
|
-
responsible for collecting and transferring data from/to the associated window (possibly applying conversions).<br>
|
81
|
-
<br>
|
82
|
-
These methods have default implementations in all of the derived validator classes and should not be overridden for
|
83
|
-
specializations of these as they will be ignored.<br>
|
84
|
-
Overriding these methods is necessary to implement data binding for any user defined specialization of the base
|
85
|
-
{Wx::Validator} class.<br>
|
86
|
-
<br>
|
87
|
-
- The methods the {Wx::Validator::Binding} mixin module provide the means to store data after collection from or retrieve data
|
88
|
-
before transfer to the associated window.<br>
|
89
|
-
<br>
|
90
|
-
The methods {Wx::Validator::Binding#on_transfer_from_window} and {Wx::Validator::Binding#on_transfer_to_window} provide
|
91
|
-
the means to specify user defined binding handlers for storing the data transferred from the associated window or retrieving the
|
92
|
-
data to transfer to the associated window. Like with event handling the handlers can be specified using a `String` or
|
93
|
-
`Symbol`, a `Proc` or a `Method`.<br>
|
94
|
-
<br>
|
95
|
-
The methods {Wx::Validator::Binding#do_on_transfer_from_window} and {Wx::Validator::Binding#do_on_transfer_to_window} by
|
96
|
-
default call the binding handlers if defined.
|
97
|
-
These methods can be overridden to create derived validator classes with dedicated data binding functionality like
|
98
|
-
with {Wx::GenericValidator}.
|
99
|
-
|
100
|
-
An example of a custom validator providing data binding would be:
|
101
|
-
|
102
|
-
```ruby
|
103
|
-
class MyTextValidator < Wx::Validator
|
104
|
-
|
105
|
-
def do_transfer_from_window
|
106
|
-
get_window.get_value
|
107
|
-
end
|
108
|
-
|
109
|
-
def do_transfer_to_window(val)
|
110
|
-
get_window.set_value(val)
|
111
|
-
true
|
112
|
-
end
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
# ...
|
117
|
-
|
118
|
-
# use custom validator
|
119
|
-
@data = nil # attribute to store data
|
120
|
-
text.set_validator(MyTextValidator.new)
|
121
|
-
text.get_validator.on_transfer_to_window { @data }
|
122
|
-
text.get_validator.on_transfer_from_window { |v| @data = v }
|
123
|
-
```
|
124
|
-
|
125
|
-
All derived, specialized, validators implement a dedicated value cache which can be accessed through the `#value` attribute
|
126
|
-
accessor. Through this accessor the data collected from the associated window can get retrieved or the data to be transferred
|
127
|
-
to the associated window set.
|
128
|
-
With these classes it is therefor not necessary to define binding handlers. Defining binding handlers can however still be
|
129
|
-
useful to implement a custom, persistent, storage solution.
|
130
|
-
|
131
|
-
### Wx::GenericValidator
|
132
|
-
|
133
|
-
The {Wx::GenericValidator} class provides an extendable standard implementation for data binding in combination with a
|
134
|
-
large collection of controls (see class documentation).
|
135
|
-
The implementation provides a standard accessor {Wx::GenericValidator#value} to get the data value collected
|
136
|
-
from the associated window or set the data to transfer to the associated window.
|
137
|
-
|
138
|
-
To add support for any control unsupported by the standard implementation the method {Wx::GenericValidator.define_handler}
|
139
|
-
is provided (see documentation for an example).
|
@@ -1,101 +0,0 @@
|
|
1
|
-
<!--
|
2
|
-
# @markup markdown
|
3
|
-
# @title 14. Configuration support
|
4
|
-
-->
|
5
|
-
|
6
|
-
# 14. Configuration support
|
7
|
-
|
8
|
-
## Introduction
|
9
|
-
|
10
|
-
wxRuby3 fully supports the wxWidgets config classes providing a Ruby-fied interface.
|
11
|
-
|
12
|
-
The config classes provide a way to store some application configuration information providing features
|
13
|
-
that make them very useful for storing all kinds of small to medium volumes of hierarchically-organized,
|
14
|
-
heterogeneous data.
|
15
|
-
In wxWidgets these were especially designed for storing application configuration information and intended to be
|
16
|
-
mostly limited to that. That meant the information to be stored was intended to be:
|
17
|
-
|
18
|
-
* Typed, i.e. strings, booleans or numbers for the moment. You cannot store binary data, for example.
|
19
|
-
* Small. For instance, it is not recommended to use the Windows registry (which is the default storage medium on
|
20
|
-
that platform) for amounts of data more than a couple of kilobytes.
|
21
|
-
* Not performance critical, neither from speed nor from a memory consumption point of view.
|
22
|
-
|
23
|
-
As you will see wxRuby3 extends the support in this area and provides means to forego a lot of these restrictions.
|
24
|
-
|
25
|
-
The config classes also are intended to abstract away a lot of platform differences. In this area wxRuby3 extends the
|
26
|
-
support also.
|
27
|
-
|
28
|
-
## Default configuration support
|
29
|
-
|
30
|
-
When the default, global, config instance is used (by using {Wx::ConfigBase.get} with default argument) this will be
|
31
|
-
a platform specific instance. On Windows platforms a Windows registry based implementation is used and on other
|
32
|
-
platforms a text format configuration file.
|
33
|
-
|
34
|
-
wxRuby3 provides a single wrapper class for these with {Wx::ConfigWx}. This is an abstract class that cannot be
|
35
|
-
instantiated in Ruby which provides a common, Ruby-fied interface supported by all config classes in wxRuby3.
|
36
|
-
|
37
|
-
While wxWidgets does a decent job of abstracting platform differences it is in no way perfect in this area. With the
|
38
|
-
text format configuration files for example the stored values loose all type information since everything is stored
|
39
|
-
as strings. This also differs from the registry based implementation where some type information is not lost but some
|
40
|
-
(like boolean types) is.
|
41
|
-
This is not a problem when accessing information for which the structure and types are exactly known as the config
|
42
|
-
classes offer type specific readers (as well as writers) which coerce values to their expected types but may offer
|
43
|
-
nasty surprises when more reflectively accessing data of which the exact typing and structure is not known.
|
44
|
-
|
45
|
-
In Ruby where we more or less expect to have common API-s that can return or accept any type of object needing to be
|
46
|
-
type specific is awkward. wxRuby3 works around this as much as possible for the {Wx::ConfigWx} wrapper class but also
|
47
|
-
provides an alternative config class integrated with the wxWidgets framework that does not suffer from these restrictions.
|
48
|
-
|
49
|
-
## Enhanced Ruby configuration support
|
50
|
-
|
51
|
-
Instead of the default, platform specific, config classes it is also possible to use a custom wxRuby3 extension providing
|
52
|
-
a config class which is implemented in pure Ruby and integrated in the wxWidgets configuration framework.
|
53
|
-
To use an instance of this class as the global config instance the {Wx::ConfigBase.create} should be called at application
|
54
|
-
initialization time with it's `:use_hash_config` keyword argument set to `true` (and possibly, to be sure, it's
|
55
|
-
`forced_create` argument set to `true` also). This would create an instance of {Wx::Config} and install that as the global config instance (if no other instance was
|
56
|
-
yet installed or, overruling that condition, if `forced_create` was set to `true`).<br>
|
57
|
-
Alternatively a {Wx::Config} (or derivative) instance could be explicitly instantiated in code and assigned as global
|
58
|
-
instance with {Wx::ConfigBase.set}.
|
59
|
-
|
60
|
-
As the keyword argument indicates {Wx::Config} is a Ruby `Hash` based config class implementation.
|
61
|
-
|
62
|
-
Value objects are stored Ruby-style as-is into it's internal hash table (maintaining full type information) and are also
|
63
|
-
retrieved as-is by default (to maintain compatibility with the {Wx::ConfigWx} wrapper type coercion options are provided).
|
64
|
-
Grouping is based of nested `Hash` instances.
|
65
|
-
|
66
|
-
Because of the `Hash` based implementation and lack of (the need for) type coercion the {Wx::Config} class does have **any**
|
67
|
-
restrictions of the type of data stored. The only possible type restrictions to enforce may come from usage contexts:
|
68
|
-
|
69
|
-
* In case of value entries shared with wxWidgets framework code (like for example entries save by the persistence
|
70
|
-
framework; see [here](15_persistence.md)) value types should be restricted to those supported by the wxWidget platform
|
71
|
-
specific classes and correspond to what the framework code expects.
|
72
|
-
* In case of the need to save/restore the configuration data to/from persistent storage which imposes type restrictions these
|
73
|
-
should be applied.
|
74
|
-
|
75
|
-
With {Wx::Config} it would be perfectly alright to store arrays or any kind of arbitrary object (only be aware that `Hash`
|
76
|
-
instances will always be expected to provide configuration structure by default) as long as these do not conflict with
|
77
|
-
expectations of framework code or storage mechanisms.
|
78
|
-
|
79
|
-
With the standard Ruby YAML and JSON serialization support this also provides improved platform independent configuration
|
80
|
-
persistence options with full type information maintainability.
|
81
|
-
|
82
|
-
## Differences between default and enhanced configuration support
|
83
|
-
|
84
|
-
The major difference is, as described above, the absence of type restrictions in the enhanced Ruby config class {Wx::Config}.
|
85
|
-
|
86
|
-
Another difference is that {Wx::Config} will not automatically create missing groups or entries on reading. This will only
|
87
|
-
happen when writing configuration values.
|
88
|
-
|
89
|
-
A last difference is that the default support is by default backed up by persistent storage (windows registry or file) and
|
90
|
-
the wxRuby enhanced support only provides in-memory storage (`Hash` instance) by default.<br>
|
91
|
-
Persisting configuration data from {Wx::Config} will require coding customized storage and retrieval operations (which is
|
92
|
-
trivial using standard YAML or JSON support).
|
93
|
-
|
94
|
-
## Differences between wxWidgets config interface and wxRuby
|
95
|
-
|
96
|
-
In wxRuby there is no option to provide a default value argument when reading values. The reasoning is that Ruby itself
|
97
|
-
provides more than enough options to elegantly provide for defaults with statement options like `var ||= default` or
|
98
|
-
`var = get('something') || default`.
|
99
|
-
|
100
|
-
As a consequence wxRuby also does not support recording defaults on read operations (and also does not provide the
|
101
|
-
corresponding option setter/getter in the interface).
|
@@ -1,148 +0,0 @@
|
|
1
|
-
<!--
|
2
|
-
# @markup markdown
|
3
|
-
# @title 15. Persistence support
|
4
|
-
-->
|
5
|
-
|
6
|
-
# 15. Persistence support
|
7
|
-
|
8
|
-
## Introduction
|
9
|
-
|
10
|
-
wxRuby3 fully supports the wxWidgets persistence framework.
|
11
|
-
|
12
|
-
This framework provides the means to persist window (and other object) states which can than be restored when
|
13
|
-
re-creating these objects.
|
14
|
-
|
15
|
-
The persistence framework depends on the configuration framework (see [here](14_config.md)).
|
16
|
-
|
17
|
-
The persistence framework includes the following components:
|
18
|
-
|
19
|
-
* {Wx::PersistenceManager} which all persistent objects register themselves with. This class handles actual saving
|
20
|
-
and restoring of persistent data.
|
21
|
-
* Persistent object adapters for persistent objects. These adapters provide a bridge between the associated class –
|
22
|
-
which has no special persistence support – and {Wx::PersistenceManager}. All Persistent object adapters need to derive
|
23
|
-
from {Wx::PersistentObject} (like {Wx::PersistentWindowBase} and it's derivatives).
|
24
|
-
* The {Wx.create_persistent_object} and {Wx.persistent_register_and_restore} methods (mainly convenience methods for
|
25
|
-
wxWidgets compatibility).
|
26
|
-
|
27
|
-
## Persistence manager
|
28
|
-
|
29
|
-
By default a global singleton manager instance is available through {Wx::PersistenceManager.get} which will be used
|
30
|
-
by all available persistent object adapters for saving/restoring state values.
|
31
|
-
|
32
|
-
An alternate (possibly customized) manager instance can be installed through {Wx::PersistenceManager.set}.
|
33
|
-
|
34
|
-
## Persistent object adapters
|
35
|
-
|
36
|
-
All persistent object adapters must be derived from {Wx::PersistentObject}. This class provides common methods for
|
37
|
-
saving and restoring state values connecting to the persistence manager for actual writing and reading.
|
38
|
-
|
39
|
-
All windows/objects to be persisted need to be registered with the persistence manager. Creating the correct persistent
|
40
|
-
object adapter instance for an object to persist is abstracted away in wxWidgets by using template methods allowing
|
41
|
-
to simply only provide the object to persist instead of having to explicitly instantiate an adapter instance and provide
|
42
|
-
both to the persistence manager (which is however still possible).
|
43
|
-
|
44
|
-
wxRuby3 replaces this convenience interface (incompatible with Ruby) by a Ruby-fied approach which relies on Rubies
|
45
|
-
trusted *duck typing*.<br>
|
46
|
-
In wxRuby3 any class supported by a specific persistent object adapter class should implement the method
|
47
|
-
`#create_persistent_object` which should return a unique adapter instance for the object instance to be persisted
|
48
|
-
like this:
|
49
|
-
|
50
|
-
```ruby
|
51
|
-
class MyPersistentObject < Wx::PersistentObject
|
52
|
-
|
53
|
-
# Save the object properties.
|
54
|
-
# The implementation of this method should use {Wx::PersistentObject#save_value}.
|
55
|
-
# @return [void]
|
56
|
-
def save
|
57
|
-
# ...
|
58
|
-
end
|
59
|
-
|
60
|
-
# Restore the object properties.
|
61
|
-
# The implementation of this method should use {Wx::PersistentObject#restore_value}.
|
62
|
-
# @return [Boolean]
|
63
|
-
def restore
|
64
|
-
# ...
|
65
|
-
end
|
66
|
-
|
67
|
-
# Returns the string uniquely identifying the objects supported by this adapter.
|
68
|
-
# This method has default implementations in any of the built-in derived adapter classes.
|
69
|
-
# @return [String]
|
70
|
-
def get_kind
|
71
|
-
'MyObject'
|
72
|
-
end
|
73
|
-
|
74
|
-
# Returns the string uniquely identifying the object we're associated with among all the other objects of the same type.
|
75
|
-
# This method has a default implementation in Wx::PersistentWindowBase returning the window name.
|
76
|
-
# @return [String]
|
77
|
-
def get_name
|
78
|
-
'object_1'
|
79
|
-
end
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
class MyObject
|
84
|
-
|
85
|
-
# ...
|
86
|
-
|
87
|
-
def create_persistent_object
|
88
|
-
MyPersistentObject.new(self)
|
89
|
-
end
|
90
|
-
|
91
|
-
# ...
|
92
|
-
|
93
|
-
end
|
94
|
-
```
|
95
|
-
|
96
|
-
## Persistent windows
|
97
|
-
|
98
|
-
A number of classes provide built-in support for persistence of a number of windows or controls:
|
99
|
-
|
100
|
-
* {Wx::PersistentTLW} supports top level windows (including {Wx::Frame} and {Wx::Dialog}).
|
101
|
-
* {Wx::PersistentBookCtrl} supports the book controls {Wx::Notebook}, {Wx::Listbook}, {Wx::Toolbook} and {Wx::Choicebook}.
|
102
|
-
* {Wx::PersistentTreeBookCtrl} supports {Wx::Treebook}
|
103
|
-
|
104
|
-
All persistent window adapters are derived from {Wx::PersistentWindowBase}. This class makes sure that any window
|
105
|
-
registered for persisting gets automatically saved when the window is destroyed. Intermittently explicit saving still
|
106
|
-
remains possible of course.
|
107
|
-
|
108
|
-
User defined persistent window adapters can be derived from this class or any of the built-in derivatives to support
|
109
|
-
otherwise unsupported or custom windows/controls like this:
|
110
|
-
|
111
|
-
```ruby
|
112
|
-
class PersistentButton < Wx::PersistentWindowBase
|
113
|
-
|
114
|
-
def get_kind
|
115
|
-
'Button'
|
116
|
-
end
|
117
|
-
|
118
|
-
def save
|
119
|
-
save_value('w', get.size.width)
|
120
|
-
save_value('h', get.size.height)
|
121
|
-
save_value('label', get.label)
|
122
|
-
save_value('my_custom_value', get.my_custom_value)
|
123
|
-
end
|
124
|
-
|
125
|
-
def restore
|
126
|
-
get.size = [Integer(restore_value('w')), Integer(restore_value('h'))]
|
127
|
-
get.label = restore_value('label')
|
128
|
-
get.my_custom_value = Float(restore_value('my_custom_value'))
|
129
|
-
true
|
130
|
-
end
|
131
|
-
|
132
|
-
end
|
133
|
-
|
134
|
-
class MyButton < Wx::Button
|
135
|
-
|
136
|
-
def initialize(parent=nil, name)
|
137
|
-
super(parent, label: '', name: name)
|
138
|
-
@my_custom_value = ''
|
139
|
-
end
|
140
|
-
|
141
|
-
attr_accessor :my_custom_value
|
142
|
-
|
143
|
-
def create_persistent_object
|
144
|
-
PersistentButton.new(self)
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
148
|
-
```
|
data/samples/sampler/back.xpm
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
/* XPM */
|
2
|
-
static const char *const back_xpm[] = {
|
3
|
-
"16 15 3 1",
|
4
|
-
" c None",
|
5
|
-
". c Black",
|
6
|
-
"X c Gray100",
|
7
|
-
" ",
|
8
|
-
" ",
|
9
|
-
" . ",
|
10
|
-
" .. ",
|
11
|
-
" .X. ",
|
12
|
-
" .XX........ ",
|
13
|
-
" .XXXXXXXXXX. ",
|
14
|
-
" .XXXXXXXXXXX. ",
|
15
|
-
" .XXXXXXXXXXX. ",
|
16
|
-
" .XXXXXXXXXX. ",
|
17
|
-
" .XX........ ",
|
18
|
-
" .X. ",
|
19
|
-
" .. ",
|
20
|
-
" . ",
|
21
|
-
" "};
|