initial commit

Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
2025-10-31 23:37:30 +01:00
commit 7228269764
9653 changed files with 4034514 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
/////////////////////////////////////////////////////////////////////////////
// Name: app.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_app wxApp Overview
@tableofcontents
A wxWidgets application does not have a @e main function; the equivalent, i.e.
the entry point where the execution of the program begins, is the
wxApp::OnInit() member function defined in a class derived from wxApp (this
class is typically specified using wxIMPLEMENT_APP() macro).
@e OnInit usually creates the main application window and returns @true.
If it returns @false, the application will exit immediately, without starting
to run.
Note that the program's command line arguments, represented by @e argc and
@e argv, are available from within wxApp member functions.
An application closes by destroying all windows. Because all frames must be
destroyed for the application to exit, it is advisable to use parent frames
wherever possible when creating new frames, so that deleting the top level
frame will automatically delete child frames. The alternative is to explicitly
delete child frames in the top-level frame's wxCloseEvent handler.
In emergencies the wxExit function can be called to kill the application
however normally the application shuts down automatically, see
@ref overview_app_shutdown.
An example of defining an application follows:
@code
class DerivedApp : public wxApp
{
public:
virtual bool OnInit() override;
};
wxIMPLEMENT_APP(DerivedApp);
bool DerivedApp::OnInit()
{
wxFrame *the_frame = new wxFrame(nullptr, ID_MYFRAME, argv[0]);
...
the_frame->Show(true);
return true;
}
@endcode
Note the use of wxIMPLEMENT_APP(), which defines the application entry
point (either @c main() or @c WinMain() function, depending on the platform)
and tells wxWidgets which application class should be used.
You can also use wxDECLARE_APP(appClass) in a header file to declare the wxGetApp
function which returns a reference to the application object. Otherwise you can
only use the global @c wxTheApp pointer which is of type @c wxApp*.
@section overview_app_shutdown Application Shutdown
The application normally shuts down when the last of its top level windows is
closed. This is normally the expected behaviour and means that it is enough to
call wxWindow::Close() in response to the "Exit" menu command if your program
has a single top level window. If this behaviour is not desirable
wxApp::SetExitOnFrameDelete can be called to change it.
Note that such logic doesn't apply for the windows shown before the program
enters the main loop: in other words, you can safely show a dialog from
wxApp::OnInit and not be afraid that your application terminates when this
dialog -- which is the last top level window for the moment -- is closed.
Another aspect of the application shutdown is wxApp::OnExit which is called
when the application exits but @e before wxWidgets cleans up its internal
structures. You should delete all wxWidgets object that you created by the time
OnExit finishes.
In particular, do @b not destroy them from application class' destructor! For
example, this code may crash:
@code
class MyApp : public wxApp
{
public:
wxCHMHelpController m_helpCtrl;
...
};
@endcode
The reason for that is that @c m_helpCtrl is a member object and is thus
destroyed from MyApp destructor. But MyApp object is deleted after wxWidgets
structures that wxCHMHelpController depends on were uninitialized! The solution
is to destroy HelpCtrl in @e OnExit:
@code
class MyApp : public wxApp
{
public:
wxCHMHelpController *m_helpCtrl;
...
};
bool MyApp::OnInit()
{
...
m_helpCtrl = new wxCHMHelpController;
...
}
int MyApp::OnExit()
{
delete m_helpCtrl;
return 0;
}
@endcode
*/

View File

@@ -0,0 +1,435 @@
/////////////////////////////////////////////////////////////////////////////
// Name: archive.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_archive Archive Formats
@tableofcontents
The archive classes handle archive formats such as zip.
Currently zip and tar support is bundled with wxWidgets and
when external liblzma library is available (see @ref page_build_liblzma),
XZ format using LZMA2 algorithm is supported as well.
For each archive type, there are the following classes (using zip here as an
example):
@li wxZipInputStream: Input stream
@li wxZipOutputStream: Output stream
@li wxZipEntry: Holds meta-data for an entry (e.g. filename, timestamp, etc.)
There are also abstract wxArchive classes that can be used to write code that
can handle any of the archive types, see @ref overview_archive_generic.
Also see wxFileSystem for a higher level interface that can handle archive
files in a generic way.
The classes are designed to handle archives on both seekable streams such as
disk files, or non-seekable streams such as pipes and sockets (see
@ref overview_archive_noseek).
@section overview_archive_create Creating an Archive
Call wxArchiveOutputStream::PutNextEntry() to create each new entry in the
archive, then write the entry's data. Another call to PutNextEntry() closes the
current entry and begins the next. For example:
@code
wxFFileOutputStream out("test.zip");
wxZipOutputStream zip(out);
wxTextOutputStream txt(zip);
wxString sep(wxFileName::GetPathSeparator());
zip.PutNextEntry("entry1.txt");
txt << "Some text for entry1.txt\n";
zip.PutNextEntry("subdir" + sep + "entry2.txt");
txt << "Some text for subdir/entry2.txt\n";
@endcode
The name of each entry can be a full path, which makes it possible to store
entries in subdirectories.
@section overview_archive_extract Extracting an Archive
wxArchiveInputStream::GetNextEntry() returns a pointer to entry object
containing the meta-data for the next entry in the archive (and gives away
ownership).
Reading from the input stream then returns the entry's data. Eof() becomes
@true after an attempt has been made to read past the end of the entry's data.
When there are no more entries, GetNextEntry() returns @NULL and sets Eof().
@code
std::unique_ptr<wxZipEntry> entry;
wxFFileInputStream in("test.zip");
wxZipInputStream zip(in);
while (entry.reset(zip.GetNextEntry()), entry.get() != nullptr)
{
// access meta-data
wxString name = entry->GetName();
// read 'zip' to access the entry's data
}
@endcode
@section overview_archive_modify Modifying an Archive
To modify an existing archive, write a new copy of the archive to a new file,
making any necessary changes along the way and transferring any unchanged
entries using wxArchiveOutputStream::CopyEntry().
For archive types which compress entry data, CopyEntry() is likely to be much
more efficient than transferring the data using Read() and Write() since it
will copy them without decompressing and recompressing them.
In general modifications are not possible without rewriting the archive, though
it may be possible in some limited cases. Even then, rewriting the archive is
usually a better choice since a failure can be handled without losing the whole
archive. wxTempFileOutputStream can be helpful to do this.
For example to delete all entries matching the pattern "*.txt":
@code
std::unique_ptr<wxFFileInputStream> in(new wxFFileInputStream("test.zip"));
wxTempFileOutputStream out("test.zip");
wxZipInputStream inzip(*in);
wxZipOutputStream outzip(out);
std::unique_ptr<wxZipEntry> entry;
// transfer any meta-data for the archive as a whole (the zip comment
// in the case of zip)
outzip.CopyArchiveMetaData(inzip);
// call CopyEntry for each entry except those matching the pattern
while (entry.reset(inzip.GetNextEntry()), entry.get() != nullptr)
if (!entry->GetName().Matches("*.txt"))
if (!outzip.CopyEntry(entry.release(), inzip))
break;
// close the input stream by releasing the pointer to it, do this
// before closing the output stream so that the file can be replaced
in.reset();
// you can check for success as follows
bool success = inzip.Eof() && outzip.Close() && out.Commit();
@endcode
@section overview_archive_byname Looking Up an Archive Entry by Name
Also see wxFileSystem for a higher level interface that is more convenient for
accessing archive entries by name.
To open just one entry in an archive, the most efficient way is to simply
search for it linearly by calling wxArchiveInputStream::GetNextEntry() until
the required entry is found. This works both for archives on seekable and
non-seekable streams.
The format of filenames in the archive is likely to be different from the local
filename format. For example zips and tars use unix style names, with forward
slashes as the path separator, and absolute paths are not allowed. So if on
Windows the file "C:\MYDIR\MYFILE.TXT" is stored, then when reading the entry
back wxArchiveEntry::GetName() will return "MYDIR\MYFILE.TXT". The conversion
into the internal format and back has lost some information.
So to avoid ambiguity when searching for an entry matching a local name, it is
better to convert the local name to the archive's internal format and search
for that:
@code
std::unique_ptr<wxZipEntry> entry;
// convert the local name we are looking for into the internal format
wxString name = wxZipEntry::GetInternalName(localName);
// open the zip
wxFFileInputStream in("test.zip");
wxZipInputStream zip(in);
// call GetNextEntry() until the required internal name is found
do
{
entry.reset(zip.GetNextEntry());
}
while (entry.get() != nullptr && entry->GetInternalName() != name);
if (entry.get() != nullptr)
{
// read the entry's data...
}
@endcode
To access several entries randomly, it is most efficient to transfer the entire
catalogue of entries to a container such as a std::map or a wxHashMap then
entries looked up by name can be opened using the
wxArchiveInputStream::OpenEntry() method.
@code
using ZipEntryPtr = std::unique_ptr<wxZipEntry>;
using ZipCatalog = std::map<wxString, ZipEntryPtr>;
ZipEntryPtr entry;
ZipCatalog cat;
// open the zip
wxFFileInputStream in("test.zip");
wxZipInputStream zip(in);
// load the zip catalog
while (entry.reset(zip.GetNextEntry()), entry.get() != nullptr)
cat[entry->GetInternalName()] = std::move(entry);
// open an entry by name
auto it = cat.find(wxZipEntry::GetInternalName(localName));
if (it != cat.end())
{
zip.OpenEntry(*it->second);
// ... now read entry's data
}
@endcode
To open more than one entry simultaneously you need more than one underlying
stream on the same archive:
@code
// opening another entry without closing the first requires another
// input stream for the same file
wxFFileInputStream in2("test.zip");
wxZipInputStream zip2(in2);
if ((it = cat.find(wxZipEntry::GetInternalName(local2))) != cat.end())
zip2.OpenEntry(*it->second);
@endcode
@section overview_archive_generic Generic Archive Programming
Also see wxFileSystem for a higher level interface that can handle archive
files in a generic way.
The specific archive classes, such as the wxZip classes, inherit from the
following abstract classes which can be used to write code that can handle any
of the archive types:
@li wxArchiveInputStream: Input stream
@li wxArchiveOutputStream: Output stream
@li wxArchiveEntry: Holds the meta-data for an entry (e.g. filename)
In order to able to write generic code it's necessary to be able to create
instances of the classes without knowing which archive type is being used.
To allow this there is a class factory for each archive type, derived from
wxArchiveClassFactory, that can create the other classes.
For example, given wxArchiveClassFactory* factory, streams and entries can be
created like this:
@code
// create streams without knowing their type
std::unique_ptr<wxArchiveInputStream> inarc(factory->NewStream(in));
std::unique_ptr<wxArchiveOutputStream> outarc(factory->NewStream(out));
// create an empty entry object
std::unique_ptr<wxArchiveEntry> entry(factory->NewEntry());
@endcode
For the factory itself, the static member wxArchiveClassFactory::Find() can be
used to find a class factory that can handle a given file extension or mime
type. For example, given @e filename:
@code
const wxArchiveClassFactory *factory;
factory = wxArchiveClassFactory::Find(filename, wxSTREAM_FILEEXT);
if (factory)
stream = factory->NewStream(new wxFFileInputStream(filename));
@endcode
@e Find() does not give away ownership of the returned pointer, so it does not
need to be deleted.
There are similar class factories for the filter streams that handle the
compression and decompression of a single stream, such as wxGzipInputStream.
These can be found using wxFilterClassFactory::Find().
For example, to list the contents of archive @e filename:
@code
std::unique_ptr<wxInputStream> in(new wxFFileInputStream(filename));
if (in->IsOk())
{
// look for a filter handler, e.g. for '.gz'
const wxFilterClassFactory *fcf;
fcf = wxFilterClassFactory::Find(filename, wxSTREAM_FILEEXT);
if (fcf)
{
in.reset(fcf->NewStream(in.release()));
// pop the extension, so if it was '.tar.gz' it is now just '.tar'
filename = fcf->PopExtension(filename);
}
// look for a archive handler, e.g. for '.zip' or '.tar'
const wxArchiveClassFactory *acf;
acf = wxArchiveClassFactory::Find(filename, wxSTREAM_FILEEXT);
if (acf)
{
std::unique_ptr<wxArchiveInputStream> arc(acf->NewStream(in.release()));
std::unique_ptr<wxArchiveEntry> entry;
// list the contents of the archive
while ((entry.reset(arc->GetNextEntry())), entry.get() != nullptr)
std::wcout << entry->GetName() << "\n";
}
else
{
wxLogError("can't handle '%s'", filename);
}
}
@endcode
@section overview_archive_noseek Archives on Non-Seekable Streams
In general, handling archives on non-seekable streams is done in the same way
as for seekable streams, with a few caveats.
The main limitation is that accessing entries randomly using
wxArchiveInputStream::OpenEntry() is not possible, the entries can only be
accessed sequentially in the order they are stored within the archive.
For each archive type, there will also be other limitations which will depend
on the order the entries' meta-data is stored within the archive. These are not
too difficult to deal with, and are outlined below.
@subsection overview_archive_noseek_entrysize PutNextEntry and the Entry Size
When writing archives, some archive formats store the entry size before the
entry's data (tar has this limitation, zip doesn't). In this case the entry's
size must be passed to wxArchiveOutputStream::PutNextEntry() or an error
occurs.
This is only an issue on non-seekable streams, since otherwise the archive
output stream can seek back and fix up the header once the size of the entry is
known.
For generic programming, one way to handle this is to supply the size whenever
it is known, and rely on the error message from the output stream when the
operation is not supported.
@subsection overview_archive_noseek_weak GetNextEntry and the Weak Reference Mechanism
Some archive formats do not store all an entry's meta-data before the entry's
data (zip is an example). In this case, when reading from a non-seekable
stream, wxArchiveInputStream::GetNextEntry() can only return a partially
populated wxArchiveEntry object - not all the fields are set.
The input stream then keeps a weak reference to the entry object and updates it
when more meta-data becomes available. A weak reference being one that does not
prevent you from deleting the wxArchiveEntry object - the input stream only
attempts to update it if it is still around.
The documentation for each archive entry type gives the details of what
meta-data becomes available and when. For generic programming, when the worst
case must be assumed, you can rely on all the fields of wxArchiveEntry being
fully populated when GetNextEntry() returns, with the following exceptions:
@li wxArchiveEntry::GetSize(): Guaranteed to be available after the entry has
been read to wxInputStream::Eof(), or wxArchiveInputStream::CloseEntry()
has been called.
@li wxArchiveEntry::IsReadOnly(): Guaranteed to be available after the end of
the archive has been reached, i.e. after GetNextEntry() returns @NULL and
Eof() is @true.
This mechanism allows wxArchiveOutputStream::CopyEntry() to always fully
preserve entries' meta-data. No matter what order order the meta-data occurs
within the archive, the input stream will always have read it before the output
stream must write it.
@subsection overview_archive_noseek_notifier wxArchiveNotifier
Notifier objects can be used to get a notification whenever an input stream
updates a wxArchiveEntry object's data via the weak reference mechanism.
Consider the following code which renames an entry in an archive. This is the
usual way to modify an entry's meta-data, simply set the required field before
writing it with wxArchiveOutputStream::CopyEntry():
@code
std::unique_ptr<wxArchiveInputStream> arc(factory->NewStream(in));
std::unique_ptr<wxArchiveOutputStream> outarc(factory->NewStream(out));
std::unique_ptr<wxArchiveEntry> entry;
outarc->CopyArchiveMetaData(*arc);
while (entry.reset(arc->GetNextEntry()), entry.get() != nullptr)
{
if (entry->GetName() == from)
entry->SetName(to);
if (!outarc->CopyEntry(entry.release(), *arc))
break;
}
bool success = arc->Eof() && outarc->Close();
@endcode
However, for non-seekable streams, this technique cannot be used for fields
such as wxArchiveEntry::IsReadOnly(), which are not necessarily set when
wxArchiveInputStream::GetNextEntry() returns.
In this case a wxArchiveNotifier can be used:
@code
class MyNotifier : public wxArchiveNotifier
{
public:
void OnEntryUpdated(wxArchiveEntry& entry) { entry.SetIsReadOnly(false); }
};
@endcode
The meta-data changes are done in your notifier's
wxArchiveNotifier::OnEntryUpdated() method, then wxArchiveEntry::SetNotifier()
is called before CopyEntry():
@code
std::unique_ptr<wxArchiveInputStream> arc(factory->NewStream(in));
std::unique_ptr<wxArchiveOutputStream> outarc(factory->NewStream(out));
std::unique_ptr<wxArchiveEntry> entry;
MyNotifier notifier;
outarc->CopyArchiveMetaData(*arc);
while (entry.reset(arc->GetNextEntry()), entry.get() != nullptr)
{
entry->SetNotifier(notifier);
if (!outarc->CopyEntry(entry.release(), *arc))
break;
}
bool success = arc->Eof() && outarc->Close();
@endcode
SetNotifier() calls OnEntryUpdated() immediately, then the input stream calls
it again whenever it sets more fields in the entry. Since OnEntryUpdated() will
be called at least once, this technique always works even when it is not
strictly necessary to use it. For example, changing the entry name can be done
this way too and it works on seekable streams as well as non-seekable.
*/

View File

@@ -0,0 +1,62 @@
/////////////////////////////////////////////////////////////////////////////
// Name: aui.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_aui wxAUI Overview
@tableofcontents
wxAUI stands for Advanced User Interface. It aims to give the user a cutting
edge interface with floatable windows, and a user-customizable layout. The
original wxAUI sources have kindly been made available under the wxWindows
licence by Kirix Corp. and they have since then been integrated into wxWidgets
and further improved.
@see @ref group_class_aui
@section overview_aui_frame Frame Management
Frame management provides the means to open, move and hide common controls that
are needed to interact with the document, and allow these configurations to be
saved into different perspectives and loaded at a later time.
@section overview_aui_toolbar Toolbars
Toolbars are a specialized subset of the frame management system and should
behave similarly to other docked components. However, they also require
additional functionality, such as "spring-loaded" rebar support, "chevron"
buttons and end-user customizability.
@section overview_aui_modeless Modeless Controls
Modeless controls expose a tool palette or set of options that float above the
application content while allowing it to be accessed. Usually accessed by the
toolbar, these controls disappear when an option is selected, but may also be
"torn off" the toolbar into a floating frame of their own.
@section overview_aui_lnf Look and Feel
Look and feel encompasses the way controls are drawn, both when shown
statically as well as when they are being moved. This aspect of user interface
design incorporates "special effects" such as transparent window dragging as
well as frame animation.
wxAUI adheres to the following principles: Use native floating frames to obtain
a native look and feel for all platforms. Use existing wxWidgets code where
possible, such as sizer implementation for frame management. Use classes
included in @ref page_libs_wxcore and @ref page_libs_wxbase only.
*/

View File

@@ -0,0 +1,160 @@
/////////////////////////////////////////////////////////////////////////////
// Name: backwardcompatibility.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_backwardcompat Backwards Compatibility
@tableofcontents
The goal of wxWidgets is not only to provide a consistent programming
interface across many platforms, but also to provide an interface that is
reasonably stable over time.
@section overview_backwardcompat_versionnumbering The Version Numbering Scheme
wxWidgets version numbers can have up to four components, with trailing zeros
sometimes omitted:
@verbatim
major.minor.release.sub-release
@endverbatim
A stable release of wxWidgets will have an even number for @e minor, e.g.
3.2.0. Stable, in this context, means that the API is not changing. In truth,
some changes are permitted, but only those that are backward compatible. For
example, you can expect later 3.2.x releases, such as 3.2.1 and 3.2.2 to be
backward compatible with their predecessor.
When it becomes necessary to make changes which are not wholly backward
compatible, the stable branch is forked, creating a new development branch of
wxWidgets. This development branch will have an odd number for @e minor, for
example 3.3.x. Releases from this branch are known as development snapshots.
The stable branch and the development branch will then be developed in parallel
for some time. When it is no longer useful to continue developing the stable
branch, the development branch is renamed and becomes a new stable branch, for
example: 3.4.0. And the process begins again. This is how the tension between
keeping the interface stable, and allowing the library to evolve is managed.
You can expect the versions with the same major and even minor version number
to be compatible, but between minor versions there will be incompatibilities.
Compatibility is not broken gratuitously however, so many applications will
require no changes or only small changes to work with the new version.
@section overview_backwardcompat_sourcecompat Source Level Compatibility
Later releases from a stable branch are backward compatible with earlier
releases from the same branch at the source level. This means that, for
example, if you develop your application using wxWidgets 3.2.0 then it should
also compile fine with all later 3.2.x versions.
The converse is also true providing you avoid any new features not present in
the earlier version. For example if you develop using 3.3.1 your program will
compile fine with wxWidgets 3.2.0 providing you don't use any 3.3.1 specific
features.
For some platforms binary compatibility is also supported, see
@ref overview_backwardcompat_libbincompat below.
Between minor versions, for example between 2.8.x, 3.0.x and 3.2.x, there will
be some incompatibilities. Wherever possible the old way of doing something is
kept alongside the new for a time wrapped inside:
@code
#if WXWIN_COMPATIBILITY_3_0
// deprecated feature
...
#endif
@endcode
By default the @c WXWIN_COMPATIBILITY_X_X macro is set to 1 for the previous
stable branch, for example in 3.2.x, @c WXWIN_COMPATIBILITY_3_0 = 1. For the
next earlier stable branch the default is 0, so @c WXWIN_COMPATIBILITY_2_8 = 0
for 3.2.x. Earlier than that, obsolete features are removed.
These macros can be changed in @c setup.h. Or on UNIX-like systems you can set
them using the @c \--disable-compat30 and @c \--enable-compat28 options to
configure. Their values can also be changed with CMake.
They can be useful in two ways:
@li Changing @c WXWIN_COMPATIBILITY_3_0 to 0 can be useful to find uses of
deprecated features in your program that should eventually be removed.
@li Changing @c WXWIN_COMPATIBILITY_2_8 to 1 can be useful to compile a program
developed using 2.8.x that no longer compiles with 3.2.x.
A program requiring one of these macros to be 1 will become incompatible with
some future version of wxWidgets, and you should consider updating it.
@section overview_backwardcompat_libbincompat Library Binary Compatibility
For some platforms, releases from a stable branch are not only source level
compatible but can also be binary compatible.
Binary compatibility makes it possible to get the maximum benefit from using
shared libraries, also known as dynamic link libraries (DLLs) on Windows or
dynamic shared libraries on macOS.
For example, suppose several applications are installed on a system requiring
wxWidgets 3.2.0, 3.2.1 and 3.2.2. Since 3.2.2 is backward compatible with the
earlier versions, it should be enough to install just wxWidgets 3.2.2 shared
libraries, and all the applications should be able to use them. If binary
compatibility is not supported, then all the required versions 3.2.0, 3.2.1 and
3.2.2 must be installed side by side.
Achieving this, without the user being required to have the source code and
recompile everything, places many extra constraints on the changes that can be
made within the stable branch. So it is not supported for all platforms, and
not for all versions of wxWidgets. To date it has mainly been supported by
wxGTK for UNIX-like platforms.
Another practical consideration is that for binary compatibility to work, all
the applications and libraries must have been compiled with compilers that are
capable of producing compatible code; that is, they must use the same ABI
(Application Binary Interface). Unfortunately most different C++ compilers do
not produce code compatible with each other, and often even different versions
of the same compiler are not compatible.
@section overview_backwardcompat_appbincompat Application Binary Compatibility
The most important aspect of binary compatibility is that applications compiled
with one version of wxWidgets, e.g. 3.2.1, continue to work with shared
libraries of a later binary compatible version, for example 3.2.2. The converse
can also be useful however. That is, it can be useful for a developer using a
later version, e.g. 3.2.2 to be able to create binary application packages that
will work with all binary compatible versions of the shared library starting
with, for example 3.2.0.
To do this the developer must, of course, avoid any features not available in
the earlier versions. However this is not necessarily enough; in some cases an
application compiled with a later version may depend on it even though the same
code would compile fine against an earlier version.
To help with this, a preprocessor symbol @c wxABI_VERSION can be defined during
the compilation of the application (this would usually be done in the
application's makefile or project settings). It should be set to the lowest
version that is being targeted, as a number with two decimal digits for each
component, for example @c wxABI_VERSION=30200 for 3.2.0.
Setting @c wxABI_VERSION should prevent the application from implicitly
depending on a later version of wxWidgets, and also disables any new features
in the API, giving a compile time check that the source is compatible with the
versions of wxWidgets being targeted.
Uses of @c wxABI_VERSION are stripped out of the wxWidgets sources when each
new development branch is created. Therefore it is only useful to help achieve
compatibility with earlier versions with the same major and even minor version
numbers. It won't, for example, help you write code compatible with 3.0.x using
wxWidgets 3.2.x.
*/

View File

@@ -0,0 +1,195 @@
/////////////////////////////////////////////////////////////////////////////
// Name: bitmap.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_bitmap Bitmaps and Icons
@tableofcontents
The wxBitmap class encapsulates the concept of a platform-dependent bitmap,
either monochrome or colour. Platform-specific methods for creating a wxBitmap
object from an existing file are catered for, and this is an occasion where
conditional compilation will sometimes be required.
A bitmap created dynamically or loaded from a file can be selected into a
memory device context (instance of wxMemoryDC). This enables the bitmap to be
copied to a window or memory device context using wxDC::Blit(), or to be used
as a drawing surface.
See wxMemoryDC for an example of drawing onto a bitmap.
@section overview_bitmap_embedding Including Bitmaps in Your Program
It is common to need to embed some small bitmaps to be used for bitmaps or
icons in the program itself, instead of loading them from external files as
would be done for larger images. wxWidgets provides a few helper macros hiding
the differences between the platforms for doing this: wxBITMAP_PNG(), which
loads images from embedded PNG files and resources, or wxICON() and wxBITMAP()
which load images from a Windows resource of the corresponding type or from
XPM file included in the program.
wxBITMAP_PNG() is generally better because PNG images support full alpha
channel, unlike the XPM ones, but requires converting PNG files to a C array
before including it into your program, see its documentation. If you do not
need alpha channel support, XPM images, which can be directly included into the
program are simpler to use as you only need to do the following:
@code
#include "sample.xpm"
MyFrame::MyFrame()
{
wxIcon icon(wxICON(sample));
}
@endcode
which is equivalent to
@code
#include "sample.xpm"
MyFrame::MyFrame()
{
#if defined(__WXGTK__)
wxIcon icon(sample_xpm);
#endif
// ... similar checks for other platforms ...
#if defined(__WXMSW__)
wxIcon icon("sample"); // loaded from Windows resources (.rc file)
#endif
}
@endcode
but is, of course, much simpler and more clear. There is also a corresponding
wxBITMAP() macro which works in the same way but
creates a wxBitmap rather than wxIcon.
Note that including XPM files under Windows is harmless, but not really
necessary, as they are not used there and can be avoided by testing for
`wxHAS_IMAGES_IN_RESOURCES` symbol, i.e. you would typically do
@code
#ifndef wxHAS_IMAGES_IN_RESOURCES
#include "bitmaps/north.xpm"
#include "bitmaps/south.xpm"
#include "bitmaps/east.xpm"
#include "bitmaps/west.xpm"
#endif
MyFrame::MyFrame()
{
wxBitmap bmpN = wxBITMAP(north);
...
}
@endcode
Finally note that you may also want to use XPMs under all platforms, including
Windows, for simplicity, and to avoid having to deal with Windows resource
files (however you still need to define the application icon there). In this
case you should _not_ use wxICON() and wxBITMAP() macros as they expect to find
the images in Windows resources when building Windows programs.
@see @ref group_class_gdi
@section overview_bitmap_supportedformats Supported Bitmap File Formats
The following lists the formats handled on different platforms. Note that
missing or partially-implemented formats are automatically supplemented by
using wxImage to load the data, and then converting it to wxBitmap form. Note
that using wxImage is the preferred way to load images in wxWidgets, with the
exception of resources (XPM-files or native Windows resources).
Writing an image format handler for wxImage is also far easier than writing one
for wxBitmap, because wxImage has exactly one format on all platforms whereas
wxBitmap can store pixel data very differently, depending on colour depths and
platform.
@subsection overview_bitmap_supportedformats_bmp wxBitmap
Under Windows, wxBitmap may load the following formats:
@li Windows bitmap resource (wxBITMAP_TYPE_BMP_RESOURCE)
@li Windows bitmap file (wxBITMAP_TYPE_BMP)
@li XPM data and file (wxBITMAP_TYPE_XPM)
@li All formats that are supported by the wxImage class.
Under wxGTK, wxBitmap may load the following formats:
@li XPM data and file (wxBITMAP_TYPE_XPM)
@li All formats that are supported by the wxImage class.
Under wxX11, wxBitmap may load the following formats:
@li XBM data and file (wxBITMAP_TYPE_XBM)
@li XPM data and file (wxBITMAP_TYPE_XPM)
@li All formats that are supported by the wxImage class.
@subsection overview_bitmap_supportedformats_icon wxIcon
Under Windows, wxIcon may load the following formats:
@li Windows icon resource (wxBITMAP_TYPE_ICO_RESOURCE)
@li Windows icon file (wxBITMAP_TYPE_ICO)
@li XPM data and file (wxBITMAP_TYPE_XPM).
Under wxGTK, wxIcon may load the following formats:
@li XPM data and file (wxBITMAP_TYPE_XPM)
@li All formats that are supported by the wxImage class.
Under wxX11, wxIcon may load the following formats:
@li XBM data and file (wxBITMAP_TYPE_XBM)
@li XPM data and file (wxBITMAP_TYPE_XPM)
@li All formats that are supported by the wxImage class.
@subsection overview_bitmap_supportedformats_cursor wxCursor
Under Windows, wxCursor may load the following formats:
@li Windows cursor resource (wxBITMAP_TYPE_CUR_RESOURCE)
@li Windows cursor file (wxBITMAP_TYPE_CUR)
@li Windows icon file (wxBITMAP_TYPE_ICO)
@li Windows bitmap file (wxBITMAP_TYPE_BMP).
Under wxGTK, wxCursor may load the following formats (in addition to stock
cursors):
@li None (stock cursors only).
Under wxX11, wxCursor may load the following formats:
@li XBM data and file (wxBITMAP_TYPE_XBM).
@section overview_bitmap_handlers Bitmap Format Handlers
To provide extensibility, the functionality for loading and saving bitmap
formats is not implemented in the wxBitmap class, but in a number of handler
classes, derived from wxBitmapHandler. There is a static list of handlers which
wxBitmap examines when a file load/save operation is requested.
Some handlers are provided as standard, but if you have special requirements,
you may wish to initialise the wxBitmap class with some extra handlers which
you write yourself or receive from a third party.
To add a handler object to wxBitmap, your application needs to include the
header which implements it, and then call the static function
wxBitmap::AddHandler().
@note Bitmap handlers are not implemented on all platforms, and new ones rarely
need to be implemented since wxImage can be used for loading most formats, as
noted earlier.
*/

View File

@@ -0,0 +1,67 @@
/////////////////////////////////////////////////////////////////////////////
// Name: bookctrl.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_bookctrl wxBookCtrl Overview
@tableofcontents
A book control is a convenient way of displaying multiple pages of information,
displayed one page at a time. wxWidgets has five variants of this control:
@li wxChoicebook: controlled by a wxChoice
@li wxListbook: controlled by a wxListCtrl
@li wxNotebook: uses a row of tabs
@li wxSimplebook: doesn't allow the user to change the page at all.
@li wxTreebook: controlled by a wxTreeCtrl
@li wxToolbook: controlled by a wxToolBar
See the @ref page_samples_notebook for an example of wxBookCtrl usage.
Notice that wxSimplebook is special in that it only allows the program to
change the selection, thus it's usually used in slightly different
circumstances than the other variants.
@see @ref group_class_bookctrl
@section overview_bookctrl_bestbookctrl Best Book
::wxBookCtrl is mapped to the class best suited for a given platform. Currently
it is the same as wxNotebook if it is compiled in (i.e. @c wxUSE_NOTEBOOK was
not explicitly set to 0), otherwise it is the same as wxChoicebook.
The mapping consists of:
@beginTable
@row2col{ ::wxBookCtrl, wxChoicebook or wxNotebook }
@row2col{ @c wxEVT_BOOKCTRL_PAGE_CHANGED,
@c wxEVT_CHOICEBOOK_PAGE_CHANGED or
@c wxEVT_NOTEBOOK_PAGE_CHANGED }
@row2col{ @c wxEVT_BOOKCTRL_PAGE_CHANGING,
@c wxEVT_CHOICEBOOK_PAGE_CHANGING or
@c wxEVT_NOTEBOOK_PAGE_CHANGING }
@row2col{ @c EVT_BOOKCTRL_PAGE_CHANGED(id\, fn),
@c EVT_CHOICEBOOK_PAGE_CHANGED(id, fn) or
@c EVT_NOTEBOOK_PAGE_CHANGED(id, fn) }
@row2col{ @c EVT_BOOKCTRL_PAGE_CHANGING(id\, fn),
@c EVT_CHOICEBOOK_PAGE_CHANGING(id, fn) or
@c EVT_NOTEBOOK_PAGE_CHANGING(id, fn) }
@endTable
For orientation of the book controller, use following flags in style:
@li @b wxBK_TOP: controller above pages
@li @b wxBK_BOTTOM: controller below pages
@li @b wxBK_LEFT: controller on the left
@li @b wxBK_RIGHT: controller on the right
@li @b wxBK_DEFAULT: native controller placement
*/

View File

@@ -0,0 +1,45 @@
/////////////////////////////////////////////////////////////////////////////
// Name: bufferclasses.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_bufferclasses Buffer Classes
@tableofcontents
wxWidgets uses two classes of classes for dealing with buffers in memory.
The first is one for dealing with character buffers, namely wxCharBuffer for
char pointer or multi-byte c strings and wxWCharBuffer for wchar_t pointer or
wide character c strings.
Secondly, wxWidgets uses, although only rarely currently, wxMemoryBuffer for
dealing with raw buffers in memory.
@section overview_bufferclasses_xcb wxXCharBuffer
@subsection overview_bufferclasses_xcb_general General Usage
As mentioned, wxCharBuffer and its wide character variant wxWCharBuffer deal
with c strings in memory. They have two constructors, one in which you pass
the c string you want them to have a copy of, and another where you specify the
size of the buffer in memory in characters you want.
wxCharBuffer and its variant only contain the c string as a member, so they can
be used safely to c functions with variable arguments such as printf. They also
contain standard assignment, character access operators and a copy constructor.
@subsection overview_bufferclasses_xcb_destruct Destruction
It should be noted that on destruction wxCharBuffer and its wide character
variant delete the c string that hold onto. If you want to get the pointer to
the buffer and don't want wxCharBuffer to delete it on destruction, use the
member function release to do so.
*/

View File

@@ -0,0 +1,194 @@
/////////////////////////////////////////////////////////////////////////////
// Name: changes_since28.h
// Purpose: topic overview
// Author: Vadim Zeitlin
// Created: 2008-05-08
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_changes_since28 Changes Since wxWidgets 2.8
This topic describes backwards-incompatible changes in wxWidgets 3.0 compared
to the last stable release and is very important to read if you are updating
from the 2.8 or an older version. And even if you hadn't used any previous
version of wxWidgets and are starting directly with 3.0, it can still be useful
to have at least a quick look at it just to know that some of the older
examples and tutorials may not be applicable any more to wxWidgets 3.0.
The incompatible changes can be grouped into the following categories:
@li @ref overview_changes_unicode
@li @ref overview_changes_other
<hr>
@section overview_changes_unicode Unicode-related Changes
If you used Unicode build of wxWidgets 2.8 or previous version, please read
@ref overview_unicode for the details about how the API changed in 3.0 as a lot
of the information which was correct before doesn't apply any longer.
For example, the notorious (due to the confusion they created) macros @c wxT()
and @c _T() are not needed at all any longer. Basically, you can remove them
from any code which used them. On the other hand, there is no particular harm
in leaving them either as the code will still compile and work correctly --
you only need to remove them if you think that your code looks tidier without
them. You also don't need to use @c wxChar any longer but can directly use the
standard @c wchar_t type even if, again, @c wxChar continues to work.
The most serious backwards-incompatible change is related to the change of
return type of wxString::c_str() method: it returns a special proxy object
instead of a simple @c char* or @c wchar_t* now. Because of this, you cannot
pass its result to any standard vararg functions such as @c printf() any more
as described in @ref overview_unicode_compilation_errors. All wxWidgets
functions, such as wxPrintf(), wxLogMessage() &c still work with it, but
passing it to @c printf() will now result in a crash. It is strongly advised to
recompile your code with a compiler warning about passing non-POD objects to
vararg functions, such as g++.
The change of the type of wxString::c_str() can also result in compilation
errors when passing its result to a function overloaded to take both narrow and
wide strings and in this case you must select the version which you really want
to use, e.g.:
@code
void OpenLogFile(const char *filename);
void OpenLogFile(const wchar_t *filename);
wxString s;
OpenLogFile(s); // ERROR: ambiguity
OpenLogFile(s.c_str()); // ERROR: ambiguity
OpenLogFile(s.wx_str()); // OK: function called depends on the build
OpenLogFile(s.mb_str()); // OK: always calls narrow string overload
OpenLogFile(s.wc_str()); // OK: always calls wide string overload
@endcode
A common example of such problem arises with @c std::fstream class constructor
in Microsoft Visual C++ standard library implementation. In addition to a
constructor from @c const @c char * which this class must have, it also
provides a constructor taking a wide character file name. Because of this, code
like the following
@code
#include <fstream>
void MyFunc(const wxString& filename)
{
std::ifstream ifs(filename.c_str());
...
}
@endcode
does not compile when using Microsoft Visual C++ and needs to be changed to use
mb_str() (which will not work for file names containing Unicode characters,
consider using wxWidgets classes and functions to work with such file names as
they are not supported by standard C++ library).
The other class of incompatible changes is due to modifying some virtual
methods to use @c wxString parameters instead of @c const @c wxChar* ones to
make them accept both narrow and wide strings. This is not a problem if you
simply call these functions but you need to change the signature of the derived
class versions if you override them as otherwise they wouldn't be called any
more. Again, the best way to ensure that this problem doesn't arise is to
rebuild your code using a compiler which warns about function signature
mismatch (you can use @c -Woverloaded-virtual g++ option).
Finally, a few structure fields, notable @c wxCmdLineEntryDesc::shortName,
@c longName and @c description fields have been changed to be of type @c const
@c char* instead of @c const @c wxChar* so you will need to remove @c wxT() or
@c _T() if you used it with their initializers.
@section overview_changes_other Miscellaneous Other Changes
- Default location of wxFileConfig files has changed under Windows, you will
need to update your code if you access these files directly.
- wxWindow::IsEnabled() now returns false if a window parent (and not
necessarily the window itself) is disabled, new function IsThisEnabled()
with the same behaviour as old IsEnabled() was added.
- Generating wxNavigationKeyEvent events doesn't work any more under wxGTK (and
other platforms in the future), use wxWindow::Navigate() or NavigateIn()
instead.
- Sizers distribute only the extra space between the stretchable items
according to their proportions and not all available space. We believe the
new behaviour corresponds better to user expectations but if you did rely
on the old behaviour you will have to update your code to set the minimal
sizes of the sizer items to be in the same proportion as the items
proportions to return to the old behaviour.
- wxWindow::Freeze/Thaw() are not virtual any more, if you overrode them in
your code you need to override DoFreeze/Thaw() instead now.
- wxCalendarCtrl has native implementation in wxGTK, but it has less features
than the generic one. The native implementation is used by default, but you
can still use wxGenericCalendarCtrl instead of wxCalendarCtrl in your code if
you need the extra features.
- wxDocument::FileHistoryLoad() and wxFileHistory::Load() now take const
reference to wxConfigBase argument and not just a reference, please update
your code if you overrode these functions and change the functions in the
derived classes to use const reference as well.
- Calling wxConfig::Write() with an enum value will fail to compile because
wxConfig now tries to convert all unknown types to wxString automatically
using wxToString() function.
The simplest solution is to cast the enum value to int, e.g.
@code
enum Colour { Red, Green, Blue };
wxConfig conf;
conf.Write("MyFavouriteColour", Red); // ERROR: no match
conf.Write("MyFavouriteColour", int(Red)); // OK
@endcode
Another possibility which exists now is to provide an overload of
wxToString() (and wxFromString()) for your own type, e.g.
@code
wxString wxToString(Colour col)
{
return col == Red ? "R" : col == Green ? "G" : "B";
}
bool wxFromString(const wxString& s, Colour* col)
{
if ( s.length() != 1 )
return false;
switch ( s[0].GetValue() )
{
case 'R': *col = Red; return true;
case 'G': *col = Green; return true;
case 'B': *col = Blue; return true;
}
return false;
}
@endcode
Of course, this will change the format of the wxConfig output which may be
undesirable.
- wxTE_AUTO_SCROLL style is deprecated as it's always on by default anyhow in
the ports which support it so you should simply remove any mentions of it
from your code.
- If you use wxScrolled<T>::SetTargetWindow() you must override
wxScrolled<T>::GetSizeAvailableForScrollTarget() method to compute the size
available for the scroll target as function of the main window size, please
see the documentation of this method for more details.
- Signature of wxDataViewCustomRenderer::StartDrag() virtual method changed.
You will need to change it in your derived renderer class too if you override
it.
- wxDataViewCustomRenderer::Activate() and
wxDataViewCustomRenderer::LeftClick() were replaced with the new
wxDataViewCustomRenderer::ActivateCell() method. You will need to change it
in your derived renderer class accordingly.
*/

View File

@@ -0,0 +1,215 @@
CMake Overview {#overview_cmake}
==============
[TOC]
CMake allows building wxWidgets on various platforms with your preferred build
system.
Most linux distributions contain CMake as a package on Windows and macOS you can
download an installer at the [CMake Page](https://cmake.org).
Using the CMake GUI {#cmake_gui}
===================
1. Start the CMake GUI
2. Specify the wxWidgets root as your source folder
3. Specify a path where the build files should be created. It's recommended to
use a path outside the wxWidgets root folder.
4. Press the *Configure* button and you will be asked which IDE or build system
you wish to use
5. *Optionally*: Customize any of the options
6. Press the *Generate* button
7. Open the wxWidgets project with your preferred IDE
Using the CMake Command Line {#cmake_cli}
============================
1. Create a folder where the build/project files should be created
2. Change into the created folder
3. Run `cmake -G "Unix Makefiles" path_to_wxWidgets_root`
4. After that you can run `cmake --build .` to start the build process or
directly use your chosen build system.
Run `cmake --help` to see a list of available generators on your platform.
These can than be specified using the -G command line option. On Windows it
is recommended to use Visual Studio and on macOS Xcode is recommended.
Various build options can be specified using -D see
[available options](#cmake_options).
Command Line Examples {#cmake_cli_samples}
---------------------
Building with tests using [Ninja](https://ninja-build.org/):
~~~{.sh}
cmake -G "Ninja" ~/Downloads/wxWidgets_3.1 -DwxBUILD_TESTS=ALL
cmake --build .
~~~
Building the minimal sample:
~~~{.sh}
cmake ~/Downloads/wxWidgets_3.1 -DwxBUILD_SAMPLES=SOME
cmake --build . --target minimal
~~~
Installing static libraries to some path:
~~~{.sh}
cmake ~/Downloads/wxWidgets_3.1 \
-DCMAKE_INSTALL_PREFIX=~/wx_install \
-DwxBUILD_SHARED=OFF
cmake --build . --target install
~~~
Build options {#cmake_options}
=======================
The following list of build options can either be configured in the CMake UI
or specified via the -D command line option when running the cmake command.
Option Name | Type | Default | Description
------------------------- | ----- | ------- | ----------------------------
wxBUILD_SHARED | BOOL | ON | Build shared or static libraries
wxBUILD_TESTS | STRING | OFF | CONSOLE_ONLY, ALL or OFF
wxBUILD_SAMPLES | STRING | OFF | SOME, ALL or OFF
wxBUILD_DEMOS | BOOL | OFF | Build demo applications
wxUSE_GUI | BOOL | ON | Build the UI libraries
wxBUILD_COMPATIBILITY | STRING | 3.2 | Enable API compatibility with 3.0, 3.2 or neither ("NONE")
wxBUILD_PRECOMP | BOOL | ON | Use precompiled headers
wxBUILD_MONOLITHIC | BOOL | OFF | Build a single library
Note that on macOS, the option `CMAKE_OSX_ARCHITECTURES` is used to specify which architecture(s) to build.
For example, the following will build a "universal binary 2" (i.e., ARM64 and Intel x86_64) library.
~~~{.sh}
cmake ~/Downloads/wxWidgets_3.1 \
-DCMAKE_INSTALL_PREFIX=~/wx_install \
-DwxBUILD_SHARED=OFF \
-D"CMAKE_OSX_ARCHITECTURES:STRING=arm64;x86_64"
cmake --build . --target install
~~~
A complete list of options and advanced options can be found when using the
CMake GUI.
Recommendations {#cmake_recommendations}
=======================
While CMake in wxWidgets aims to support most generators available
in CMake, the following generators are recommended:
* Windows: Visual Studio (any supported version)
* macOS: Xcode
* Linux: Ninja or Makefiles
CMake 3.10 or newer is recommended. The minimum tested version is 3.5.
Using CMake with your applications {#cmake_apps}
==================================
If you are using CMake with your own application, there are various ways to use
wxWidgets:
* Using an installed, binary or compiled version of wxWidgets
using `find_package()`
* wxWidgets as a sub directory.
* CMake's [ExternalProject module](https://cmake.org/cmake/help/latest/module/ExternalProject.html).
Using find_package {#cmake_find_package}
------------------
You can use `find_package(wxWidgets)` to use a compiled version of wxWidgets.
Have a look at the [CMake Documentation](https://cmake.org/cmake/help/latest/module/FindwxWidgets.html)
for detailed instructions. wxWidgets also provides an example CMake file in the minimal sample folder.
*WARNING*: Please note that CMake `findwxWidgets` module unfortunately doesn't
detect wxWidgets 3.2.0 in versions of CMake older than 3.24. You may copy the
latest version of `FindwxWidgets.cmake` from [CMake sources][1] to your system
to fix this or, if you build wxWidgets itself using CMake, use `CONFIG` mode of
`find_package()` which works even with older CMake versions.
[1]: https://gitlab.kitware.com/cmake/cmake/-/blob/master/Modules/FindwxWidgets.cmake
Your *CMakeLists.txt* would look like this:
~~~
...
find_package(wxWidgets REQUIRED COMPONENTS net core base)
if(wxWidgets_USE_FILE) # not defined in CONFIG mode
include(${wxWidgets_USE_FILE})
endif()
add_executable(myapp myapp.cpp)
target_link_libraries(myapp ${wxWidgets_LIBRARIES})
~~~
Using a sub directory {#cmake_subdir}
---------------------
You can use wxWidgets as a subdirectory in your application's build tree
(e.g., as a git submodule). This way the wxWidgets libraries will be part
of your application's build process.
Your *CMakeLists.txt* would look like this:
~~~
...
add_subdirectory(libs/wxWidgets)
add_executable(myapp myapp.cpp)
target_link_libraries(myapp wx::net wx::core wx::base)
~~~
Note that you can predefine the build options before using `add_subdirectory()`
by either defining them on command line with e.g. `-DwxBUILD_SHARED=OFF`, or by
adding
~~~~
set(wxBUILD_SHARED OFF)
~~~~
to your *CMakeLists.txt* if you want to always use static wxWidgets libraries.
Using an out-of-tree directory {#cmake_outerdir}
---------------------
Likewise, wxWidgets can also be outside of your project, but still be part
of your application's build process. To do this, you will need to provide a
build directory argument to `add_subdirectory()`.
This will tell CMake where to place wxWidget's build files.
For example, if wxWidgets is one folder up from your project:
~~~
...
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../wxWidgets"
"${CMAKE_CURRENT_SOURCE_DIR}/wxWidgets_lib")
add_executable(myapp myapp.cpp)
target_link_libraries(myapp wx::net wx::core wx::base)
~~~
This can be useful if you have multiple projects using wxWidgets.
This way, you can place wxWidgets side-by-side with your other projects and
have their CMake scripts all point to the same wxWidgets folder.
Cached CMake variables
----------------------
If building wxWidgets statically into your program, these values will
be available:
Name | Description
------------------ | ----------- |
wxVERSION | wxWidgets's version number
wxCOPYRIGHT | The copyright string
Using XRC
---------
To embed XRC resources into your application, you need to define a custom
command to generate a source file using `wxrc`. When using an installed version
of wxWidgets you can just use `wxrc` directly, but when using wxWidgets from a
subdirectory you need to ensure that it is built first and use the correct path
to it, e.g.:
~~~~{.cmake}
# One or more XRC files containing your resources.
set(xrc_files ${CMAKE_CURRENT_SOURCE_DIR}/resource.xrc)
# Generate this file somewhere under the build directory.
set(resource_cpp ${CMAKE_CURRENT_BINARY_DIR}/resource.cpp)
# Not needed with the installed version, just use "wxrc".
set(wxrc $<TARGET_FILE:wxrc>)
add_custom_command(
OUTPUT ${resource_cpp}
COMMAND ${wxrc} -c -o ${resource_cpp} ${xrc_files}
DEPENDS ${xrc_files}
DEPENDS wxrc # Not needed with the installed version.
COMMENT "Compiling XRC resources"
)
target_sources(myapp PRIVATE ${resource_cpp})
~~~~

View File

@@ -0,0 +1,257 @@
/////////////////////////////////////////////////////////////////////////////
// Name: commondialogs.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_cmndlg Common Dialogs
@tableofcontents
Common dialog classes and functions encapsulate commonly-needed dialog box
requirements. They are all 'modal', grabbing the flow of control until the user
dismisses the dialog, to make them easy to use within an application.
Some dialogs have both platform-dependent and platform-independent
implementations, so that if underlying windowing systems do not provide the
required functionality, the generic classes and functions can stand in. For
example, under MS Windows, wxColourDialog uses the standard colour selector.
There is also an equivalent called wxGenericColourDialog for other platforms,
and a macro defines wxColourDialog to be the same as wxGenericColourDialog on
non-MS Windows platforms. However, under MS Windows, the generic dialog can
also be used, for testing or other purposes.
@see @ref group_class_cmndlg
@section overview_cmndlg_colour wxColourDialog Overview
Classes: wxColourDialog, wxColourData
The wxColourDialog presents a colour selector to the user, and returns with
colour information.
@subsection overview_cmndlg_colour_msw The MS Windows Colour Selector
Under Windows, the native colour selector common dialog is used. This presents
a dialog box with three main regions: at the top left, a palette of 48
commonly-used colours is shown. Under this, there is a palette of 16
'custom colours' which can be set by the application if desired. Additionally,
the user may open up the dialog box to show a right-hand panel containing
controls to select a precise colour, and add it to the custom colour palette.
@subsection overview_cmndlg_colour_generic The Generic Colour Selector
Under non-MS Windows platforms, the colour selector is a simulation of most of
the features of the MS Windows selector. Two palettes of 48 standard and 16
custom colours are presented, with the right-hand area containing three or four sliders
for the user to select a colour from red, green, blue and opacity (optionally) components. This
colour may be added to the custom colour palette, and will replace either the
currently selected custom colour, or the first one in the palette if none is
selected. The RGB or ARGB colour sliders are not optional in the generic colour
selector. The generic colour selector is also available under MS Windows; use
the name wxGenericColourDialog.
@subsection overview_cmndlg_colour_example Example
In the samples/dialogs directory, there is an example of using the
wxColourDialog class. Here is an excerpt, which sets various parameters of a
wxColourData object, including a grey scale for the custom colours. If the user
did not cancel the dialog, the application retrieves the selected colour and
uses it to set the background of a window.
@code
wxColourData data;
data.SetChooseFull(true);
for (int i = 0; i < 16; i++)
{
wxColour colour(i*16, i*16, i*16);
data.SetCustomColour(i, colour);
}
wxColourDialog dialog(this, &data);
if (dialog.ShowModal() == wxID_OK)
{
wxColourData retData = dialog.GetColourData();
wxColour col = retData.GetColour();
wxBrush brush(col, wxBRUSHSTYLE_SOLID);
myWindow->SetBackground(brush);
myWindow->Clear();
myWindow->Refresh();
}
@endcode
@section overview_cmndlg_font wxFontDialog Overview
Classes: wxFontDialog, wxFontData
The wxFontDialog presents a font selector to the user, and returns with font
and colour information.
@subsection overview_cmndlg_font_msw The MS Windows Font Selector
Under Windows, the native font selector common dialog is used. This presents a
dialog box with controls for font name, point size, style, weight, underlining,
strikeout and text foreground colour. A sample of the font is shown on a white
area of the dialog box. Note that in the translation from full MS Windows fonts
to wxWidgets font conventions, strikeout is ignored and a font family (such as
Swiss or Modern) is deduced from the actual font name (such as Arial or
Courier).
@subsection overview_cmndlg_font_generic The Generic Font Selector
Under non-MS Windows platforms, the font selector is simpler. Controls for font
family, point size, style, weight, underlining and text foreground colour are
provided, and a sample is shown upon a white background. The generic font
selector is also available under MS Windows; use the name wxGenericFontDialog.
@subsection overview_cmndlg_font_example Example
In the samples/dialogs directory, there is an example of using the wxFontDialog
class. The application uses the returned font and colour for drawing text on a
canvas. Here is an excerpt:
@code
wxFontData data;
data.SetInitialFont(canvasFont);
data.SetColour(canvasTextColour);
wxFontDialog dialog(this, &data);
if (dialog.ShowModal() == wxID_OK)
{
wxFontData retData = dialog.GetFontData();
canvasFont = retData.GetChosenFont();
canvasTextColour = retData.GetColour();
myWindow->Refresh();
}
@endcode
@section overview_cmndlg_print wxPrintDialog Overview
Classes: wxPrintDialog, wxPrintData
This class represents the print and print setup common dialogs. You may obtain
a wxPrinterDC device context from a successfully dismissed print dialog.
The samples/printing example shows how to use it: see @ref overview_printing
for an excerpt from this example.
@section overview_cmndlg_file wxFileDialog Overview
Classes: wxFileDialog
Pops up a file selector box. On Windows and GTK 2.4+, this is the common file
selector dialog. In X, this is a file selector box with somewhat less
functionality. The path and filename are distinct elements of a full file
pathname.
If path is "", the current directory will be used. If filename is "", no
default filename will be supplied. The wildcard determines what files are
displayed in the file selector, and file extension supplies a type extension
for the required filename. Flags may be a combination of wxFD_OPEN, wxFD_SAVE,
wxFD_OVERWRITE_PROMPT, wxFD_HIDE_READONLY, wxFD_FILE_MUST_EXIST, wxFD_MULTIPLE,
wxFD_CHANGE_DIR or 0.
Both the X and Windows versions implement a wildcard filter. Typing a filename
containing wildcards (*, ?) in the filename text item, and clicking on Ok, will
result in only those files matching the pattern being displayed. In the X
version, supplying no default name will result in the wildcard filter being
inserted in the filename text item; the filter is ignored if a default name is
supplied.
The wildcard may be a specification for multiple types of file with a
description for each, such as:
@verbatim
"BMP files (*.bmp)|*.bmp|GIF files (*.gif)|*.gif"
@endverbatim
@section overview_cmndlg_dir wxDirDialog Overview
Classes: wxDirDialog
This dialog shows a directory selector dialog, allowing the user to select
one or multiple directories.
@section overview_cmndlg_textentry wxTextEntryDialog Overview
Classes: wxTextEntryDialog
This is a dialog with a text entry field. The value that the user entered is
obtained using wxTextEntryDialog::GetValue().
@section overview_cmndlg_password wxPasswordEntryDialog Overview
Classes: wxPasswordEntryDialog
This is a dialog with a password entry field. The value that the user entered
is obtained using wxTextEntryDialog::GetValue().
@section overview_cmndlg_numeric wxNumberEntryDialog Overview
Classes: wxNumberEntryDialog
This is a dialog with a numeric entry field. The value that the user entered
is obtained using wxNumberEntryDialog::GetValue().
@section overview_cmndlg_cred wxCredentialEntryDialog Overview
Classes: wxCredentialEntryDialog
This is a dialog with user and password entry fields. The values that the
user entered are obtained using wxCredentialEntryDialog::GetUser() and
wxCredentialEntryDialog::GetPassword().
@section overview_cmndlg_msg wxMessageDialog Overview
Classes: wxMessageDialog
This dialog shows a message, plus buttons that can be chosen from OK, Cancel,
Yes, and No. Under Windows, an optional icon can be shown, such as an
exclamation mark or question mark.
The return value of wxMessageDialog::ShowModal() indicates which button the
user pressed.
@section overview_cmndlg_singlechoice wxSingleChoiceDialog Overview
Classes: wxSingleChoiceDialog
This dialog shows a list of choices, plus OK and (optionally) Cancel. The user
can select one of them. The selection can be obtained from the dialog as an
index, a string or client data.
@section overview_cmndlg_multichoice wxMultiChoiceDialog Overview
Classes: wxMultiChoiceDialog
This dialog shows a list of choices, plus OK and (optionally) Cancel. The user
can select one or more of them.
*/

View File

@@ -0,0 +1,61 @@
/////////////////////////////////////////////////////////////////////////////
// Name: config.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_config wxConfig Overview
Classes: wxConfigBase
This overview briefly describes what the config classes are and what they are
for. All the details about how to use them may be found in the description of
the wxConfigBase class and the documentation of the file, registry and INI file
based implementations mentions all the features/limitations specific to each
one of these versions.
The config classes provide a way to store some application configuration
information. They were especially designed for this usage and, although may
probably be used for many other things as well, should be limited to it. It
means that this information should be:
@li Typed, i.e. strings or numbers for the moment. You cannot store binary
data, for example.
@li Small. For instance, it is not recommended to use the Windows registry for
amounts of data more than a couple of kilobytes.
@li Not performance critical, neither from speed nor from a memory consumption
point of view.
On the other hand, the features provided make them very useful for storing all
kinds of small to medium volumes of hierarchically-organized, heterogeneous
data. In short, this is a place where you can conveniently stuff all your data
(numbers and strings) organizing it in a tree where you use the filesystem-like
paths to specify the location of a piece of data. In particular, these classes
were designed to be as easy to use as possible.
From another point of view, they provide an interface which hides the
differences between the Windows registry and the standard Unix text format
configuration files. Other (future) implementations of wxConfigBase might also
understand GTK resource files or their analogues on the KDE side.
In any case, each implementation of wxConfigBase does its best to make the data
look the same way everywhere. Due to limitations of the underlying physical
storage, it may not implement 100% of the base class functionality.
There are groups of entries and the entries themselves. Each entry contains
either a string or a number (or a boolean value; support for other types of
data such as dates or timestamps is planned) and is identified by the full path
to it: something like @c /MyApp/UserPreferences/Colors/Foreground.
The previous elements in the path are the group names, and each name may
contain an arbitrary number of entries and subgroups.
The path components are @e always separated with a slash, even though some
implementations use the backslash internally. Further details (including how to
read/write these entries) may be found in the documentation for wxConfigBase.
*/

View File

@@ -0,0 +1,139 @@
/////////////////////////////////////////////////////////////////////////////
// Name: container.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_container Container Classes
@tableofcontents
For historical reasons, wxWidgets uses custom container classes internally.
This was unfortunately unavoidable during a long time when the standard library
wasn't widely available and can't be easily changed even now that it is for
compatibility reasons. However, starting from version 3.3.0 these custom
container classes are implemented in terms of the standard library classes by
default and so are mostly interoperable with them.
This means that even if some wxWidgets function is documented as taking or
returning a legacy container such as wxList<T> or wxArray<T>, you can work with
them as if they were just `std::list<T*>` or `std::vector<T>`. For example,
wxWidgets::GetChildren() is documented as returning a `wxWindowList`, which
inherits from `std::list<wxWindow*>` and so can be used as such, e.g.
@code
const auto& children = someFrame->GetChildren();
auto it = std::find(children.begin(), children.end(), someWindow);
if ( it != children.end() )
// ... do something with this window ...
@endcode
You may still need to create wxWidgets containers to pass them to some
wxWidgets function, e.g. wxDir::GetAllFiles() requires a wxArrayString to be
passed in. However in this case you may still the object as if it were just a
`std::vector<wxString>` and, other than that, there is no reason to use the
container classes provided by wxWidgets anywhere in the new code, they only
exist for backwards compatibility and standard library classes should be used
by the application.
@see @ref group_class_containers
@section overview_container_legacy Legacy Classes
This section contains a brief overview of the legacy container classes and is
mostly useful if you need to maintain an existing code base using them -- none
of this is really necessary to know if you follow the advice above and treat
all wxWidgets containers as if they were standard containers.
All these classes use macro-based machinery to define type-safe classes based
on the generic implementation. Generally speaking, this consists of using one
macro to declare a particular "instantiation" and then another one to actually
define it, e.g. WX_DECLARE_LIST() and WX_DEFINE_LIST() for the linked lists or
WX_DECLARE_OBJARRAY() and WX_DEFINE_OBJARRAY() for the arrays containing
objects. The array classes storing primitive types, such as `int`, don't need
to be declared and defined separately, and so only WX_DEFINE_ARRAY_INT()
exists, without the matching "DECLARE" macro.
The "DECLARE" macro declares a new container class containing the elements of
given type and can be used in a header file and don't require the full
declaration of the contained type. The "DEFINE" macros must be used in a place
where the @e full declaration of container element class is in scope (i.e. not
just forward declaration).
Finally, wxWidgets predefines several commonly used container classes. wxList
itself is defined for compatibility with very old versions of wxWidgets as a
list containing wxObjects and wxStringList as a list of C-style strings
(`char *`). There are also a few predefined array classes including wxArrayInt,
wxArrayLong, wxArrayPtrVoid and wxArrayString, similar to `std::vector`
instantiations for `int`, `long`, `void*` and `wxString` respectively.
@section overview_container_impls Different Implementations
Since wxWidgets 3.3.0, all legacy container classes are implemented in terms of
the standard library classes. These implementations are mostly, but not
completely, compatible with the implementation provided by wxWidgets itself
which was used by default in the previous versions.
If the existing code doesn't compile with the implementation based on the
standard containers, it's possible to rebuild the library to use the legacy
implementation of them by setting wxUSE_STD_CONTAINERS option to 0. This is
done by:
- Either manually editing `wx/msw/setup.h` file to change the option of this
value there for wxMSW.
- Or using `--disable-std_containers` option when calling configure when
building wxWidgets under Unix-like systems.
- Or using `-DwxUSE_STD_CONTAINERS=OFF` when using CMake build system.
However a better approach is to update the legacy code to work with the new
container classes implementation. In most cases this can be done in such a way
that they still continue to work with the legacy implementation as well, thus
allowing the application to compile with the default configurations of both
wxWidgets 3.3 and 3.2 and even earlier versions.
Here are some modifications that may need to be done in order to make the
existing compatible with the default build of wxWidgets 3.3:
- `wxList::compatibility_iterator` must be used instead of `wxList::Node*` when
iterating over the list contents. The `compatibility_iterator` class has the
same semantics as a `Node` pointer but it is an object and not a pointer, so
the old code doing
@code
for ( wxWindowList::Node *n = list.GetFirst(); n; n = n->GetNext() ) {
// ... do something with *n ...
}
@endcode
can be mechanically rewritten as
@code
for ( wxWindowList::compatibility_iterator it = list.GetFirst();
it;
it = it->GetNext() ) {
// ... do something with *it ...
}
@endcode
Of course, if compatibility with the previous wxWidgets versions is not
important, an even better and simpler way to rewrite it is
@code
for ( const auto& elem: list ) {
// ... do something with elem ...
}
@endcode
- wxSortedArrayString and wxArrayString are separate classes now and the
former doesn't derive from the latter. If you need to convert a sorted array
to a normal one, you must copy all the elements. Alternatively, you may
avoid the use of wxSortedArrayString by using a normal array and calling its
wxArrayString::Sort() method when needed.
- `WX_DEFINE_ARRAY_INT(bool)` cannot be used because of the differences in
`std::vector<bool>` specialization compared with the generic std::vector<>
class. Please either use `std::vector<bool>` directly or use wxArrayInt
instead.
*/

View File

@@ -0,0 +1,83 @@
/////////////////////////////////////////////////////////////////////////////
// Name: cpprttidisabled.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_cpp_rtti_disabled Caveats When Not Using C++ RTTI
@tableofcontents
@note C++ RTTI is usually enabled by default in most wxWidgets builds. If you
do not know if your build has C++ RTTI enabled or not, then it probably
is enabled, and you should not worry about anything mentioned in this
section.
While in general wxWidgets standard @ref overview_rtti is used throughout the
library, there are some places where it won't work. One of those places
is template classes.
When available, C++ RTTI is used to address this issue. If you have built the
library with C++ RTTI disabled, an internal RTTI system is substituted.
However, this system is not perfect and one proven scenario where it may break
is a shared library or DLL build. More specifically, a template class instance
created in one physical binary may not be recognized as its correct type when
used in another one.
@see @ref overview_rtti, wxEvtHandler::Bind(), wxAny
@section overview_cpp_rtti_disabled_bind Bind() Issues
wxWidgets 2.9.0 introduced a new @ref overview_events_bind system, using
wxEvtHandler::Bind<>() and Unbind<>(). This functionality uses templates
behind the scenes and therefore is vulnerable to breakage in shared library
builds, as described above.
Currently only Unbind<>() needs the type information, so you should be immune
to this problem simply if you only need to use Bind<>() and not Unbind<>().
Also, if you only bind and unbind same event handler inside same binary, you
should be fine.
@section overview_cpp_rtti_disabled_wxany wxAny Issues
wxAny is a dynamic type class which transparently uses templates to generate
data type handlers, and therefore is vulnerable to breakage in shared library
builds, as described above
You should be fine if you only create and use wxAny instances inside same
physical binary. However, if you do need to be able to use wxAny freely
across binary boundaries, (and for sake of code-safety, you probably do),
then specializations for wxAnyValueTypeImpl<> templates need to be defined in
one of your shared library (DLL) files. One specialization is required for
every data type you use with wxAny. Easiest way to do this is using macros
provided in wx/any.h. Note that you @b do @b not need to define
specializations for C built-in types, nor for wxString or wxDateTime, because
these are already provided in wxBase. However, you @b do need to define
specializations for all pointer types except char* and wchar_t*.
Let's define a specialization for imaginary type 'MyClass'. In your shared
library source code you will need to have this line:
@code
WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<MyClass>)
@endcode
In your header file you will need the following:
@code
wxDECLARE_ANY_TYPE(MyClass, WXIMPORT_OR_WXEXPORT)
@endcode
Where WXIMPORT_OR_WXEXPORT is WXEXPORT when being included from the shared
library that called the WX_IMPLEMENT_ANY_VALUE_TYPE() macro, and WXIMPORT
otherwise.
*/

View File

@@ -0,0 +1,137 @@
/////////////////////////////////////////////////////////////////////////////
// Name: customwidgets.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_customwidgets Creating a Custom Widget
@tableofcontents
Typically combining the existing @ref group_class_ctrl controls in wxDialogs
and wxFrames is sufficient to fulfill any GUI design. Using the wxWidgets
standard controls makes your GUI looks native on all ports and is obviously
easier and faster.
However there are situations where you need to show some particular kind of
data which is not suited to any existing control. In these cases rather than
hacking an existing control for something it has not been conceived for, it's
better to write a new widget.
@section overview_customwidgets_how Writing a Custom Widget
There are at least two very different ways to implement a new widget.
The first is to build it upon wxWidgets existing classes, thus deriving it from
wxControl or wxWindow. In this way you'll get a @b generic widget. This method
has the advantage that writing a single implementation works on all ports; the
disadvantage is that it the widget will look the same on all platforms, and
thus it may not integrate well with the native look and feel.
The second method is to build it directly upon the native toolkits of the
platforms you want to support (e.g. GTK+, Cocoa and GDI). In this way you'll
get a @b native widget. This method in fact has the advantage of a native look
and feel but requires different implementations and thus more work.
In both cases you'll want to better explore some hot topics like:
- @ref overview_windowsizing
- @ref overview_events_custom to implement your custom widget's events.
You will probably need also to gain some familiarity with the wxWidgets
sources, since you'll need to interface with some undocumented wxWidgets
internal mechanisms.
@subsection overview_customwidgets_how_generic Writing a Generic Widget
Generic widgets are typically derived from wxControl or wxWindow.
They are easy to write. The typical "template" is as follows:
@code
enum MySpecialWidgetStyles
{
SWS_LOOK_CRAZY = 1,
SWS_LOOK_SERIOUS = 2,
SWS_SHOW_BUTTON = 4,
SWS_DEFAULT_STYLE = (SWS_SHOW_BUTTON|SWS_LOOK_SERIOUS)
};
class MySpecialWidget : public wxControl
{
public:
MySpecialWidget() { Init(); }
MySpecialWidget(wxWindow *parent,
wxWindowID winid,
const wxString& label,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = SWS_DEFAULT_STYLE,
const wxValidator& val = wxDefaultValidator,
const wxString& name = "MySpecialWidget")
{
Init();
Create(parent, winid, label, pos, size, style, val, name);
}
bool Create(wxWindow *parent,
wxWindowID winid,
const wxString& label,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = SWS_DEFAULT_STYLE,
const wxValidator& val = wxDefaultValidator,
const wxString& name = wxCollapsiblePaneNameStr);
// accessors...
protected:
void Init() {
// init widget's internals...
}
virtual wxSize DoGetBestSize() const {
// we need to calculate and return the best size of the widget...
}
void OnPaint(wxPaintEvent&) {
// draw the widget on a wxDC...
}
private:
wxDECLARE_DYNAMIC_CLASS(MySpecialWidget);
wxDECLARE_EVENT_TABLE();
};
@endcode
@subsection overview_customwidgets_how_native Writing a Native Widget
Writing a native widget is typically more difficult as it requires you to know
the APIs of the platforms you want to support. See @ref page_port_nativedocs
for links to the documentation manuals of the various toolkits.
The organization used by wxWidgets consists in:
- declaring the common interface of the control in a generic header, using
the 'Base' postfix; e.g. MySpecialWidgetBase.
See for example the wxWidgets' @c "wx/button.h" file.
- declaring the real widget class inheriting from the Base version in
platform-specific headers; see for example the wxWidgets' @c "wx/gtk/button.h" file.
- separating the different implementations in different source files, putting
all common stuff in a separate source.
See for example the wxWidgets' @c "src/common/btncmn.cpp", @c "src/gtk/button.cpp"
and @c "src/msw/button.cpp" files.
*/

View File

@@ -0,0 +1,76 @@
/////////////////////////////////////////////////////////////////////////////
// Name: dataobject.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_dataobject wxDataObject Overview
@tableofcontents
This overview discusses data transfer through clipboard or drag and drop. In
wxWidgets, these two ways to transfer data (either between different
applications or inside one and the same) are very similar which allows to
implement both of them using almost the same code - or, in other words, if you
implement drag and drop support for your application, you get clipboard support
for free and vice versa.
At the heart of both clipboard and drag and drop operations lies the
wxDataObject class. The objects of this class (or, to be precise, classes
derived from it) represent the data which is being carried by the mouse during
drag and drop operation or copied to or pasted from the clipboard. wxDataObject
is a "smart" piece of data because it knows which formats it supports (see
GetFormatCount and GetAllFormats) and knows how to render itself in any of them
(see GetDataHere). It can also receive its value from the outside in a format
it supports if it implements the SetData method. Please see the documentation
of this class for more details.
Both clipboard and drag and drop operations have two sides: the source and
target, the data provider and the data receiver. These which may be in the same
application and even the same window when, for example, you drag some text from
one position to another in a word processor. Let us describe what each of them
should do.
@see @ref overview_dnd, @ref group_class_dnd, @ref page_samples_dnd
@section overview_dataobject_source The Data Provider (Source)
The data provider is responsible for creating a wxDataObject containing the
data to be transferred. Then it should either pass it to the clipboard using
wxClipboard::SetData function or to wxDropSource and call
wxDropSource::DoDragDrop function.
The only (but important) difference is that the object for the clipboard
transfer must always be created on the heap (i.e. using @c new) and it will be
freed by the clipboard when it is no longer needed (indeed, it is not known in
advance when, if ever, the data will be pasted from the clipboard). On the
other hand, the object for drag and drop operation must only exist while
wxDropSource::DoDragDrop executes and may be safely deleted afterwards and so
can be created either on heap or on stack (i.e. as a local variable).
Another small difference is that in the case of clipboard operation, the
application usually knows in advance whether it copies or cuts (i.e. copies and
deletes) data - in fact, this usually depends on which menu item the user
chose. But for drag and drop it can only know it after wxDropSource::DoDragDrop
returns (from its return value).
@section overview_dataobject_target The Data Receiver (Target)
To receive (paste in usual terminology) data from the clipboard, you should
create a wxDataObject derived class which supports the data formats you need
and pass it as argument to wxClipboard::GetData. If it returns @false,
no data in (any of) the supported format(s) is available. If it returns @true,
the data has been successfully transferred to wxDataObject.
For drag and drop case, the wxDropTarget::OnData virtual function will be
called when a data object is dropped, from which the data itself may be
requested by calling wxDropTarget::GetData method which fills the data object.
*/

View File

@@ -0,0 +1,229 @@
/////////////////////////////////////////////////////////////////////////////
// Name: datetime.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_datetime Date and Time
@tableofcontents
wxWidgets provides a set of powerful classes to work with dates and times. Some
of the supported features of wxDateTime class are:
@li Wide range: the range of supported dates goes from about 4714 B.C. to
some 480 million years in the future.
@li Precision: not using floating point calculations anywhere ensures that
the date calculations don't suffer from rounding errors.
@li Many features: not only all usual calculations with dates are supported,
but also more exotic week and year day calculations, work day testing,
standard astronomical functions, conversion to and from strings in either
strict or free format.
@li Efficiency: objects of wxDateTime are small (8 bytes) and working with
them is fast
There are 3 main classes declared in @c wx/datetime.h: except wxDateTime itself
which represents an absolute moment in time, there are also two classes -
wxTimeSpan and wxDateSpan - which represent the intervals of time.
There are also helper classes which are used together with wxDateTime:
wxDateTimeHolidayAuthority which is used to determine whether a given date is a
holiday or not and wxDateTimeWorkDays which is a derivation of this class for
which (only) Saturdays and Sundays are the holidays. See more about these
classes in the discussion of the holidays (see
@ref overview_datetime_holidays).
Finally, in other parts of this manual you may find mentions of wxDate and
wxTime classes. @ref overview_datetime_compat are obsolete and superseded by
wxDateTime.
@section overview_datetime_characteristics wxDateTime Characteristics
wxDateTime stores the time as a signed number of
milliseconds since the Epoch which is fixed, by convention, to Jan 1, 1970 -
however this is not visible to the class users (in particular, dates prior to
the Epoch are handled just as well (or as bad) as the dates after it). But it
does mean that the best resolution which can be achieved with this class is 1
millisecond.
The size of wxDateTime object is 8 bytes because it is represented as a 64 bit
integer. The resulting range of supported dates is thus approximatively 580
million years, but due to the current limitations in the Gregorian calendar
support, only dates from Nov 24, 4714BC are supported (this is subject to
change if there is sufficient interest in doing it).
Finally, the internal representation is time zone independent (always in GMT)
and the time zones only come into play when a date is broken into
year/month/day components. See more about timezones below
(see @ref overview_datetime_timezones).
Currently, the only supported calendar is Gregorian one (which is used even
for the dates prior to the historic introduction of this calendar which was
first done on Oct 15, 1582 but is, generally speaking, country, and even
region, dependent). Future versions will probably have Julian calendar support
as well and support for other calendars (Maya, Hebrew, Chinese...) is not
ruled out.
@section overview_datetime_timespandiff wxDateSpan and wxTimeSpan
While there is only one logical way to represent an absolute moment in the
time (and hence only one wxDateTime class), there are at least two methods to
describe a time interval.
First, there is the direct and self-explaining way implemented by
wxTimeSpan: it is just a difference in milliseconds
between two moments in time. Adding or subtracting such an interval to
wxDateTime is always well-defined and is a fast operation.
But in the daily life other, calendar-dependent time interval specifications are
used. For example, 'one month later' is commonly used. However, it is clear
that this is not the same as wxTimeSpan of 60*60*24*31 seconds because 'one
month later' Feb 15 is Mar 15 and not Mar 17 or Mar 16 (depending on whether
the year is leap or not).
This is why there is another class for representing such intervals called
wxDateSpan. It handles these sort of operations in the
most natural way possible, but note that manipulating with intervals of
this kind is not always well-defined. Consider, for example, Jan 31 + '1
month': this will give Feb 28 (or 29), i.e. the last day of February and not
the non-existent Feb 31. Of course, this is what is usually wanted, but you
still might be surprised to notice that now subtracting back the same
interval from Feb 28 will result in Jan 28 and @b not Jan 31 we started
with!
So, unless you plan to implement some kind of natural language parsing in the
program, you should probably use wxTimeSpan instead of wxDateSpan (which is
also more efficient). However, wxDateSpan may be very useful in situations
when you do need to understand what 'in a month' means (of course, it is
just @c wxDateTime::Now() + wxDateSpan::Month()).
@section overview_datetime_arithmetics Date Arithmetic
Many different operations may be performed with the dates, however not all of
them make sense. For example, multiplying a date by a number is an invalid
operation, even though multiplying either of the time span classes by a number
is perfectly valid.
Here is what can be done:
@li @b Addition: a wxTimeSpan or wxDateSpan can be added to wxDateTime
resulting in a new wxDateTime object and also 2 objects of the same span class
can be added together giving another object of the same class.
@li @b Subtraction: the same types of operations as above are
allowed and, additionally, a difference between two wxDateTime objects can be
taken and this will yield wxTimeSpan.
@li @b Multiplication: a wxTimeSpan or wxDateSpan object can be
multiplied by an integer number resulting in an object of the same type.
@li <b>Unary minus</b>: a wxTimeSpan or wxDateSpan object may finally be
negated giving an interval of the same magnitude but of opposite time
direction.
For all these operations there are corresponding global (overloaded) operators
and also member functions which are synonyms for them: Add(), Subtract() and
Multiply(). Unary minus as well as composite assignment operations (like +=)
are only implemented as members and Neg() is the synonym for unary minus.
@section overview_datetime_timezones Time Zone Considerations
Although the time is always stored internally in GMT, you will usually work in
the local time zone. Because of this, all wxDateTime constructors and setters
which take the broken down date assume that these values are for the local
time zone. Thus, @c wxDateTime(1, wxDateTime::Jan, 1970) will not
correspond to the wxDateTime Epoch unless you happen to live in the UK.
All methods returning the date components (year, month, day, hour, minute,
second...) will also return the correct values for the local time zone by
default, so, generally, doing the natural things will lead to natural and
correct results.
If you only want to do this, you may safely skip the rest of this section.
However, if you want to work with different time zones, you should read it to
the end.
In this (rare) case, you are still limited to the local time zone when
constructing wxDateTime objects, i.e. there is no way to construct a
wxDateTime corresponding to the given date in, say, Pacific Standard Time.
To do it, you will need to call wxDateTime::ToTimezone or wxDateTime::MakeTimezone
methods to adjust the date for the target time zone. There are also special
versions of these functions wxDateTime::ToUTC and wxDateTime::MakeUTC for
the most common case - when the date should be constructed in UTC.
You also can just retrieve the value for some time zone without converting the
object to it first. For this you may pass TimeZone argument to any of the
methods which are affected by the time zone (all methods getting date
components and the date formatting ones, for example). In particular, the
Format() family of methods accepts a TimeZone parameter and this allows to
simply print time in any time zone.
To see how to do it, the last issue to address is how to construct a TimeZone
object which must be passed to all these methods. First of all, you may construct
it manually by specifying the time zone offset in seconds from GMT, but
usually you will just use one of the @ref overview_datetime and
let the conversion constructor do the job.
I.e. you would just write
@code
wxDateTime dt(...whatever...);
wxPrintf("The time is %s in local time zone", dt.FormatTime());
wxPrintf("The time is %s in GMT", dt.FormatTime(wxDateTime::GMT));
@endcode
@section overview_datetime_dst Daylight Saving Time (DST)
DST (a.k.a. 'summer time') handling is always a delicate task which is better
left to the operating system which is supposed to be configured by the
administrator to behave correctly. Unfortunately, when doing calculations with
date outside of the range supported by the standard library, we are forced to
deal with these issues ourselves.
Several functions are provided to calculate the beginning and end of DST in
the given year and to determine whether it is in effect at the given moment or
not, but they should not be considered as absolutely correct because, first of
all, they only work more or less correctly for only a handful of countries
(any information about other ones appreciated!) and even for them the rules
may perfectly well change in the future.
The time zone handling methods (see @ref overview_datetime_timezones) use
these functions too, so they are subject to the same limitations.
@section overview_datetime_holidays Holidays
The wxDateTimeHolidayAuthority-derived classes help determine whether a
given date is a holiday and are used by all functions working with "work days".
In this context, a holiday is an event which results in a day off from work.
Multiple holiday authorities can be combined by passing them to
wxDateTimeHolidayAuthority::AddAuthority(), and a date can be verified as a holiday
by calling wxDateTimeHolidayAuthority::IsHoliday().
Holiday authorities are available for weekends (loaded by default) and
Catholic/Christian holy days of obligation.
Custom holiday authorities can also be created by deriving from wxDateTimeHolidayAuthority
and defining DoIsHoliday() and DoGetHolidaysInRange().
@section overview_datetime_compat Compatibility
The old classes for date/time manipulations ported from wxWidgets version 1.xx
are still included but are reimplemented in terms of wxDateTime. However, using
them is strongly discouraged because they have a few quirks/bugs and were not
'Y2K' compatible.
*/

View File

@@ -0,0 +1,68 @@
/////////////////////////////////////////////////////////////////////////////
// Name: dc.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_dc Device Contexts
A wxDC is a @e device context onto which graphics and text can be drawn.
The device context is intended to represent a number of output devices in a
generic way, with the same API being used throughout.
Objects of wxDC class itself can't be created, instead you should create
objects of the following classes:
@li wxPaintDC for painting on a window from within a paint event handler. This
is the most common device context to use.
@li wxMemoryDC for painting off-screen, i.e. to a bitmap.
@li wxPrinterDC for printing.
@li wxInfoDC for obtaining information about the device context without drawing
on it.
To draw on a window, you need to create a wxPaintDC object in the paint event
handler:
@code
void MyWindow::OnPaint(wxPaintEvent& event)
{
wxPaintDC dc(this);
dc.DrawText("Hello, world!", 20, 20);
}
@endcode
To obtain information about a device context associated with a window outside
of its paint event handler, you need to use wxInfoDC, e.g.
the window as argument, for example:
@code
void MyFrame::SomeFunction()
{
wxInfoDC dc(this);
// Create control with the width just big enough for the given string.
auto* text = new wxStaticText
(
this, wxID_ANY, "",
wxPoint(),
dc.GetTextExtent("String of max length"),
wxST_NO_AUTORESIZE
);
}
@endcode
When writing drawing code, it is recommended to extract it into a function
taking wxDC as an argument. This allows you to reuse the same code for drawing
and printing, by calling it with either wxPaintDC or wxPrinterDC.
Please note that other device context classes that could previously be used for
painting on screen cannot be used any more due to the architecture of the
modern graphics systems. In particular, wxClientDC, wxWindowDC and wxScreenDC
are not guaranteed to work any longer.
@see @ref group_class_dc
*/

View File

@@ -0,0 +1,112 @@
/////////////////////////////////////////////////////////////////////////////
// Name: debugging.h
// Purpose: topic overview
// Author: Vadim Zeitlin
// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_debugging Debugging
@tableofcontents
Various classes, functions and macros are provided in wxWidgets to help you
debug your application. Assertion macros allow you to insert various checks in
your application which can be compiled out or disabled in release builds but
are extremely useful while developing. Logging functions are also provided
which are useful for inserting traces into your application code as well as
debugging. Both assertions and debug logging are also used by wxWidgets itself
so you may encounter them even if you don't use either of these features
yourself.
@see wxLog, @ref group_funcmacro_log, @ref group_funcmacro_debug
@section overview_debugging_config Configuring Debug Support
Starting with wxWidgets 2.9.1 debugging features are always available by
default (and not only in a special "debug" build of the library) and you need
to predefine wxDEBUG_LEVEL symbol as 0 when building both the library and your
application to remove them completely from the generated object code. However
the debugging features are disabled by default when the application itself is
built with @c NDEBUG defined (i.e. in "release" or "production" mode) so there
is no need to do this, unless the resources of the system your application will
be running on are unusually constrained (notice that when asserts are disabled
their condition is not even evaluated so the only run-time cost is a single
condition check and the extra space taken by the asserts in the code).
This automatic deactivation of debugging code is done by wxIMPLEMENT_APP()
macro so if you don't use you may need to explicitly call
wxDISABLE_DEBUG_SUPPORT() yourself.
Also notice that it is possible to build your own application with a different
value of wxDEBUG_LEVEL than the one which was used for wxWidgets itself. E.g.
you may be using an official binary version of the library which will have been
compiled with default @code wxDEBUG_LEVEL == 1 @endcode but still predefine
wxDEBUG_LEVEL as 0 for your own code.
On the other hand, if you do want to keep the asserts even in production
builds, you will probably want to override the handling of assertion failures
as the default behaviour which pops up a message box notifying the user about
the problem is usually inappropriate. Use wxSetAssertHandler() to set up your
own custom function which should be called instead of the standard assertion
failure handler. Such function could log an appropriate message in the
application log file or maybe notify the user about the problem in some more
user-friendly way.
@section overview_debugging_dbgmacros Assertion Macros
wxASSERT(), wxFAIL(), wxCHECK() as well as their other variants (see @ref
group_funcmacro_debug) are similar to the standard assert() macro but are more
flexible and powerful. The first of them is equivalent to assert() itself, i.e.
it simply checks a condition and does nothing if it is true. The second one is
equivalent to checking an always false condition and is supposed to be used for
code paths which are supposed to be inaccessible (e.g. @c default branch of a
@c switch statement which should never be executed). Finally, the wxCHECK()
family of macros verifies the condition just as wxASSERT() does and performs
some action such returning from the function if it fails -- thus, it is useful
for checking the functions preconditions.
All of the above functions exist in @c _MSG variants which allow you to provide
a custom message which will be shown (or, more generally, passed to the assert
handler) if the assertion fails, in addition to the usual file and line number
information and the condition itself.
Example of using an assertion macro:
@code
void GetTheAnswer(int *p)
{
wxCHECK_RET( p, "pointer can't be null in GetTheAnswer()" );
*p = 42;
};
@endcode
If the condition is false, i.e. @c p is @NULL, the assertion handler is called
and, in any case (even when wxDEBUG_LEVEL is 0), the function returns without
dereferencing the null pointer on the next line thus avoiding a crash.
The default assertion handler behaviour depends on whether the application
using wxWidgets was compiled in release build (with @c NDEBUG defined) or debug
one (without) but may be changed in either case as explained above. If it
wasn't changed, then nothing will happen in the release build and a message box
showing the information about the assert as well as allowing to stop the
program, ignore future asserts or break into the debugger is shown. On the
platforms where wxStackWalker is supported the message box will also show the
stack trace at the moment when the assert failed often allowing you to diagnose
the problem without using the debugger at all. You can see an example of such
message box in the @ref page_samples_except.
@section overview_debugging_logging Logging Functions
You can use the wxLogDebug and wxLogTrace functions to output debugging
information in debug mode; it will do nothing for non-debugging code.
*/

View File

@@ -0,0 +1,137 @@
/////////////////////////////////////////////////////////////////////////////
// Name: dialog.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_dialog wxDialog Overview
@tableofcontents
Classes: wxDialog, wxDialogLayoutAdapter
A dialog box is similar to a panel, in that it is a window which can be used
for placing controls, with the following exceptions:
@li A surrounding frame is implicitly created.
@li Extra functionality is automatically given to the dialog box, such as
tabbing between items (currently Windows only).
@li If the dialog box is @e modal, the calling program is blocked until the
dialog box is dismissed.
For a set of dialog convenience functions, including file selection, see
@ref group_funcmacro_dialog.
See also wxTopLevelWindow and wxWindow for inherited member functions.
Validation of data in controls is covered in @ref overview_validator.
@section overview_dialog_autoscrolling Automatic Scrolled Dialogs
As an ever greater variety of mobile hardware comes to market, it becomes more
imperative for wxWidgets applications to adapt to these platforms without
putting too much burden on the programmer. One area where wxWidgets can help is
in adapting dialogs for the lower resolution screens that inevitably accompany
a smaller form factor. wxDialog therefore supplies a global
wxDialogLayoutAdapter class that implements automatic scrolling adaptation for
most sizer-based custom dialogs.
Many applications should therefore be able to adapt to small displays with
little or no work, as far as dialogs are concerned. By default this adaptation
is off. To switch scrolling adaptation on globally in your application, call
the static function wxDialog::EnableLayoutAdaptation passing @true. You can
also adjust adaptation on a per-dialog basis by calling
wxDialog::SetLayoutAdaptationMode with one of
@c wxDIALOG_ADAPTATION_MODE_DEFAULT (use the global setting),
@c wxDIALOG_ADAPTATION_MODE_ENABLED or @c wxDIALOG_ADAPTATION_MODE_DISABLED.
The last two modes override the global adaptation setting. With adaptation
enabled, if the display size is too small for the dialog, wxWidgets (or rather
the standard adapter class wxStandardDialogLayoutAdapter) will make part of the
dialog scrolling, leaving standard buttons in a non-scrolling part at the
bottom of the dialog. This is done as follows, in
wxDialogLayoutAdapter::DoLayoutAdaptation called from within wxDialog::Show or
wxDialog::ShowModal:
@li If wxDialog::GetContentWindow returns a window derived from wxBookCtrlBase,
the pages are made scrollable and no other adaptation is done.
@li wxWidgets looks for a wxStdDialogButtonSizer and uses it for the
non-scrolling part.
@li If that search failed, wxWidgets looks for a horizontal wxBoxSizer with one
or more standard buttons, with identifiers such as @c wxID_OK and
@c wxID_CANCEL.
@li If that search failed too, wxWidgets finds 'loose' standard buttons (in any
kind of sizer) and adds them to a wxStdDialogButtonSizer. If no standard
buttons were found, the whole dialog content will scroll.
@li All the children apart from standard buttons are reparented onto a new
::wxScrolledWindow object, using the old top-level sizer for the scrolled
window and creating a new top-level sizer to lay out the scrolled window
and standard button sizer.
@subsection overview_dialog_autoscrolling_custom Customising Scrolling Adaptation
In addition to switching adaptation on and off globally and per dialog, you can
choose how aggressively wxWidgets will search for standard buttons by setting
wxDialog::SetLayoutAdaptationLevel. By default, all the steps described above
will be performed but by setting the level to 1, for example, you can choose to
only look for wxStdDialogButtonSizer.
You can use wxDialog::AddMainButtonId to add identifiers for buttons that
should also be treated as standard buttons for the non-scrolling area.
You can derive your own class from wxDialogLayoutAdapter or
wxStandardDialogLayoutAdapter and call wxDialog::SetLayoutAdapter, deleting the
old object that this function returns. Override the functions
CanDoLayoutAdaptation and DoLayoutAdaptation to test for adaptation
applicability and perform the adaptation.
You can also override wxDialog::CanDoLayoutAdaptation and
wxDialog::DoLayoutAdaptation in a class derived from wxDialog.
@subsection overview_dialog_autoscrolling_fail Where Scrolling Adaptation May Fail
Because adaptation rearranges your sizer and window hierarchy, it is not
fool-proof, and may fail in the following situations:
@li The dialog doesn't use sizers.
@li The dialog implementation makes assumptions about the window hierarchy,
for example getting the parent of a control and casting to the dialog class.
@li The dialog does custom painting and/or event handling not handled by the scrolled window.
If this problem can be solved globally, you can derive a new adapter class from
wxStandardDialogLayoutAdapter and override its CreateScrolledWindow function to return
an instance of your own class.
@li The dialog has unusual layout, for example a vertical sizer containing a mixture of
standard buttons and other controls.
@li The dialog makes assumptions about the sizer hierarchy, for example to show or hide
children of the top-level sizer. However, the original sizer hierarchy will still hold
until Show or ShowModal is called.
You can help make sure that your dialogs will continue to function after
adaptation by:
@li avoiding the above situations and assumptions;
@li using wxStdDialogButtonSizer;
@li only making assumptions about hierarchy immediately after the dialog is created;
@li using an intermediate sizer under the main sizer, a @false top-level sizer that
can be relied on to exist for the purposes of manipulating child sizers and windows;
@li overriding wxDialog::GetContentWindow to return a book control if your dialog implements
pages: wxWidgets will then only make the pages scrollable.
@subsection overview_dialog_propertysheet wxPropertySheetDialog and wxWizard
Adaptation for wxPropertySheetDialog is always done by simply making the pages
scrollable, since wxDialog::GetContentWindow returns the dialog's book control
and this is handled by the standard layout adapter.
wxWizard uses its own CanDoLayoutAdaptation and DoLayoutAdaptation functions
rather than the global adapter: again, only the wizard pages are made
scrollable.
*/

View File

@@ -0,0 +1,92 @@
/////////////////////////////////////////////////////////////////////////////
// Name: dnd.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_dnd Drag and Drop Overview
@tableofcontents
It may be noted that data transfer to and from the clipboard is quite
similar to data transfer with drag and drop and the code to implement
these two types is almost the same. In particular, both data transfer
mechanisms store data in some kind of wxDataObject and identify its format(s)
using the wxDataFormat class.
Note that @c wxUSE_DRAG_AND_DROP must be defined in @c setup.h in order
to use drag and drop in wxWidgets.
@see @ref overview_dataobject, @ref group_class_dnd, @ref page_samples_dnd
@section overview_dnd_dropsource Drop Source Requirements
To be a @e "drop source", i.e. to provide the data which may be dragged by
the user elsewhere, you should implement the following steps:
@li @b Preparation: First of all, a data object must be created and
initialized with the data you wish to drag. For example:
@code
wxTextDataObject my_data("This text will be dragged.");
@endcode
@li <b>Drag start</b>: To start the dragging process (typically in response to a
mouse click) you must call wxDropSource::DoDragDrop like this:
@code
wxDropSource dragSource( this );
dragSource.SetData( my_data );
wxDragResult result = dragSource.DoDragDrop( true );
@endcode
@li @b Dragging: The call to DoDragDrop() blocks the program until the user
releases the mouse button (unless you override the
wxDropSource::GiveFeedback function to do something special). When the
mouse moves in a window of a program which understands the same
drag-and-drop protocol (any program under Windows or any program supporting
the XDnD protocol under X Windows), the corresponding wxDropTarget methods
are called - see below.
@li <b>Processing the result</b>: DoDragDrop() returns an @e effect code which
is one of the values of @c wxDragResult enum (explained in wxDropTarget page):
@code
switch (result)
{
case wxDragCopy:
// copy the data
break;
case wxDragMove:
// move the data
break;
default:
// do nothing
break;
}
@endcode
@section overview_dnd_droptarget Drop Target Requirements
To be a @e "drop target", i.e. to receive the data dropped by the user you should
follow the instructions below:
@li @b Initialization: For a window to be a drop target, it needs to have
an associated wxDropTarget object. Normally, you will call wxWindow::SetDropTarget
during window creation associating your drop target with it. You must derive a class
from wxDropTarget and override its pure virtual methods. Alternatively, you may
derive from wxTextDropTarget or wxFileDropTarget and override their OnDropText()
or OnDropFiles() method.
@li @b Drop: When the user releases the mouse over a window, wxWidgets
asks the associated wxDropTarget object if it accepts the data. For this,
a wxDataObject must be associated with the drop target and this data object will
be responsible for the format negotiation between the drag source and the drop target.
If all goes well, then wxDropTarget::OnData will get called and the wxDataObject belonging
to the drop target can get filled with data.
@li <b>The end</b>: After processing the data, DoDragDrop() returns either
wxDragCopy or wxDragMove depending on the state of the keys Ctrl, Shift
and Alt at the moment of the drop. There is currently no way for the drop
target to change this return code.
*/

View File

@@ -0,0 +1,339 @@
/////////////////////////////////////////////////////////////////////////////
// Name: docview.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_docview Document/View Framework
@tableofcontents
The document/view framework is found in most application frameworks, because it
can dramatically simplify the code required to build many kinds of application.
The idea is that you can model your application primarily in terms of
@e documents to store data and provide interface-independent operations upon
it, and @e views to visualise and manipulate the data. Documents know how to do
input and output given stream objects, and views are responsible for taking
input from physical windows and performing the manipulation on the document
data.
If a document's data changes, all views should be updated to reflect the
change. The framework can provide many user-interface elements based on this
model.
Once you have defined your own classes and the relationships between them, the
framework takes care of popping up file selectors, opening and closing files,
asking the user to save modifications, routing menu commands to appropriate
(possibly default) code, even some default print/preview functionality and
support for command undo/redo.
The framework is highly modular, allowing overriding and replacement of
functionality and objects to achieve more than the default behaviour.
These are the overall steps involved in creating an application based on the
document/view framework:
@li Define your own document and view classes, overriding a minimal set of
member functions e.g. for input/output, drawing and initialization.
@li Define any subwindows (such as a scrolled window) that are needed for the
view(s). You may need to route some events to views or documents, for
example, "OnPaint" needs to be routed to wxView::OnDraw.
@li Decide what style of interface you will use: Microsoft's MDI (multiple
document child frames surrounded by an overall frame), SDI (a separate,
unconstrained frame for each document), or single-window (one document open
at a time, as in Windows Write).
@li Use the appropriate wxDocParentFrame and wxDocChildFrame classes. Construct
an instance of wxDocParentFrame in your wxApp::OnInit, and a
wxDocChildFrame (if not single-window) when you initialize a view. Create
menus using standard menu ids (such as wxID_OPEN, wxID_PRINT).
@li Construct a single wxDocManager instance at the beginning of your
wxApp::OnInit, and then as many wxDocTemplate instances as necessary to
define relationships between documents and views. For a simple application,
there will be just one wxDocTemplate.
If you wish to implement Undo/Redo, you need to derive your own class(es) from
wxCommand and use wxCommandProcessor::Submit instead of directly executing
code. The framework will take care of calling Undo and Do functions as
appropriate, so long as the wxID_UNDO and wxID_REDO menu items are defined in
the view menu.
Here are a few examples of the tailoring you can do to go beyond the default
framework behaviour:
@li Override wxDocument::OnCreateCommandProcessor to define a different Do/Undo
strategy, or a command history editor.
@li Override wxView::OnCreatePrintout to create an instance of a derived
wxPrintout class, to provide multi-page document facilities.
@li Override wxDocManager::SelectDocumentPath to provide a different file
selector.
@li Limit the maximum number of open documents and the maximum number of undo
commands.
Note that to activate framework functionality, you need to use some or all of
the wxWidgets @ref overview_docview_predefid in your menus.
@beginWxPerlOnly
The document/view framework is available in wxPerl. To use it, you will need
the following statements in your application code:
@code{.pl}
use Wx::DocView;
use Wx ':docview'; # import constants (optional)
@endcode
@endWxPerlOnly
@see @ref group_class_docview,
@section overview_docview_wxdoc wxDocument Overview
The wxDocument class can be used to model an application's file-based data. It
is part of the document/view framework supported by wxWidgets, and cooperates
with the wxView, wxDocTemplate and wxDocManager classes. Using this framework
can save a lot of routine user-interface programming, since a range of menu
commands -- such as open, save, save as -- are supported automatically.
The programmer just needs to define a minimal set of classes and member
functions for the framework to call when necessary. Data, and the means to view
and edit the data, are explicitly separated out in this model, and the concept
of multiple @e views onto the same data is supported.
Note that the document/view model will suit many but not all styles of
application. For example, it would be overkill for a simple file conversion
utility, where there may be no call for @e views on @e documents or the ability
to open, edit and save files. But probably the majority of applications are
document-based.
See the example application in @c samples/docview. To use the abstract
wxDocument class, you need to derive a new class and override at least the
member functions SaveObject and LoadObject. SaveObject and LoadObject will be
called by the framework when the document needs to be saved or loaded.
Use the macros wxDECLARE_DYNAMIC_CLASS and wxIMPLEMENT_DYNAMIC_CLASS in order
to allow the framework to create document objects on demand. When you create
a wxDocTemplate object on application initialization, you should pass
CLASSINFO(YourDocumentClass) to the wxDocTemplate constructor so that it knows
how to create an instance of this class.
If you do not wish to use the wxWidgets method of creating document objects
dynamically, you must override wxDocTemplate::CreateDocument to return an
instance of the appropriate class.
@section overview_docview_wxview wxView Overview
The wxView class can be used to model the viewing and editing component of an
application's file-based data. It is part of the document/view framework
supported by wxWidgets, and cooperates with the wxDocument, wxDocTemplate and
wxDocManager classes.
See the example application in @c samples/docview.
To use the abstract wxView class, you need to derive a new class and override
at least the member functions OnCreate, OnDraw, OnUpdate and OnClose. You will
probably want to respond to menu commands from the frame containing the view.
Use the macros wxDECLARE_DYNAMIC_CLASS and wxIMPLEMENT_DYNAMIC_CLASS in order
to allow the framework to create view objects on demand. When you create a
wxDocTemplate object on application initialization, you should pass
CLASSINFO(YourViewClass) to the wxDocTemplate constructor so that it knows how
to create an instance of this class.
If you do not wish to use the wxWidgets method of creating view objects
dynamically, you must override wxDocTemplate::CreateView to return an instance
of the appropriate class.
@section overview_docview_wxdoctemplate wxDocTemplate Overview
The wxDocTemplate class is used to model the relationship between a document
class and a view class. The application creates a document template object for
each document/view pair. The list of document templates managed by the
wxDocManager instance is used to create documents and views. Each document
template knows what file filters and default extension are appropriate for a
document/view combination, and how to create a document or view.
For example, you might write a small doodling application that can load and
save lists of line segments. If you had two views of the data -- graphical, and
a list of the segments -- then you would create one document class
DoodleDocument, and two view classes (DoodleGraphicView and DoodleListView).
You would also need two document templates, one for the graphical view and
another for the list view. You would pass the same document class and default
file extension to both document templates, but each would be passed a different
view class. When the user clicks on the Open menu item, the file selector is
displayed with a list of possible file filters -- one for each wxDocTemplate.
Selecting the filter selects the wxDocTemplate, and when a file is selected,
that template will be used for creating a document and view.
For the case where an application has one document type and one view type,
a single document template is constructed, and dialogs will be appropriately
simplified.
wxDocTemplate is part of the document/view framework supported by wxWidgets,
and cooperates with the wxView, wxDocument and wxDocManager classes.
See the example application in @c samples/docview.
To use the wxDocTemplate class, you do not need to derive a new class. Just
pass relevant information to the constructor including
CLASSINFO(YourDocumentClass) and CLASSINFO(YourViewClass) to allow dynamic
instance creation.
If you do not wish to use the wxWidgets method of creating document
objects dynamically, you must override wxDocTemplate::CreateDocument
and wxDocTemplate::CreateView to return instances of the appropriate class.
@note The document template has nothing to do with the C++ template construct.
@section overview_docview_wxdocmanager wxDocManager Overview
The wxDocManager class is part of the document/view framework supported by
wxWidgets, and cooperates with the wxView, wxDocument and wxDocTemplate
classes.
A wxDocManager instance coordinates documents, views and document templates. It
keeps a list of document and template instances, and much functionality is
routed through this object, such as providing selection and file dialogs. The
application can use this class 'as is' or derive a class and override some
members to extend or change the functionality.
Create an instance of this class near the beginning of your application
initialization, before any documents, views or templates are manipulated.
There may be multiple wxDocManager instances in an application. See the example
application in @c samples/docview.
@section overview_docview_events Event Propagation in Document/View framework
While wxDocument, wxDocManager and wxView are abstract objects, with which the
user can't interact directly, all of them derive from wxEvtHandler class and
can handle events arising in the windows showing the document with which the
user does interact. This is implemented by adding additional steps to the event
handling process described in @ref overview_events_processing, so the full list
of the handlers searched for an event occurring directly in wxDocChildFrame is:
<ol>
<li>wxDocument opened in this frame.</li>
<li>wxView shown in this frame.</li>
<li>wxDocManager associated with the parent wxDocParentFrame.</li>
<li>wxDocChildFrame itself.</li>
<li>wxDocParentFrame, as per the usual event bubbling up to parent rules.</li>
<li>wxApp, again as the usual fallback for all events.</li>
</ol>
This is mostly useful to define handlers for some menu commands directly in
wxDocument or wxView and is also used by the framework itself to define the
handlers for several standard commands, such as wxID_NEW or wxID_SAVE, in
wxDocManager itself. Notice that due to the order of the event handler search
detailed above, the handling of these commands can @e not be overridden at
wxDocParentFrame level but must be done at the level of wxDocManager itself.
@section overview_docview_wxcommand wxCommand Overview
wxCommand is a base class for modelling an application command, which is an
action usually performed by selecting a menu item, pressing a toolbar button or
any other means provided by the application to change the data or view.
Instead of the application functionality being scattered around switch
statements and functions in a way that may be hard to read and maintain, the
functionality for a command is explicitly represented as an object which can be
manipulated by a framework or application.
When a user interface event occurs, the application @e submits a command to a
wxCommandProcessor object to execute and store.
The wxWidgets document/view framework handles Undo and Redo by use of wxCommand
and wxCommandProcessor objects. You might find further uses for wxCommand, such
as implementing a macro facility that stores, loads and replays commands.
An application can derive a new class for every command, or, more likely, use
one class parameterized with an integer or string command identifier.
@section overview_docview_wxcommandproc wxCommandProcessor Overview
wxCommandProcessor is a class that maintains a history of wxCommand instances,
with undo/redo functionality built-in. Derive a new class from this if you want
different behaviour.
@section overview_docview_filehistory wxFileHistory Overview
wxFileHistory encapsulates functionality to record the last few files visited,
and to allow the user to quickly load these files using the list appended to
the File menu. Although wxFileHistory is used by wxDocManager, it can be used
independently. You may wish to derive from it to allow different behaviour,
such as popping up a scrolling list of files.
By calling wxFileHistory::UseMenu() you can associate a file menu with the file
history. The menu will then be used for appending filenames that are added to
the history.
Please notice that currently if the history already contained filenames when
UseMenu() is called (e.g. when initializing a second MDI child frame), the menu
is not automatically initialized with the existing filenames in the history and
so you need to call wxFileHistory::AddFilesToMenu() after UseMenu() explicitly
in order to initialize the menu with the existing list of MRU files (otherwise
an assertion failure is raised in debug builds).
The filenames are appended using menu identifiers in the range @c wxID_FILE1 to
@c wxID_FILE9.
In order to respond to a file load command from one of these identifiers, you
need to handle them using an event handler, for example:
@code
wxBEGIN_EVENT_TABLE(wxDocParentFrame, wxFrame)
EVT_MENU(wxID_EXIT, wxDocParentFrame::OnExit)
EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, wxDocParentFrame::OnMRUFile)
wxEND_EVENT_TABLE()
void wxDocParentFrame::OnExit(wxCommandEvent& WXUNUSED(event))
{
Close();
}
void wxDocParentFrame::OnMRUFile(wxCommandEvent& event)
{
wxString f(m_docManager->GetHistoryFile(event.GetId() - wxID_FILE1));
if (!f.empty())
(void)m_docManager-CreateDocument(f, wxDOC_SILENT);
}
@endcode
@section overview_docview_predefid Predefined Command Identifiers
To allow communication between the application's menus and the document/view
framework, several command identifiers are predefined for you to use in menus.
@verbatim
wxID_OPEN (5000)
wxID_CLOSE (5001)
wxID_NEW (5002)
wxID_SAVE (5003)
wxID_SAVEAS (5004)
wxID_REVERT (5005)
wxID_EXIT (5006)
wxID_UNDO (5007)
wxID_REDO (5008)
wxID_HELP (5009)
wxID_PRINT (5010)
wxID_PRINT_SETUP (5011)
wxID_PREVIEW (5012)
@endverbatim
*/

View File

@@ -0,0 +1,63 @@
/////////////////////////////////////////////////////////////////////////////
// Name: envvars.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_envvars Environment Variables
This section describes all environment variables that affect execution of
wxWidgets programs.
@beginDefList
@itemdef{WXLOG_TIME_FORMAT,
If set, the contents of this variable is set as the initial timestamp
used for logging, i.e. passed to wxLog::SetTimestamp(), on program
startup. For example, this can be used to enable milliseconds in the
timestamps by setting `WXLOG_TIME_FORMAT=%H:%M:%S.%l` or it could also
be used to use ISO 8601 timestamp format instead of the default
locale-dependent format. This variable is only used since wxWidgets
3.3.0.}
@itemdef{WXTRACE,
This variable can be set to a comma-separated list of trace masks used in
wxLogTrace calls; wxLog::AddTraceMask is called for every mask
in the list during wxWidgets initialization. It only has an effect if
debug logging is enabled, see wxLogTrace().}
@itemdef{WXPREFIX,
(Unix only.)
Overrides installation prefix. Normally, the prefix
is hard-coded and is the same as the value passed to @c configure via
the @c \--prefix switch when compiling the library (typically
@c /usr/local or @c /usr). You can set WXPREFIX if you are for example
distributing a binary version of an application and you don't know in advance
where it will be installed.}
@itemdef{WXWEBREQUEST_BACKEND,
This variable can be set to override the choice of the default backend
used by wxWebRequest, see wxWebSession::New(). Most common use is to
set it to @c "CURL" to force using libcurl-based implementation under
MSW or macOS platforms where the native implementation would be chosen
by default.}
@itemdef{WXSUPPRESS_SIZER_FLAGS_CHECK,
If set, disables asserts about using invalid sizer flags in the code.
This can be helpful when running older programs recompiled with
wxWidgets 3.1 or later, as these asserts are mostly harmless and can
be safely ignored if the code works as expected.}
@itemdef{WXSUPPRESS_GTK_DIAGNOSTICS,
If set to a non-zero value, wxApp::GTKSuppressDiagnostics() is called
on program startup using the numeric value of this variable or the
default value if it's not a number, so that e.g. setting it to "yes"
suppresses all GTK diagnostics while setting it to 16 only suppresses
GTK warning messages.}
@itemdef{WXLANGUAGE,
This variable can be set to override OS setting of preferred languages
and make wxUILocale::GetPreferredUILanguages() return the set list
instead. The format is a superset of GNU's <a
href="https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html">LANGUAGE</a>
variable: a colon-separated list of language tags (which are, in their
simplest form, just the language names).}
*/
@see wxSystemOptions

View File

@@ -0,0 +1,935 @@
/////////////////////////////////////////////////////////////////////////////
// Name: eventhandling.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_events Events and Event Handling
@tableofcontents
Like with all the other GUI frameworks, the control of flow in wxWidgets
applications is event-based: the program normally performs most of its actions
in response to the events generated by the user. These events can be triggered
by using the input devices (such as keyboard, mouse, joystick) directly or,
more commonly, by a standard control which synthesizes such input events into
higher level events: for example, a wxButton can generate a click event when
the user presses the left mouse button on it and then releases it without
pressing @c Esc in the meanwhile. There are also events which don't directly
correspond to the user actions, such as wxTimerEvent or wxSocketEvent.
But in all cases wxWidgets represents these events in a uniform way and allows
you to handle them in the same way wherever they originate from. And while the
events are normally generated by wxWidgets itself, you can also do this, which
is especially useful when using custom events (see @ref overview_events_custom).
To be more precise, each event is described by:
- <em>Event type</em>: this is simply a value of type wxEventType which
uniquely identifies the type of the event. For example, clicking on a button,
selecting an item from a list box and pressing a key on the keyboard all
generate events with different event types.
- <em>Event class</em> carried by the event: each event has some information
associated with it and this data is represented by an object of a class
derived from wxEvent. Events of different types can use the same event class,
for example both button click and listbox selection events use wxCommandEvent
class (as do all the other simple control events), but the key press event
uses wxKeyEvent as the information associated with it is different.
- <em>Event source</em>: wxEvent stores the object which generated the event
and, for windows, its identifier (see @ref overview_events_winid). As it is
common to have more than one object generating events of the same type (e.g. a
typical window contains several buttons, all generating the same button click
event), checking the event source object or its id allows to distinguish
between them.
@see wxEvtHandler, wxWindow, wxEvent
@section overview_events_eventhandling Event Handling
There are two principal ways to handle events in wxWidgets. One of them uses
<em>event table</em> macros and allows you to define the binding between events
and their handlers only statically, i.e., during program compilation. The other
one uses wxEvtHandler::Bind<>() call and can be used to bind and
unbind, the handlers dynamically, i.e. during run-time depending on some
conditions. It also allows the direct binding of events to:
@li A handler method in another object.
@li An ordinary function like a static method or a global function.
@li An arbitrary functor such as boost::function<> or, in C++11,
std::function<> or a lambda expression.
The static event tables can only handle events in the object where they are
defined so using Bind<>() is more flexible than using the event tables. On the
other hand, event tables are more succinct and centralize all event handler
bindings in one place. You can either choose a single approach that you find
preferable or freely combine both methods in your program in different classes
or even in one and the same class, although this is probably sufficiently
confusing to be a bad idea.
Also notice that most of the existing wxWidgets tutorials and discussions use
the event tables because they historically preceded the apparition of dynamic
event handling in wxWidgets. But this absolutely doesn't mean that using the
event tables is the preferred way: handling events dynamically is better in
several aspects and you should strongly consider doing it if you are just
starting with wxWidgets. On the other hand, you still need to know about the
event tables if only because you are going to see them in many samples and
examples.
So before you make the choice between static event tables and dynamically
connecting the event handlers, let us discuss these two ways in more detail. In
the next section we provide a short introduction to handling the events using
the event tables. Please see @ref overview_events_bind for the discussion of
Bind<>().
@subsection overview_events_eventtables Event Handling with Event Tables
To use an <em>event table</em> you must first decide in which class you wish to
handle the events. The only requirement imposed by wxWidgets is that this class
must derive from wxEvtHandler and so, considering that wxWindow derives from
it, any classes representing windows can handle events. Simple events such as
menu commands are usually processed at the level of a top-level window
containing the menu, so let's suppose that you need to handle some events in @c
MyFrame class deriving from wxFrame.
First define one or more <em>event handlers</em>. They
are just simple methods of the class that take as a parameter a
reference to an object of a wxEvent-derived class and have no return value (any
return information is passed via the argument, which is why it is non-const).
You also need to insert a line with the macro indicating that the class uses an
event table, like this:
@code
wxDECLARE_EVENT_TABLE();
@endcode
somewhere in the class declaration. It doesn't matter where it appears but
it's customary to put it at the end because the macro changes the access
type internally so it's safest if nothing follows it. The
full class declaration might look like this:
@code
class MyFrame : public wxFrame
{
public:
MyFrame(...) : wxFrame(...) { }
...
protected:
int m_whatever;
private:
// Notice that as the event handlers normally are not called from outside
// the class, they normally are private. In particular they don't need
// to be public.
void OnExit(wxCommandEvent& event);
void OnButton1(wxCommandEvent& event);
void OnSize(wxSizeEvent& event);
// it's common to call the event handlers OnSomething() but there is no
// obligation to do that; this one is an event handler too:
void DoTest(wxCommandEvent& event);
wxDECLARE_EVENT_TABLE();
};
@endcode
Next the event table must be defined and, as with any definition, it must be
placed in an implementation file. The event table tells wxWidgets how to map
events to member functions and in our example it could look like this:
@code
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
EVT_MENU(DO_TEST, MyFrame::DoTest)
EVT_SIZE(MyFrame::OnSize)
EVT_BUTTON(BUTTON1, MyFrame::OnButton1)
wxEND_EVENT_TABLE()
@endcode
Notice that you must mention a method you want to use for the event handling in
the event table definition; just defining it in MyFrame class is @e not enough.
Let us now look at the details of this definition: the first line means that we
are defining the event table for MyFrame class and that its base class is
wxFrame, so events not processed by MyFrame will, by default, be handled by
wxFrame. The next four lines define bindings of individual events to their
handlers: the first two of them map menu commands from the items with the
identifiers specified as the first macro parameter to two different member
functions. In the next one, @c EVT_SIZE means that any changes in the size of
the frame will result in calling OnSize() method. Note that this macro doesn't
need a window identifier, since normally you are only interested in the current
window's size events.
The @c EVT_BUTTON macro demonstrates that the originating event does not have to
come from the window class implementing the event table -- if the event source
is a button within a panel within a frame, this will still work, because event
tables are searched up through the hierarchy of windows for the command events.
(But only command events, so you can't catch mouse move events in a child
control in the parent window in the same way because wxMouseEvent doesn't
derive from wxCommandEvent. See below for how you can do it.) In this case, the
button's event table will be searched, then the parent panel's, then the
frame's.
Finally, you need to implement the event handlers. As mentioned before, all
event handlers take a wxEvent-derived argument whose exact class differs
according to the type of event and the class of the originating window. For
size events, wxSizeEvent is used. For menu commands and most control commands
(such as button presses), wxCommandEvent is used. When controls get more
complicated, more specific wxCommandEvent-derived event classes providing
additional control-specific information can be used, such as wxTreeEvent for
events from wxTreeCtrl windows.
In the simplest possible case an event handler may not use the @c event
parameter at all. For example,
@code
void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
{
// when the user selects "Exit" from the menu we should close
Close(true);
}
@endcode
In other cases you may need some information carried by the @c event argument,
as in:
@code
void MyFrame::OnSize(wxSizeEvent& event)
{
wxSize size = event.GetSize();
... update the frame using the new size ...
}
@endcode
You will find the details about the event table macros and the corresponding
wxEvent-derived classes in the discussion of each control generating these
events.
@subsection overview_events_bind Dynamic Event Handling
@see @ref overview_cpp_rtti_disabled
The possibilities of handling events in this way are rather different.
Let us start by looking at the syntax: the first obvious difference is that you
need not use wxDECLARE_EVENT_TABLE() nor wxBEGIN_EVENT_TABLE() and the
associated macros. Instead, in any place in your code, but usually in
the code of the class defining the handler itself (and definitely not in the
global scope as with the event tables), call its Bind<>() method like this:
@code
MyFrame::MyFrame(...)
{
Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT);
}
@endcode
Note that @c this pointer must be specified here.
Now let us describe the semantic differences:
<ul>
<li>
Event handlers can be bound at any moment. For example, it's possible
to do some initialization first and only bind the handlers if and when
it succeeds. This can avoid the need to test that the object was properly
initialized in the event handlers themselves. With Bind<>() they
simply won't be called if it wasn't correctly initialized.
</li>
<li>
As a slight extension of the above, the handlers can also be unbound at
any time with Unbind<>() (and maybe rebound later). Of course,
it's also possible to emulate this behaviour with the classic
static (i.e., bound via event tables) handlers by using an internal
flag indicating whether the handler is currently enabled and returning
from it if it isn't, but using dynamically bind handlers requires
less code and is also usually more clear.
</li>
<li>
Almost last but very, very far from least is the increased flexibility
which allows to bind an event to:
@li A method in another object.
@li An ordinary function like a static method or a global function.
@li An arbitrary functor such as boost::function<> or, in C++11,
std::function<> or a lambda expression.
This is impossible to do with the event tables because it is not
possible to specify these handlers to dispatch the event to, so it
necessarily needs to be sent to the same object which generated the
event. Not so with Bind<>() which can be used to specify these handlers
which will handle the event. To give a quick example, a common question
is how to receive the mouse movement events happening when the mouse is
in one of the frame children in the frame itself. Doing it in a naive
way doesn't work:
<ul>
<li>
A @c EVT_LEAVE_WINDOW(MyFrame::OnMouseLeave) line in the frame
event table has no effect as mouse move (including entering and
leaving) events are not propagated up to the parent window
(at least not by default).
</li>
<li>
Putting the same line in a child event table will crash during
run-time because the MyFrame method will be called on a wrong
object -- it's easy to convince oneself that the only object
that can be used here is the pointer to the child, as
wxWidgets has nothing else. But calling a frame method with the
child window pointer instead of the pointer to the frame is, of
course, disastrous.
</li>
</ul>
However writing
@code
MyFrame::MyFrame(...)
{
m_child->Bind(wxEVT_LEAVE_WINDOW, &MyFrame::OnMouseLeave, this);
}
@endcode
will work exactly as expected. Note that you can get the object that
generated the event -- and that is not the same as the frame -- via
wxEvent::GetEventObject() method of @c event argument passed to the
event handler.
</li>
<li>
Really last point is the consequence of the previous one: because of
increased flexibility of Bind(), it is also safer as it is impossible
to accidentally use a method of another class. Instead of run-time
crashes you will get compilation errors in this case when using Bind().
</li>
</ul>
Let us now look at more examples of how to use different event handlers using
the two overloads of Bind() function: first one for the object methods and the
other one for arbitrary functors (callable objects, including simple functions):
In addition to using a method of the object generating the event itself, you
can use a method from a completely different object as an event handler:
@code
void MyFrameHandler::OnFrameExit(wxCommandEvent&)
{
// Do something useful.
}
MyFrameHandler myFrameHandler;
MyFrame::MyFrame()
{
Bind(wxEVT_MENU, &MyFrameHandler::OnFrameExit,
&myFrameHandler, wxID_EXIT);
}
@endcode
Note that @c MyFrameHandler doesn't need to derive from wxEvtHandler. But
keep in mind that then the lifetime of @c myFrameHandler must be greater than
that of @c MyFrame object -- or at least it needs to be unbound before being
destroyed.
To use an ordinary function or a static method as an event handler you would
write something like this:
@code
void HandleExit(wxCommandEvent&)
{
// Do something useful
}
MyFrame::MyFrame()
{
Bind(wxEVT_MENU, &HandleExit, wxID_EXIT);
}
@endcode
And finally you can bind to an arbitrary functor and use it as an event
handler:
@code
struct MyFunctor
{
void operator()(wxCommandEvent&)
{
// Do something useful
}
};
MyFunctor myFunctor;
MyFrame::MyFrame()
{
Bind(wxEVT_MENU, myFunctor, wxID_EXIT);
}
@endcode
In C++11 a lambda expression can be used directly, without having to define a
separate functor class:
@code
MyFrame::MyFrame()
{
Bind(wxEVT_MENU,
[](wxCommandEvent&) {
// Do something useful
},
wxID_EXIT);
}
@endcode
Another common example of a generic functor is boost::function<> or, since
C++11, std::function<>:
@code
#if wxCHECK_CXX_STD(201103L)
using namespace std;
using namespace std::placeholders;
#else // Pre C++11 compiler
using namespace boost;
#endif
void MyHandler::OnExit(wxCommandEvent&)
{
// Do something useful
}
MyHandler myHandler;
MyFrame::MyFrame()
{
function<void (wxCommandEvent& )> exitHandler(bind(&MyHandler::OnExit, &myHandler, _1));
Bind(wxEVT_MENU, exitHandler, wxID_EXIT);
}
@endcode
With the aid of @c bind<>() you can even use methods or functions which
don't quite have the correct signature:
@code
void MyHandler::OnExit(int exitCode, wxCommandEvent&, wxString goodByeMessage)
{
// Do something useful
}
MyHandler myHandler;
MyFrame::MyFrame()
{
function<void (wxCommandEvent&)> exitHandler(
bind(&MyHandler::OnExit, &myHandler, EXIT_FAILURE, _1, "Bye"));
Bind(wxEVT_MENU, exitHandler, wxID_EXIT);
}
@endcode
To summarize, using Bind<>() requires slightly more typing but is much more
flexible than using static event tables so don't hesitate to use it when you
need this extra power. On the other hand, event tables are still perfectly fine
in simple situations where this extra flexibility is not needed.
@section overview_events_processing How Events are Processed
The previous sections explain how to define event handlers but don't address
the question of how exactly wxWidgets finds the handler to call for the
given event. This section describes the algorithm used in detail. Notice that
you may want to run the @ref page_samples_event while reading this section and
look at its code and the output when the button which can be used to test the
event handlers execution order is clicked to understand it better.
When an event is received from the windowing system, wxWidgets calls
wxEvtHandler::ProcessEvent() on the first event handler object belonging to the
window generating the event. The normal order of event table searching by
ProcessEvent() is as follows, with the event processing stopping as soon as a
handler is found (unless the handler calls wxEvent::Skip() in which case it
doesn't count as having handled the event and the search continues):
<ol>
<li value="0">
Before anything else happens, wxApp::FilterEvent() is called. If it returns
anything but -1 (default), the event handling stops immediately.
</li>
<li value="1">
If the object is a wxWindow and has an associated validator, wxValidator
gets a chance to process the event.
</li>
<li value="2">
If this event handler is disabled via a call to
wxEvtHandler::SetEvtHandlerEnabled() the two next steps are skipped and
the event handler resumes at step (5).
</li>
<li value="3">
The list of dynamically bound event handlers, i.e., those for which
Bind<>() was called, is consulted. Notice that this is done before
checking the static event table entries, so if both a dynamic and a static
event handler match the same event, the static one is never going to be
used unless wxEvent::Skip() is called in the dynamic one. Also note that
the dynamically bound handlers are searched in reverse order of their registration
during program run-time, i.e. later bound handlers take priority over the
previously bound ones.
</li>
<li value="4">
The event table containing all the handlers defined using the event table
macros in this class and its base classes is examined. The search in an
event table respects the order of the event macros appearance in the source
code, i.e. earlier occurring entries take precedence over later occurring
ones. Notice that this means that any event handler defined in a base class
will be executed at this step.
</li>
<li value="5">
The event is passed to the next event handler, if any, in the event handler
chain, i.e., the steps (1) to (4) are done for it. Usually there is no next
event handler so the control passes to the next step but see @ref
overview_events_nexthandler for how the next handler may be defined.
</li>
<li value="6">
If the object is a wxWindow and the event is set to propagate (by default
only wxCommandEvent-derived events are set to propagate), then the
processing restarts from the step (1) (and excluding the step (7)) for the
parent window. If this object is not a window but the next handler exists,
the event is passed to its parent if it is a window. This ensures that in a
common case of (possibly several) non-window event handlers pushed on top
of a window, the event eventually reaches the window parent.
</li>
<li value="7">
Finally, i.e., if the event is still not processed, the wxApp object itself
(which derives from wxEvtHandler) gets a last chance to process it.
</li>
</ol>
<em>Please pay close attention to step 6!</em> People often overlook or get
confused by this powerful feature of the wxWidgets event processing system. The
details of event propagation up the window hierarchy are described in the
next section.
Also please notice that there are additional steps in the event handling for
the windows-making part of wxWidgets document-view framework, i.e.,
wxDocParentFrame, wxDocChildFrame and their MDI equivalents wxDocMDIParentFrame
and wxDocMDIChildFrame. The parent frame classes modify step (2) above to
send the events received by them to wxDocManager object first. This object, in
turn, sends the event to the current view and the view itself lets its
associated document process the event first. The child frame classes send
the event directly to the associated view which still forwards it to its
document object. Notice that to avoid remembering the exact order in which the
events are processed in the document-view frame, the simplest, and recommended,
solution is to only handle the events at the view classes level, and not in the
document or document manager classes
@subsection overview_events_propagation How Events Propagate Upwards
As mentioned above, the events of the classes deriving from wxCommandEvent are
propagated by default to the parent window if they are not processed in this
window itself. But although by default only the command events are propagated
like this, other events can be propagated as well because the event handling
code uses wxEvent::ShouldPropagate() to check whether an event should be
propagated. It is also possible to propagate the event only a limited number of
times and not until it is processed (or a top level parent window is reached).
Finally, there is another additional complication (which, in fact, simplifies
life of wxWidgets programmers significantly): when propagating the command
events up to the parent window, the event propagation stops when it
reaches the parent dialog, if any. This means that you don't risk getting
unexpected events from the dialog controls (which might be left unprocessed by
the dialog itself because it doesn't care about them) when a modal dialog is
popped up. The events do propagate beyond the frames, however. The rationale
for this choice is that there are only a few frames in a typical application
and their parent-child relation are well understood by the programmer while it
may be difficult, if not impossible, to track down all the dialogs that
may be popped up in a complex program (remember that some are created
automatically by wxWidgets). If you need to specify a different behaviour for
some reason, you can use <tt>wxWindow::SetExtraStyle(wxWS_EX_BLOCK_EVENTS)</tt>
explicitly to prevent the events from being propagated beyond the given window
or unset this flag for the dialogs that have it on by default.
Typically events that deal with a window as a window (size, motion,
paint, mouse, keyboard, etc.) are sent only to the window. Events
that have a higher level of meaning or are generated by the window
itself (button click, menu select, tree expand, etc.) are command
events and are sent up to the parent to see if it is interested in the event.
More precisely, as said above, all event classes @b not deriving from wxCommandEvent
(see the wxEvent inheritance map) do @b not propagate upward.
In some cases, it might be desired by the programmer to get a certain number
of system events in a parent window, for example all key events sent to, but not
used by, the native controls in a dialog. In this case, a special event handler
will have to be written that will override ProcessEvent() in order to pass
all events (or any selection of them) to the parent window.
@subsection overview_events_nexthandler Event Handlers Chain
The step 5 of the event propagation algorithm checks for the next handler in
the event handler chain. This chain can be formed using
wxEvtHandler::SetNextHandler():
@image html overview_events_chain.png
(referring to the image, if @c A->ProcessEvent is called and it doesn't handle
the event, @c B->ProcessEvent will be called and so on...).
Additionally, in the case of wxWindow you can build a stack (implemented using
wxEvtHandler double-linked list) using wxWindow::PushEventHandler():
@image html overview_events_winstack.png
(referring to the image, if @c W->ProcessEvent is called, it immediately calls
@c A->ProcessEvent; if nor @c A nor @c B handle the event, then the wxWindow
itself is used -- i.e. the dynamically bind event handlers and static event
table entries of wxWindow are looked as the last possibility, after all pushed
event handlers were tested).
By default the chain is empty, i.e. there is no next handler.
@section overview_events_custom Custom Event Summary
@subsection overview_events_custom_general General approach
As each event is uniquely defined by its event type, defining a custom event
starts with defining a new event type for it. This is done using
wxDEFINE_EVENT() macro. As an event type is a variable, it can also be
declared using wxDECLARE_EVENT() if necessary.
The next thing to do is to decide whether you need to define a custom event
class for events of this type or if you can reuse an existing class, typically
either wxEvent (which doesn't provide any extra information) or wxCommandEvent
(which contains several extra fields and also propagates upwards by default).
Both strategies are described in details below. See also the @ref
page_samples_event for a complete example of code defining and working with the
custom event types.
Finally, you will need to generate and post your custom events.
Generation is as simple as instancing your custom event class and initializing
its internal fields.
For posting events to a certain event handler there are two possibilities:
using wxEvtHandler::AddPendingEvent or using wxEvtHandler::QueueEvent.
Basically you will need to use the latter when doing inter-thread communication;
when you use only the main thread you can also safely use the former.
Last, note that there are also two simple global wrapper functions associated
to the two wxEvtHandler mentioned functions: wxPostEvent() and wxQueueEvent().
@subsection overview_events_custom_existing Using Existing Event Classes
If you just want to use a wxCommandEvent with a new event type, use one of the
generic event table macros listed below, without having to define a new event
class yourself.
Example:
@code
// this is typically in a header: it just declares MY_EVENT event type
wxDECLARE_EVENT(MY_EVENT, wxCommandEvent);
// this is a definition so can't be in a header
wxDEFINE_EVENT(MY_EVENT, wxCommandEvent);
// example of code handling the event with event tables
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU (wxID_EXIT, MyFrame::OnExit)
...
EVT_COMMAND (ID_MY_WINDOW, MY_EVENT, MyFrame::OnMyEvent)
wxEND_EVENT_TABLE()
void MyFrame::OnMyEvent(wxCommandEvent& event)
{
// do something
wxString text = event.GetString();
}
// example of code handling the event with Bind<>():
MyFrame::MyFrame()
{
Bind(MY_EVENT, &MyFrame::OnMyEvent, this, ID_MY_WINDOW);
}
// example of code generating the event
void MyWindow::SendEvent()
{
wxCommandEvent event(MY_EVENT, GetId());
event.SetEventObject(this);
// Give it some contents
event.SetString("Hello");
// Do send it
ProcessWindowEvent(event);
}
@endcode
@subsection overview_events_custom_ownclass Defining Your Own Event Class
Under certain circumstances, you must define your own event class e.g., for
sending more complex data from one place to another. Apart from defining your
event class, you also need to define your own event table macro if you still
need to use event tables (now considered legacy) for handling events of this type.
See ChessBoardEvent in the event sample for a full working implementation
of a new wxEvent-derived class.
Here is a simple example:
@code
// create a new event class derived from wxEvent
class MyPlotEvent: public wxEvent
{
public:
MyPlotEvent(wxEventType eventType, int winid, const wxPoint& pos)
: wxEvent(winid, eventType),
m_pos(pos)
{
}
// accessors
wxPoint GetPoint() const { return m_pos; }
// implement the base class pure virtual
virtual wxEvent *Clone() const { return new MyPlotEvent(*this); }
private:
const wxPoint m_pos;
};
// We use a single myEVT_PLOT_CLICKED event type associated with the class
// above but often you are going to have more than one event type, e.g. you
// could also have myEVT_PLOT_ZOOMED or myEVT_PLOT_PANNED etc. -- in which case
// you would just add more similar lines here.
//
// Note that this macro, as all declarations, should be in the header, and
// there should be a matching definition macro in some source file (see
// wxDEFINE_EVENT below).
wxDECLARE_EVENT(myEVT_PLOT_CLICKED, MyPlotEvent);
// --- Skip this part if you're only going to use Bind() (as recommended) ---
// The following typedef and macro are needed only when the new event class
// still needs to be used with the legacy approach to handling events - event
// table macros or Connect() - to cast the type of a function handling it to
// the type expected by the legacy event handling machinery.
typedef void (wxEvtHandler::*MyPlotEventFunction)(MyPlotEvent&);
#define MyPlotEventHandler(func) wxEVENT_HANDLER_CAST(MyPlotEventFunction, func)
// If the new event is to be used with event tables, a macro for creating
// event table entries for the new event type must be defined.
#define EVT_PLOT_CLICKED(id, func) \
wx__DECLARE_EVT1(myEVT_PLOT_CLICKED, id, MyPlotEventHandler(func))
// --- End of the part which is only relevant when using event tables ---
// Up until now, we only had declarations that would typically appear in a
// header file. Starting from now we have the definitions, which must occur
// only once in the program and so need to be in a source file.
// This defines the event type declared above. If you use multiple event types,
// you need to do it for each of them.
wxDEFINE_EVENT(myEVT_PLOT_CLICKED, MyPlotEvent);
// example of code handling the event (you will use one of these methods,
// not both, of course):
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_PLOT_CLICKED(ID_MY_WINDOW, MyFrame::OnPlot)
wxEND_EVENT_TABLE()
MyFrame::MyFrame()
{
Bind(myEVT_PLOT_CLICKED, &MyFrame::OnPlot, this, ID_MY_WINDOW);
}
void MyFrame::OnPlot(MyPlotEvent& event)
{
... do something with event.GetPoint() ...
}
// example of code generating the event:
void MyWindow::SendEvent()
{
MyPlotEvent event(myEVT_PLOT_CLICKED, GetId(), wxPoint(...));
event.SetEventObject(this);
ProcessWindowEvent(event);
}
@endcode
@section overview_events_misc Miscellaneous Notes
@subsection overview_events_virtual Event Handlers vs Virtual Methods
It may be noted that wxWidgets' event processing system implements something
close to virtual methods in normal C++ in spirit: both of these mechanisms
allow you to alter the behaviour of the base class by defining the event handling
functions in the derived classes.
There is however an important difference between the two mechanisms when you
want to invoke the default behaviour, as implemented by the base class, from a
derived class handler. With the virtual functions, you need to call the base
class function directly and you can do it either in the beginning of the
derived class handler function (to post-process the event) or at its end (to
pre-process the event). With the event handlers, you only have the option of
pre-processing the events and in order to still let the default behaviour
happen you must call wxEvent::Skip() and @em not call the base class event
handler directly. In fact, the event handler probably doesn't even exist in the
base class as the default behaviour is often implemented in platform-specific
code by the underlying toolkit or OS itself. But even if it does exist at
wxWidgets level, it should never be called directly as the event handlers are
not part of wxWidgets API and should never be called directly.
@subsection overview_events_prog User Generated Events vs Programmatically Generated Events
While generically wxEvents can be generated both by user
actions (e.g., resize of a wxWindow) and by calls to functions
(e.g., wxWindow::SetSize), wxWidgets controls normally send wxCommandEvent-derived
events only for the user-generated events. The only @b exceptions to this rule are:
@li wxNotebook::AddPage: No event-free alternatives
@li wxNotebook::AdvanceSelection: No event-free alternatives
@li wxNotebook::DeletePage: No event-free alternatives
@li wxNotebook::SetSelection: Use wxNotebook::ChangeSelection instead, as
wxNotebook::SetSelection is deprecated
@li wxTreeCtrl::Delete: No event-free alternatives
@li wxTreeCtrl::DeleteAllItems: No event-free alternatives
@li wxTreeCtrl::EditLabel: No event-free alternatives
@li All wxTextCtrl methods
wxTextCtrl::ChangeValue can be used instead of wxTextCtrl::SetValue but the other
functions, such as wxTextCtrl::Replace or wxTextCtrl::WriteText don't have event-free
equivalents.
@subsection overview_events_pluggable Pluggable Event Handlers
<em>TODO: Probably deprecated, Bind() provides a better way to do this</em>
In fact, you don't have to derive a new class from a window class
if you don't want to. You can derive a new class from wxEvtHandler instead,
defining the appropriate event table, and then call wxWindow::SetEventHandler
(or, preferably, wxWindow::PushEventHandler) to make this
event handler the object that responds to events. This way, you can avoid
a lot of class derivation, and use instances of the same event handler class (but different
objects as the same event handler object shouldn't be used more than once) to
handle events from instances of different widget classes.
If you ever have to call a window's event handler
manually, use the GetEventHandler function to retrieve the window's event handler and use that
to call the member function. By default, GetEventHandler returns a pointer to the window itself
unless an application has redirected event handling using SetEventHandler or PushEventHandler.
One use of PushEventHandler is to temporarily or permanently change the
behaviour of the GUI. For example, you might want to invoke a dialog editor
in your application that changes aspects of dialog boxes. You can
grab all the input for an existing dialog box, and edit it 'in situ',
before restoring its behaviour to normal. So even if the application
has derived new classes to customize behaviour, your utility can indulge
in a spot of body-snatching. It could be a useful technique for on-line
tutorials, too, where you take a user through a serious of steps and
don't want them to diverge from the lesson. Here, you can examine the events
coming from buttons and windows, and if acceptable, pass them through to
the original event handler. Use PushEventHandler/PopEventHandler
to form a chain of event handlers, where each handler processes a different
range of events independently from the other handlers.
@subsection overview_events_winid Window Identifiers
Window identifiers are integers, and are used to
uniquely determine window identity in the event system (though you can use it
for other purposes). In fact, identifiers do not need to be unique
across your entire application as long they are unique within the
particular context you're interested in, such as a frame and its children. You
may use the @c wxID_OK identifier, for example, on any number of dialogs
as long as you don't have several within the same dialog.
If you pass @c wxID_ANY to a window constructor, an identifier will be
generated for you automatically by wxWidgets. This is useful when you don't
care about the exact identifier either because you're not going to process the
events from the control being created or because you process the events
from all controls in one place (in which case you should specify @c wxID_ANY
in the event table or wxEvtHandler::Bind call
as well). The automatically generated identifiers are always negative and so
will never conflict with the user-specified identifiers which must be always
positive.
See @ref page_stdevtid for the list of standard identifiers available.
You can use wxID_HIGHEST to determine the number above which it is safe to
define your own identifiers. Or, you can use identifiers below wxID_LOWEST.
@subsection overview_events_with_mouse_capture Event Handlers and Mouse Capture
Some events are generated in response to a user action performed using the
mouse and, often, the mouse will be captured (see wxWindow::CaptureMouse()) by
the window generating the event in this case. This happens when the user is
dragging the mouse, i.e. for all events involving resizing something (e.g. @c
EVT_SPLITTER_SASH_POS_CHANGING), but also, perhaps less obviously, when
selecting items (e.g. @c EVT_LIST_ITEM_SELECTED).
When the mouse is captured, the control sending events will continue receiving
all mouse events, meaning that the event handler can't do anything relying on
getting them in any other window. Most notably, simply showing a modal dialog
won't work as expected, as the dialog won't receive any mouse input and appear
unresponsive to the user.
The best solution is to avoid showing modal dialogs from such event handlers
entirely, as it can be jarring for the user to be interrupted in their workflow
by a dialog suddenly popping up. However if it's really indispensable to show a
dialog, you need to forcefully break the existing mouse capture by capturing
(and then releasing, because you don't really need the capture) it yourself:
@code
dialog.CaptureMouse();
dialog.ReleaseMouse();
@endcode
@subsection overview_events_custom_generic Generic Event Table Macros
@beginTable
@row2col{EVT_CUSTOM(event\, id\, func),
Allows you to add a custom event table
entry by specifying the event identifier (such as wxEVT_SIZE),
the window identifier, and a member function to call.}
@row2col{EVT_CUSTOM_RANGE(event\, id1\, id2\, func),
The same as EVT_CUSTOM, but responds to a range of window identifiers.}
@row2col{EVT_COMMAND(id\, event\, func),
The same as EVT_CUSTOM, but expects a member function with a
wxCommandEvent argument.}
@row2col{EVT_COMMAND_RANGE(id1\, id2\, event\, func),
The same as EVT_CUSTOM_RANGE, but
expects a member function with a wxCommandEvent argument.}
@row2col{EVT_NOTIFY(event\, id\, func),
The same as EVT_CUSTOM, but
expects a member function with a wxNotifyEvent argument.}
@row2col{EVT_NOTIFY_RANGE(event\, id1\, id2\, func),
The same as EVT_CUSTOM_RANGE, but
expects a member function with a wxNotifyEvent argument.}
@endTable
@subsection overview_events_list List of wxWidgets Events
For the full list of event classes, please see the
@ref group_class_events "event classes group page".
*/

View File

@@ -0,0 +1,110 @@
/////////////////////////////////////////////////////////////////////////////
// Name: exceptions.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_exceptions C++ Exceptions
@tableofcontents
wxWidgets had been started long before the exceptions were introduced in C++ so
it is not very surprising that it is not built around using them, i.e.
the library doesn't throw exceptions to signal about the errors.
However it is exception-friendly. This means that while the library doesn't
use the exceptions by itself, it should be now safe to use the exceptions in
the user code and the library tries to help you with this.
@section overview_exceptions_strategies Strategies for Exception Handling
There are several choice for using the exceptions in wxWidgets programs. First
of all, you may not use them at all. As stated above, the library doesn't throw
any exceptions by itself and so you don't have to worry about exceptions at all
unless your own code throws them. This is, of course, the simplest solution but
may be not the best one to deal with all possible errors.
The next simplest strategy is to only use exceptions inside non-GUI code, i.e.
never let unhandled exceptions escape the event handler in which it happened.
In this case using exceptions in wxWidgets programs is not different from using
them in any other C++ program.
Things get more interesting if you decide to let (at least some) exceptions
escape from the event handler in which they occurred. Such exceptions will be
caught by wxWidgets and the special wxApp::OnExceptionInMainLoop() method will
be called from the @c catch clause. This allows you to decide in a single place
what to do about such exceptions: you may want to handle the exception somehow
or terminate the program. In this sense, OnExceptionInMainLoop() is equivalent
to putting a @c try/catch block around the entire @c main() function body in
the traditional console programs. However notice that, as its name indicates,
this method won't help you with the exceptions thrown before the main loop is
started or after it is over, so you may still want to have @c try/catch in your
overridden wxApp::OnInit() and wxApp::OnExit() methods too, otherwise
wxApp::OnUnhandledException() will be called.
Finally, notice that even if you decide to not let any exceptions escape in
this way, this still may happen unexpectedly in a program using exceptions as a
result of a bug. So consider always overriding OnExceptionInMainLoop() in your
wxApp-derived class if you use exceptions in your program, whether you expect
it to be called or not. In the latter case you may simple re-throw the
exception and let it bubble up to OnUnhandledException() as well.
To summarize, when you use exceptions in your code, you may handle them in the
following places, in order of priority:
-# In a @c try/catch block inside an event handler.
-# In wxApp::OnExceptionInMainLoop().
-# In wxApp::OnUnhandledException().
In the first two cases you may decide whether you want to handle the exception
and continue execution or to exit the program. In the last one the program is
about to exit already so you can just try to save any unsaved data and notify
the user about the problem (while being careful not to throw any more
exceptions as otherwise @c std::terminate() will be called).
@section overview_exceptions_store_rethrow Handling Exception Inside wxYield()
In some, relatively rare cases, using wxApp::OnExceptionInMainLoop() may not
be sufficiently flexible. The most common example is using automated GUI tests,
when test failures are signaled by throwing an exception and these exceptions
can't be caught in a single central method because their handling depends on
the test logic, e.g. sometimes an exception is expected while at other times it
is an actual error. Typically this results in writing code like the following:
@code
void TestNewDocument()
{
wxUIActionSimulator ui;
ui.Char('n', wxMOD_CONTROL); // simulate creating a new file
// Let wxWidgets dispatch Ctrl+N event, invoke the handler and create the
// new document.
try {
wxYield();
} catch ( ... ) {
// Handle exceptions as failure in the new document creation test.
}
}
@endcode
@section overview_exceptions_tech Technicalities
To use any kind of exception support in the library you need to build it
with @c wxUSE_EXCEPTIONS set to 1. It is turned on by default but you may
wish to check @c include/wx/msw/setup.h file under Windows or run @c configure
with explicit @c \--enable-exceptions argument under Unix.
On the other hand, if you do not plan to use exceptions, setting this
flag to 0 or using @c \--disable-exceptions could result in a leaner and
slightly faster library.
As for any other library feature, there is a sample (@c except)
showing how to use it. Please look at its sources for further information.
*/

View File

@@ -0,0 +1,40 @@
/////////////////////////////////////////////////////////////////////////////
// Name: file.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_file File Classes and Functions
@tableofcontents
wxWidgets provides some functions and classes to facilitate working with files.
As usual, the accent is put on cross-platform features which explains, for
example, the wxTextFile class which may be used to convert
between different types of text files (DOS/Unix/Mac).
wxFile may be used for low-level IO. It contains all the usual functions to work
with files (opening/closing, reading/writing, seeking, and so on) but compared with
using standard C functions, has error checking (in case of an error a message
is logged using wxLog facilities) and closes the file
automatically in the destructor which may be quite convenient.
wxTempFile is a very small file designed to make replacing the files contents
safer - see its documentation for more details.
wxTextFile is a general purpose class for working with small text files on line
by line basis. It is especially well suited for working with configuration files
and program source files. It can be also used to work with files with "non
native" line termination characters and write them as "native" files if needed
(in fact, the files may be written in any format).
wxDir is a helper class for enumerating the files or subdirectories of a
directory. It may be used to enumerate all files, only files satisfying the
given template mask or only non-hidden files.
@see wxFile, wxDir, wxTempFile, wxTextFile, @ref group_funcmacro_file
*/

View File

@@ -0,0 +1,113 @@
/////////////////////////////////////////////////////////////////////////////
// Name: filesystem.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_fs wxFileSystem Overview
@tableofcontents
The wxHTML library uses a @b virtual file system mechanism similar to the one
used in Midnight Commander, Dos Navigator, FAR or almost any modern file
manager. It allows the user to access data stored in archives as if they were
ordinary files. On-the-fly generated files that exist only in memory are also
supported.
@section overview_fs_classes Classes
Three classes are used in order to provide virtual file systems mechanism:
@li The wxFSFile class provides information
about opened file (name, input stream, mime type and anchor).
@li The wxFileSystem class is the interface.
Its main methods are ChangePathTo() and OpenFile(). This class
is most often used by the end user.
@li The wxFileSystemHandler is the core
of virtual file systems mechanism. You can derive your own handler and pass
it to the VFS mechanism. You can derive your own handler and pass it to
wxFileSystem's AddHandler() method. In the new handler you only need to
override the OpenFile() and CanOpen() methods.
@section overview_fs_locations Locations
Locations (aka filenames aka addresses) are constructed from four parts:
@li @b protocol - handler can recognize if it is able to open a
file by checking its protocol. Examples are "http", "file" or "ftp".
@li <b>right location</b> - is the name of file within the protocol.
In "https://www.wxwidgets.org/index.html" the right location is
"//www.wxwidgets.org/index.html".
@li @b anchor - an anchor is optional and is usually not present.
In "index.htm#chapter2" the anchor is "chapter2".
@li <b>left location</b> - this is usually an empty string.
It is used by 'local' protocols such as ZIP.
See Combined Protocols paragraph for details.
@section overview_fs_combined Combined Protocols
The left location precedes the protocol in the URL string.
It is not used by global protocols like HTTP but it becomes handy when nesting
protocols - for example you may want to access files in a ZIP archive:
file:archives/cpp_doc.zip#zip:reference/fopen.htm#syntax
In this example, the protocol is "zip", right location is
"reference/fopen.htm", anchor is "syntax" and left location
is "file:archives/cpp_doc.zip".
There are @b two protocols used in this example: "zip" and "file".
@section overview_fs_wxhtmlfs File Systems Included in wxHTML
The following virtual file system handlers are part of wxWidgets so far:
@li @b wxArchiveFSHandler:
A handler for archives such as zip
and tar. Include file is wx/fs_arc.h. URLs examples:
"archive.zip#zip:filename", "archive.tar.gz#gzip:#tar:filename".
@li @b wxDataSchemeFSHandler:
A handler for accessing data inlined in URI according to RFC 2397.
URI example: "data:text/plain;base64,d3hXaWRnZXRzIGV4YW1wbGU=".
Include file is wx/fs_data.h.
@li @b wxFilterFSHandler:
A handler for compression schemes such
as gzip. Header is wx/fs_filter.h. URLs are in the form, e.g.:
"document.ps.gz#gzip:".
@li @b wxInternetFSHandler:
A handler for accessing documents
via HTTP or FTP protocols. Include file is wx/fs_inet.h.
@li @b wxMemoryFSHandler:
This handler allows you to access
data stored in memory (such as bitmaps) as if they were regular files.
See wxMemoryFSHandler for details.
Include file is wx/fs_mem.h. URL is prefixed with memory:, e.g.
"memory:myfile.htm"
In addition, wxFileSystem itself can access local files.
@section overview_fs_init Initializing file system handlers
Use wxFileSystem::AddHandler to initialize a handler, for example:
@code
#include <wx/fs_mem.h>
...
bool MyApp::OnInit()
{
wxFileSystem::AddHandler(new wxMemoryFSHandler);
...
}
@endcode
*/

View File

@@ -0,0 +1,90 @@
/////////////////////////////////////////////////////////////////////////////
// Name: font.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_font wxFont Overview
@tableofcontents
A font is an object which determines the appearance of text, primarily when
drawing text to a window or device context. A font is determined by the
following parameters (not all of them have to be specified, of course):
@beginDefList
@itemdef{Point size, This is the standard way of referring to text size.}
@itemdef{Family,
Supported families are:
@b wxDEFAULT, @b wxDECORATIVE, @b wxROMAN, @b wxSCRIPT, @b wxSWISS, @b wxMODERN.
@b wxMODERN is a fixed pitch font; the others are either fixed or variable pitch.}
@itemdef{Style, The value can be @b wxNORMAL, @b wxSLANT or @b wxITALIC.}
@itemdef{Weight, The value can be @b wxNORMAL, @b wxLIGHT or @b wxBOLD.}
@itemdef{Underlining, The value can be @true or @false.}
@itemdef{Face name,
An optional string specifying the actual typeface to be used. If @NULL,
a default typeface will chosen based on the family.}
@itemdef{Encoding,
The font encoding (see @b wxFONTENCODING_XXX
constants and the @ref overview_fontencoding for more details)}
@endDefList
Specifying a family, rather than a specific typeface name, ensures a degree of
portability across platforms because a suitable font will be chosen for the
given font family, however it doesn't allow to choose a font precisely as the
parameters above don't suffice, in general, to identify all the available fonts
and this is where using the native font descriptions may be helpful - see
below.
Under Windows, the face name can be one of the installed fonts on the user's
system. Since the choice of fonts differs from system to system, either choose
standard Windows fonts, or if allowing the user to specify a face name, store
the family name with any file that might be transported to a different Windows
machine or other platform.
@see wxFont, wxFontDialog
@note There is currently a difference between the appearance of fonts on the
two platforms, if the mapping mode is anything other than wxMM_TEXT.
Under X, font size is always specified in points. Under MS Windows, the
unit for text is points but the text is scaled according to the current
mapping mode. However, user scaling on a device context will also scale
fonts under both environments.
@section overview_font_nativeinfo Native Font Information
An alternative way of choosing fonts is to use the native font description.
This is the only acceptable solution if the user is allowed to choose the font
using the wxFontDialog because the selected font cannot
be described using only the family name and so, if only family name is stored
permanently, the user would almost surely see a different font in the program
later.
Instead, you should store the value returned by wxFont::GetNativeFontInfoDesc and pass
it to wxFont::SetNativeFontInfo later to recreate exactly the same font.
Note that the contents of this string depends on the platform and shouldn't be
used for any other purpose (in particular, it is not meant to be shown to the
user). Also please note that although the native font information is currently
implemented for Windows and Unix (GTK and X11) ports only, all the methods
are available for all the ports and should be used to make your program work
correctly when they are implemented later.
@section overview_font_privateinfo Private font information
Sometimes an application needs fonts that are not globally installed on the
system. On Macintosh/OSX this can be arranged by placing the desired fonts
within the Application Bundle in Contents/Resources/Fonts and using
the ATSApplicationFontsPath key to point there. The full details of the
procedure there can be found as OSX developer resources. For the GTK+ and
Windows ports it is possible to add TrueType fonts from arbitrary locations at
run-time using wxFont::AddPrivateFont(). Notice that under MSW this function
should be called before creating the first wxGraphicsContext object if you want
the private font to be usable from it.
*/

View File

@@ -0,0 +1,84 @@
/////////////////////////////////////////////////////////////////////////////
// Name: fontencoding.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_fontencoding Font Encodings
@tableofcontents
wxWidgets has support for multiple font encodings.
By encoding we mean here the mapping between the character codes and the
letters. Probably the most well-known encoding is (7 bit) ASCII one which is
used almost universally now to represent the letters of the English alphabet
and some other common characters. However, it is not enough to represent the
letters of foreign alphabets and here other encodings come into play. Please
note that we will only discuss 8-bit fonts here and not Unicode
(see @ref overview_unicode).
Font encoding support is ensured by several classes: wxFont itself, but also
wxFontEnumerator and wxFontMapper. wxFont encoding support is reflected by a
(new) constructor parameter @e encoding which takes one of the following values
(elements of enumeration type @c wxFontEncoding):
@beginDefList
@itemdef{wxFONTENCODING_SYSTEM,
The default encoding of the underlying operating system.}
@itemdef{wxFONTENCODING_DEFAULT,
The applications default encoding as returned by wxFont::GetDefaultEncoding.
On program startup, the applications default encoding is the same as
wxFONTENCODING_SYSTEM, but may be changed to make all the fonts created later
to use it (by default).}
@itemdef{wxFONTENCODING_ISO8859_1..15,
ISO8859 family encodings which are
usually used by all non-Microsoft operating systems.}
@itemdef{wxFONTENCODING_KOI8,
Standard Cyrillic encoding for the Internet
(but see also wxFONTENCODING_ISO8859_5 and wxFONTENCODING_CP1251).}
@itemdef{wxFONTENCODING_CP1250, Microsoft analogue of ISO8859-2}
@itemdef{wxFONTENCODING_CP1251, Microsoft analogue of ISO8859-5}
@itemdef{wxFONTENCODING_CP1252, Microsoft analogue of ISO8859-1}
@endDefList
As you may see, Microsoft's encoding partly mirror the standard ISO8859 ones,
but there are (minor) differences even between ISO8859-1 (Latin1, ISO encoding
for Western Europe) and CP1251 (WinLatin1, standard code page for English
versions of Windows) and there are more of them for other encodings.
The situation is particularly complicated with Cyrillic encodings for which
(more than) three incompatible encodings exist: KOI8 (the old standard, widely
used on the Internet), ISO8859-5 (ISO standard for Cyrillic) and CP1251
(WinCyrillic).
This abundance of (incompatible) encodings should make it clear that using
encodings is less easy than it might seem. The problems arise both from the
fact that the standard encodings for the given language (say Russian, which is
written in Cyrillic) are different on different platforms and because the
fonts in the given encoding might just not be installed (this is especially a
problem with Unix, or, in general, non-Win32 systems).
To clarify, the wxFontEnumerator class may be used to enumerate both all
available encodings and to find the facename(s) in which the given encoding
exists. If you can find the font in the correct encoding with wxFontEnumerator
then your troubles are over, but, unfortunately, sometimes this is not enough.
For example, there is no standard way (that I know of, please tell me if you
do!) to find a font on a Windows system for KOI8 encoding (only for WinCyrillic
one which is quite different), so wxFontEnumerator will never return one, even
if the user has installed a KOI8 font on his system.
To solve this problem, a wxFontMapper class is provided.
This class stores the mapping between the encodings and the font face names
which support them in wxConfigBase object. Of course, it would be fairly
useless if it tried to determine these mappings by itself, so, instead, it
(optionally) asks the user and remembers his answers so that the next time the
program will automatically choose the correct font. All these topics are
illustrated by the @ref page_samples_font; please refer to it and the
documentation of the classes mentioned here for further explanations.
*/

View File

@@ -0,0 +1,136 @@
/////////////////////////////////////////////////////////////////////////////
// Name: grid.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_grid wxGrid Overview
@tableofcontents
wxGrid and its related classes are used for displaying and editing tabular
data. wxGrid supports custom attributes for the table cells, allowing to
completely customize its appearance and uses a separate grid table
(wxGridTableBase-derived) class for the data management meaning that it can be
used to display arbitrary amounts of data.
@section overview_grid_simpleexample Getting Started
For simple applications you need only refer to the wxGrid class in your code.
This example shows how you might create a grid in a frame or dialog constructor
and illustrates some of the formatting functions.
@code
// Create a wxGrid object
grid = new wxGrid( this,
-1,
wxPoint( 0, 0 ),
wxSize( 400, 300 ) );
// Then we call CreateGrid to set the dimensions of the grid
// (100 rows and 10 columns in this example)
grid->CreateGrid( 100, 10 );
// We can set the sizes of individual rows and columns
// in pixels
grid->SetRowSize( 0, 60 );
grid->SetColSize( 0, 120 );
// And set grid cell contents as strings
grid->SetCellValue( 0, 0, "wxGrid is good" );
// We can specify that some cells are read->only
grid->SetCellValue( 0, 3, "This is read->only" );
grid->SetReadOnly( 0, 3 );
// Colours can be specified for grid cell contents
grid->SetCellValue(3, 3, "green on grey");
grid->SetCellTextColour(3, 3, *wxGREEN);
grid->SetCellBackgroundColour(3, 3, *wxLIGHT_GREY);
// We can specify the some cells will store numeric
// values rather than strings. Here we set grid column 5
// to hold floating point values displayed with width of 6
// and precision of 2
grid->SetColFormatFloat(5, 6, 2);
grid->SetCellValue(0, 6, "3.1415");
@endcode
Here is a list of classes related to wxGrid:
@li wxGrid: The main grid control class itself.
@li wxGridTableBase: The base class for grid data provider.
@li wxGridStringTable: Simple wxGridTableBase implementation supporting only
string data items and storing them all in memory (hence suitable for not
too large grids only).
@li wxGridCellAttr: A cell attribute, allowing to customize its appearance as
well as the renderer and editor used for displaying and editing it.
@li wxGridCellAttrProvider: The object responsible for storing and retrieving
the cell attributes.
@li wxGridColLabelWindow: The window showing the grid columns labels.
@li wxGridRowLabelWindow: The window showing the grid rows labels.
@li wxGridCornerLabelWindow: The window used in the upper left grid corner.
@li wxGridWindow: The window representing the main part of the grid.
@li wxGridCellRenderer: Base class for objects used to display a cell value.
@li wxGridCellStringRenderer: Renderer showing the cell as a text string.
@li wxGridCellNumberRenderer: Renderer showing the cell as an integer number.
@li wxGridCellFloatRenderer: Renderer showing the cell as a floating point
number.
@li wxGridCellBoolRenderer: Renderer showing the cell as checked or unchecked
box.
@li wxGridCellDateRenderer: Renderer showing the cell as date.
@li wxGridCellEditor: Base class for objects used to edit the cell value.
@li wxGridCellStringEditor: Editor for cells containing text strings.
@li wxGridCellNumberEditor: Editor for cells containing integer numbers.
@li wxGridCellFloatEditor: Editor for cells containing floating point numbers.
@li wxGridCellBoolEditor: Editor for boolean-valued cells.
@li wxGridCellChoiceEditor: Editor allowing to choose one of the predefined
strings (and possibly enter new one).
@li wxGridCellDateEditor: Editor for cells containing dates without time component.
@li wxGridEvent: The event sent by most of wxGrid actions.
@li wxGridSizeEvent: The special event sent when a grid column or row is
resized.
@li wxGridRangeSelectEvent: The special event sent when a range of cells is
selected in the grid.
@li wxGridEditorCreatedEvent: The special event sent when a cell editor is
created.
@li wxGridSelection: The object efficiently representing the grid selection.
@li wxGridTypeRegistry: Contains information about the data types supported by
the grid.
@section overview_grid_resizing Column and Row Sizes
@b NB: This section will discuss the resizing of wxGrid rows only to avoid
repetitions but everything in it also applies to grid columns, just replace @c
Row in the method names with @c Col.
Initially all wxGrid rows have the same height, which can be modified for all
of them at once using wxGrid::SetDefaultRowSize(). However, unlike simpler
controls such as wxListBox or wxListCtrl, wxGrid also allows its rows to be
individually resized to have their own height using wxGrid::SetRowSize() (as a
special case, a row may be hidden entirely by setting its size to 0, which is
done by a helper wxGrid::HideRow() method). It is also possible to resize a row
to fit its contents with wxGrid::AutoSizeRow() or do it for all rows at once
with wxGrid::AutoSizeRows().
Additionally, by default the user can also drag the row separator lines to
resize the rows interactively. This can be forbidden completely by calling
wxGrid::DisableDragRowSize() or just for the individual rows using
wxGrid::DisableRowResize().
If you do allow the user to resize the grid rows, it may be a good idea to save
their heights and restore it when the grid is recreated the next time (possibly
during a next program execution): the functions wxGrid::GetRowSizes() and
wxGrid::SetRowSizes() can help with this, you will just need to serialize
wxGridSizesInfo structure returned by the former in some way and deserialize it
back before calling the latter.
*/

View File

@@ -0,0 +1,331 @@
/////////////////////////////////////////////////////////////////////////////
// Name: helloworld.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_helloworld Hello World Example
@tableofcontents
This page shows a very simple wxWidgets program that can be used as a skeleton
for your own code.
@note Creating the UI entirely from C++ code is fine for a simple example, but
more realistic programs can find it more convenient to define their UI at least
partially in @ref overview_xrc "XRC resource files".
While this program does nothing very useful, it introduces a couple of
important concepts and explains how to write a working wxWidgets application.
Trying building and running this application is also a good way of checking
that wxWidgets is correctly installed on your system. And if you haven't
installed wxWidgets yet, please @ref overview_install "do it first".
Without further ado, let's write our first application.
First, you have to include wxWidgets' header files, of course. This can be done
on a file by file basis (such as @c wx/frame.h) or using one global include
(@c wx/wx.h) which includes most of the commonly needed headers (although not
all of them as there are simply too many wxWidgets headers to pull in all of
them).
@code
// Start of wxWidgets "Hello World" Program
#include <wx/wx.h>
@endcode
Execution of a "classic" C++ program starts in its `main()` function (putting
aside the constructors of the global objects), but GUI applications must use a
different "entry function" on some platforms (such as `WinMain()` used under
Microsoft Windows). wxWidgets provides a convenient ::wxIMPLEMENT_APP() macro,
which allows to define the appropriate entry function on all platforms. Please
note that you can avoid using macros if you're so inclined by defining your own
entry function and using wxInitializer class for the library initialization,
but this example won't do it for brevity and simplicity.
This macro takes a single parameter which is the name of the application class,
that must be defined in the program. This class must derive from wxApp and,
at the very least, override wxApp::OnInit() virtual function, as it will be
called by wxWidgets to initialize the application. Let's do this:
@code
class MyApp : public wxApp
{
public:
bool OnInit() override;
};
// This defines the equivalent of main() for the current platform.
wxIMPLEMENT_APP(MyApp);
@endcode
The main window of a typical application is a wxFrame object. While it's
possible to just use this class directly, it's usually more convenient to
derive a custom class from it, as this allows to store additional data and
handle events (such as mouse clicks, messages from the menu, or a button) in
the methods of this class — allowing them to access this data easily.
So, even if we don't have any data in this toy example, let's define such a
custom class with a few "event handlers", i.e. functions taking the @c event
parameter of the type corresponding to the event being handled, which is
wxCommandEvent for the events from simple controls such as buttons, text fields
and also menu items. In our example, we react to three menu items: our custom
"Hello", and the "Exit" and "About" items (any program should normally
implement the latter two). Notice that these handlers don't need to be virtual
or public.
@code
class MyFrame : public wxFrame
{
public:
MyFrame();
private:
void OnHello(wxCommandEvent& event);
void OnExit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
};
@endcode
Now that we have this class, we can implement `OnInit()` which, as you
remember, is called upon application startup and simply create the main
window, represented by this class, in it:
@code
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame();
frame->Show();
return true;
}
@endcode
Please note the following points:
- Contrary to appearances, there is no memory leak in this example:
wxWidgets takes ownership of all the window objects and destroys them
automatically when the corresponding on-screen window is destroyed. For
the frames (i.e. top-level windows) this happens when the user closes it.
For the other windows, it happens when their parent is destroyed. But,
generally speaking, all windows are owned by the framework and must @b not
be deleted by the application.
- Frames, unlike all the other windows, are created hidden by default in
order to allow filling them with their contents before showing everything
at once. Please don't forget to call `Show()` to make this happen.
- Returning @true from `OnInit()` allows the application to start running.
By default, it will exit once all top-level windows have been closed (but
see wxApp::SetExitOnFrameDelete()), so this function should normally
create at least one window (but can, of course, create more than one).
Otherwise it can just return @false to exit immediately instead.
In the constructor of the main window, we create a menu with our
menu items, as well as a status bar to be shown at the bottom of the main
window.
In order to be able to react to a menu command, it must be given a unique
identifier which can be defined as a constant or an enum element. The
latter is often used because typically many such constants will be needed:
@code
enum
{
ID_Hello = 1
};
@endcode
Notice that you don't need to define identifiers for "About" and "Exit", as
wxWidgets already predefines standard values such as ::wxID_ABOUT and
::wxID_EXIT (see @ref page_stockitems for the full list). You should use
these whenever possible, as they can be handled in a special way by a
particular platform and also have predefined labels associated with them,
which allows us to omit them when appending the corresponding menu items.
For our custom item, we specify the label, also containing an accelerator,
separated by `Tab` from the label itself, allowing to invoke this command
from keyboard:
@code
MyFrame::MyFrame()
: wxFrame(nullptr, wxID_ANY, "Hello World")
{
wxMenu *menuFile = new wxMenu;
menuFile->Append(ID_Hello, "&Hello...\tCtrl+H",
"Help string shown in status bar for this menu item");
menuFile->AppendSeparator();
menuFile->Append(wxID_EXIT);
wxMenu *menuHelp = new wxMenu;
menuHelp->Append(wxID_ABOUT);
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(menuFile, "&File");
menuBar->Append(menuHelp, "&Help");
SetMenuBar(menuBar);
CreateStatusBar();
SetStatusText("Welcome to wxWidgets!");
... continued below ...
@endcode
Note that, as with the windows, menu pointers don't need to (and, in fact,
must not) be destroyed because they are owned by the menu bar, which is
itself owned by the frame, which is owned, i.e. will be destroyed, by
wxWidgets.
We also have to connect our event handlers to the events we want to handle in
them. We do this by calling Bind() to send all the menu events (identified by
wxEVT_MENU event type) with the specified ID to the given function. The
parameters we pass to Bind() are
-# The event type, e.g. wxEVT_MENU, wxEVT_BUTTON, wxEVT_SIZE, or one
of many other events used by wxWidgets.
-# A pointer to the method to call, and the object to call it on. In
this case, we just call our own function, and pass the `this` pointer
for the object itself. We could instead call the method of another object,
or a non-member function — in fact, any object that can be called with a
wxCommandEvent, can be used here.
-# An optional identifier, allowing us to select just some events of wxEVT_MENU
type, namely those from the menu item with the given ID, instead of handling
all of them in the provided handler. This is mainly useful with menu items
and rarely with other kinds of events.
@code
... continued from above ...
Bind(wxEVT_MENU, &MyFrame::OnHello, this, ID_Hello);
Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT);
Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT);
}
@endcode
Here are the standard event handlers implementations. MyFrame::OnExit() closes
the main window by calling Close(). The parameter @true indicates that other
windows have no veto power such as after asking "Do you really want to close?".
If there is no other main window left, the application will quit.
@code
void MyFrame::OnExit(wxCommandEvent& event)
{
Close(true);
}
@endcode
MyFrame::OnAbout() will display a small window with some text in it. In this
case a typical "About" window with information about the program.
@code
void MyFrame::OnAbout(wxCommandEvent& event)
{
wxMessageBox("This is a wxWidgets Hello World example",
"About Hello World", wxOK | wxICON_INFORMATION);
}
@endcode
The implementation of custom menu command handler may perform whatever task
your program needs to do, in this case we will simply show a message from it as
befits a Hello World example:
@code
void MyFrame::OnHello(wxCommandEvent& event)
{
wxLogMessage("Hello world from wxWidgets!");
}
@endcode
@note It can be convenient to use unnamed lambdas instead of functions for
event handlers, especially for such short functions. Here, for example,
we could replace the handler above with just
@code
Bind(wxEVT_MENU, [=](wxCommandEvent&) { wxLogMessage("Hello from a lambda!"); }, ID_Hello);
@endcode
Here is the entire program that can be copied and pasted:
@code
// Start of wxWidgets "Hello World" Program
#include <wx/wx.h>
class MyApp : public wxApp
{
public:
bool OnInit() override;
};
wxIMPLEMENT_APP(MyApp);
class MyFrame : public wxFrame
{
public:
MyFrame();
private:
void OnHello(wxCommandEvent& event);
void OnExit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
};
enum
{
ID_Hello = 1
};
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame();
frame->Show(true);
return true;
}
MyFrame::MyFrame()
: wxFrame(nullptr, wxID_ANY, "Hello World")
{
wxMenu *menuFile = new wxMenu;
menuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
"Help string shown in status bar for this menu item");
menuFile->AppendSeparator();
menuFile->Append(wxID_EXIT);
wxMenu *menuHelp = new wxMenu;
menuHelp->Append(wxID_ABOUT);
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(menuFile, "&File");
menuBar->Append(menuHelp, "&Help");
SetMenuBar( menuBar );
CreateStatusBar();
SetStatusText("Welcome to wxWidgets!");
Bind(wxEVT_MENU, &MyFrame::OnHello, this, ID_Hello);
Bind(wxEVT_MENU, &MyFrame::OnAbout, this, wxID_ABOUT);
Bind(wxEVT_MENU, &MyFrame::OnExit, this, wxID_EXIT);
}
void MyFrame::OnExit(wxCommandEvent& event)
{
Close(true);
}
void MyFrame::OnAbout(wxCommandEvent& event)
{
wxMessageBox("This is a wxWidgets Hello World example",
"About Hello World", wxOK | wxICON_INFORMATION);
}
void MyFrame::OnHello(wxCommandEvent& event)
{
wxLogMessage("Hello world from wxWidgets!");
}
@endcode
*/

View File

@@ -0,0 +1,354 @@
High DPI Support in wxWidgets {#overview_high_dpi}
=============================
[TOC]
Introduction {#high_dpi_intro}
============
Many modern displays have way more pixels on the same surface than used to be
the norm, resulting in much higher values of DPI (dots, i.e. pixels, per inch)
than the traditionally used values. This allows to render texts, or geometric
shapes in general much more smoothly.
As an illustration here are two scaled up views of the same text in 11 pt
Helvetica using up the same space on screen. First on an original Mac display
at 72 dpi, then on a High DPI Display, called "Retina" by Apple with twice as
many pixels in both dimensions (144 dpi), thus 4 times the number of pixels on
the same surface. Using these the contours are much more detailed.
![11 pt Helvetica at 72 DPI](overview_highdpi_text_72.png)
![11 pt Helvetica at 144 DPI](overview_highdpi_text_144.png)
To the user the DPI is typically expressed using a scaling factor, by which the
baseline DPI value is multiplied. For example, MSW systems may use 125% or 150%
scaling, meaning that they use DPI of 120 or 144 respectively, as baseline DPI
value is 96. Similarly, Linux systems may use "2x" scaling, resulting in DPI
value of 192. Macs are slightly different, as even they also may use "2x"
scaling, as in the example above, the effective DPI corresponding to it is 144,
as the baseline value on this platform is 72.
The Problem with High DPI Displays
----------------------------------
If high DPI displays were treated in the same way as normal ones, existing
applications would look tiny of them. For example, a square window 500 pixels
in size would take half of a standard 1920×1080 ("Full HD") display vertically,
but only a quarter on a 3840×2160 ("4K UHD") display. To prevent this from
happening, most platforms automatically scale the windows by the scaling
factor, defined above, when displaying them on high DPI displays. In this
example, scaling factor is 2 and so the actual size of the window on screen
would become 1000 when automatic scaling is in effect.
Automatic scaling is convenient, but doesn't really allow the application to
use the extra pixels available on the display. Visually, this means that the
scaled application appears blurry, in contrast to sharper applications using
the full display resolution, so a better solution for interpreting pixel values
on high DPI displays is needed: one which allows to scale some pixel values
(e.g. the total window size), but not some other ones (e.g. those used for
drawing, which should remain unscaled to use the full available resolution).
Pixel Values in wxWidgets {#high_dpi_pixel_types}
=========================
Logical and Device-Independent Pixels {#high_dpi_lp_and_dip}
-------------------------------------
Some systems like eg Apple's OSes automatically scale all the coordinates by
the DPI scaling factor, however not all systems supported by wxWidgets do it --
notably, MSW does not. This means that **logical pixels**, in which all
coordinates and sizes are expressed in wxWidgets API, do _not_ have the same
meaning on all platforms when using high DPI displays. So while on macOS you
can always pass in a size of (500,500) to create the window from the previous
paragraph, whatever the resolution of the display is, you would have to
increase this to (1000,1000) on MSW when working on a 200% display. To hide
this difference from the application, wxWidgets provides **device-independent
pixels**, abbreviated as "DIP", that are always of the same size on all
displays and all platforms.
Thus, the first thing do when preparing your application for high DPI support
is to stop using raw pixel values, as they mean different things under
different platforms when DPI scaling is used. Actually, using any pixel values
is not recommended and replacing them with the values based on the text
metrics, i.e. obtained using wxWindow::GetTextExtent(), or expressing them in
dialog units (see wxWindow::ConvertDialogToPixels()) is preferable. However
the simplest change is to just replace the pixel values with the values in
DIP: for this, just use wxWindow::FromDIP() to convert from one to the other.
For example, if you have the existing code:
~~~{cpp}
myFrame->SetClientSize(wxSize(400, 300));
~~~
you can just replace it with
~~~{cpp}
myFrame->SetClientSize(myFrame->FromDIP(wxSize(400, 300)));
~~~
although replacing it with something like
~~~{cpp}
const wxSize sizeM = myFrame->GetTextExtent("M");
myFrame->SetClientSize(100*sizeM.x, 40*sizeM.y));
~~~
might be even better.
In any case, remember that window and wxDC or wxGraphicsContext coordinates
must be in logical pixels that can depend on the current DPI scaling, and so
should never be fixed at compilation time.
Physical Pixels {#high_dpi_pp}
---------------
In addition to (logical) pixels and DIPs discussed above, you may also need to
work in physical pixel coordinates, corresponding to the actual display pixels.
Physical pixels are never scaled, on any platform, and are used for the real
bitmap sizes. They are also used for drawing operations on wxGLCanvas, which
is _different_ from wxDC and wxGraphicsContext that use logical pixels.
Under MSW physical pixels are same as logical ones, but when writing portable
code you need to convert between logical and physical pixels. This can be done
using convenience wxWindow::FromPhys() and wxWindow::ToPhys() functions
similar to the DIP functions above or by directly multiplying or dividing by
wxWindow::GetContentScaleFactor(): this function returns a value greater than
or equal to 1 (and always just 1 under MSW), so a value in logical pixels
needs to be multiplied by it in order to obtain the value in physical pixels.
For example, in a wxGLCanvas created with the size of 100 (logical) pixels, the
rightmost physical pixel coordinate will be `100*GetContentScaleFactor()`
under all platforms.
You can convert from DIPs to physical pixels by converting DIPs to the logical
pixels first, but you can also do it directly, by using
wxWindow::GetDPIScaleFactor(). This function can return a value different from
1 even under MSW, i.e. it returns DPI scaling for physical display pixels.
**Warning:** It is possible that conversion between different pixel
coordinates is not lossless due to rounding. E.g. to create a window big
enough to show a bitmap 15 pixels wide, you need to use `FromPhys(15)`,
however the exact result of this function is not representable as an `int`
when using 200% DPI scaling. In this case, the value is always rounded
upwards, i.e. the function returns `8`, to ensure that a window of this size
in logical pixels is always big enough to show the bitmap, but this can only
be done at the price of having one "extra" pixel in the window.
Summary of Different Pixel Kinds {#high_dpi_pixel_conversions}
--------------------------------
Under MSW, logical pixels are always the same as physical pixels, but are
different from DIPs, while under all the other platforms with DPI scaling
support (currently only GTK 3 and macOS), logical pixels are the same as DIP,
but different from physical pixels.
However under all platforms the following functions can be used to convert
between different kinds of pixels:
* From DIP to logical pixels: use wxWindow::FromDIP() or wxWindow::ToDIP().
* From physical to logical pixels: use wxWindow::FromPhys() or wxWindow::ToPhys().
* From DIP to physical pixels: multiply or divide by wxWindow::GetDPIScaleFactor().
Or, in the diagram form:
@dot
digraph Pixels
{
node [shape = hexagon, style = filled, fontname = Helvetica];
LP [fillcolor = lightblue, label = "Logical\nPixels"];
DIP [fillcolor = yellow, label = "DI\nPixels"];
PP [fillcolor = green, label = "Physical\nPixels"];
LP -> PP [fontname = Helvetica, labeldistance = 5, labelangle = 30, dir = both, weight = 2, minlen = 3, headlabel = "ToPhys()", taillabel = "FromPhys()"];
LP -> DIP [fontname = Helvetica, labeldistance = 6, dir = both, weight = 2, minlen = 3, headlabel = "ToDIP()", taillabel = "FromDIP()"];
DIP -> PP [fontname = Helvetica, dir = both, minlen = 10, label = "GetDPIScaleFactor()" headlabel = "multiply by", taillabel = "divide by", constraint = false] ;
}
@enddot
Almost all functions in wxWidgets API take and return values expressed in
logical pixels. With the obvious exceptions of the functions that explicitly
use "Logical", "Physical" or "DIP" in their names, the only exceptions are:
- Size passed to wxBitmap constructors taking one, as well as the size returned
by wxBitmap::GetWidth() and wxBitmap::GetHeight() is in physical pixels. You
can use wxBitmap::CreateWithDIPSize() and wxBitmap::GetDIPSize() or
wxBitmap::GetLogicalSize() to use or get the size in DPI-independent or
logical pixels (notably, the latter must be used in any computations
involving the sizes expressed in logical units).
- Similarly, the size returned by wxBitmapBundle::GetPreferredBitmapSizeFor()
is in physical pixels, but wxBitmapBundle::GetPreferredLogicalSizeFor() can
be used to retrieve the same value in logical units.
- The default size of wxBitmapBundle, taken by wxBitmapBundle::FromSVG() and
returned by wxBitmapBundle::GetDefaultSize() is in DIPs.
High-Resolution Images and Artwork {#high_dpi_artwork}
==================================
In order to really benefit from the increased detail on High DPI devices you need
to provide the images or artwork your application uses in higher resolutions as
well. Note that it is not recommended to just provide a high-resolution version
and let the system scale that down on 1x displays. Apart from performance
consideration also the quality might suffer, contours become more blurry, so
for best results it is recommended to use the images that can be used without
scaling at the common DPI values, i.e. at least 100% and 200% scaling. If you
don't want providing several copies of all bitmaps, you can use a single
vector image in [SVG format][] instead.
[SVG format]: https://en.wikipedia.org/wiki/Scalable_Vector_Graphics
In either case, you must use wxBitmapBundle class representing several
different versions of the same bitmap (or even potentially just a single one,
which makes it upwards-compatible with wxBitmap). Most functions accepting
wxBitmap or wxImage in wxWidgets API have been updated to work with
wxBitmapBundle instead, which allows the library to select the appropriate
size depending on the current DPI and, for the platforms supporting it
(currently only MSW and macOS), even update the bitmap automatically if the
DPI changes, as can happen, for example, when the window showing the bitmap is
moved to another monitor with a different resolution.
Note that other than creating wxBitmapBundle instead of wxBitmap, no other
changes are needed. Moreover, when upgrading the existing code it is possible
to replace some wxBitmap objects by wxBitmapBundle while keeping the others.
Using Multiple Bitmaps {#high_dpi_bundle_bitmaps}
----------------------
When using multiple bitmaps, the simplest way to create a wxBitmapBundle is to
do it from a vector of bitmaps of different sizes. In the most common case of
just two bitmaps, a special constructor taking these bitmaps directly can be
used rather than having to construct a vector from them:
~~~{cpp}
wxBitmap normal(32, 32);
wxBitmap highDPI(64, 64);
... initialize the bitmaps somehow ...
wxBitmapBundle bundle = wxBitmapBundle::FromBitmaps(normal, highDPI);
// Now the bundle can be passed to any wxWidgets control using bitmaps.
~~~
For the platforms where it is common to embed bitmaps in the resources, it is
possible to use wxBitmapBundle::FromResources() to create a bundle containing
all bitmaps using the given base name, i.e. `foo` for the normal bitmap and
`foo_2x` for the bitmap for 200% scaling (for fractional values decimal
separator must be replaced with underscore, e.g. use `foo_1_5x` for the bitmap
to use 150% scaling).
It is also possible to create wxBitmapBundle from the files using the same
naming convention with wxBitmapBundle::FromFiles(). And, to abstract the
differences between the platforms using resources and the other ones, a helper
wxBITMAP_BUNDLE_2() macro which uses resources if possible or files otherwise
is provided, similar to wxBITMAP_PNG() macro for plain bitmaps.
Independently of the way in which the bundle was created, it will provide the
bitmap closest in size to the expected size at the current DPI, while trying
to avoid having scale it. This means that at 175% DPI scaling, for example,
the high DPI (i.e. double-sized) bitmap will be used _without_ scaling rather
than scaling it by 0.875, which almost certainly wouldn't look good. However
if the current DPI scaling is 300%, the 2x bitmap will be scaled, if it's the
closest one available, as using it without scaling would result in bitmaps too
small to use. The cut-off for the decision whether to scale bitmap or use an
existing one without scaling is the factor of 1.5: if the mismatch between the
required and closest available size is equal or greater than 1.5, the bitmap
will be scaled. Otherwise it will be used in its natural size.
If this behaviour is inappropriate for your application, it is also possible
to define a custom wxBitmapBundle implementation, see wxBitmapBundleImpl for
more details.
Using Vector Graphics {#high_dpi_bundle_vector}
---------------------
As an alternative to providing multiple versions of the bitmaps, it is
possible to use a single SVG image and create the bitmap bundle using either
wxBitmapBundle::FromSVG() or wxBitmapBundle::FromSVGFile(). Such bitmap
bundles will always produce bitmaps of exactly the required size, at any
resolution. At normal DPI, i.e. without any scaling, the size of the resulting
bitmap will be the default bundle size, which must be provided when creating
this kind of bitmap bundle, as SVG image itself doesn't necessarily contain
this information.
Note that wxWidgets currently uses [NanoSVG][] library for SVG support and so
doesn't support all SVG standard features and you may need to simplify or
tweak the SVG files to make them appear correctly.
[NanoSVG]: https://github.com/memononen/nanosvg
wxBitmapBundle and XRC {#high_dpi_bundle_xrc}
----------------------
XRC format has been updated to allow specifying wxBitmapBundle with
`<bitmaps>` tag in all the places where wxBitmap could be specified using
`<bitmap>` before (of course, using the latter tag is still supported). Either
multiple bitmaps or a single SVG image can be used.
Adapting Existing Code To High DPI {#high_dpi_existing_code}
==================================
Generally speaking, adding support for high DPI to the existing wxWidgets
programs involves doing at least the following:
1. Not using any hard-coded pixel values outside of `FromDIP()` (note that
this does _not_ apply to XRC).
2. Using wxBitmapBundle containing at least 2 (normal and high DPI) bitmaps
instead of wxBitmap and wxImageList when setting bitmaps.
3. Updating any custom art providers to override
wxArtProvider::CreateBitmapBundle() (and, of course, return multiple bitmaps
from it) instead of wxArtProvider::CreateBitmap().
4. Removing any calls to wxToolBar::SetToolBitmapSize() or, equivalently,
`<bitmapsize>` attributes from the XRC, as this overrides the best size
determination and may result in suboptimal appearance.
Platform-Specific Build Issues {#high_dpi_platform_specific}
==============================
Some platforms handle applications not specifically marked as
being "DPI-aware" by emulating low-resolution display for them and scaling them
up, resulting in blurry graphics and fonts, but globally preserving the
application appearance. For the best results, the application needs to be
explicitly marked as DPI-aware in a platform-dependent way.
MSW {#high_dpi_platform_msw}
---
The behaviour of the application when running on a high-DPI display depends on
the values in its [manifest][msw-manifest]. You may either use your own
manifest, in which case you need to define the `dpiAware` (for compatibility
with older OS versions) and `dpiAwareness` (for proper per-monitor DPI support)
in it, or use a manifest provided by wxWidgets in one of the ways explained in
the [manifests documentation](@ref msw_manifest).
Note that `wx_dpi_aware_pmv2.manifest` file and `wxUSE_DPI_AWARE_MANIFEST=2`
documented there correspond to full, per-monitor DPI awareness supported by
Windows 10 version 1703 or later. It is also possible to use
`wx_dpi_aware.manifest` and set `wxUSE_DPI_AWARE_MANIFEST=1` to enable minimal
support for system DPI, see [MSDN documentation][msw-highdpi] for more
information about different levels of DPI awareness.
[msw-highdpi]: https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows
macOS {#high_dpi_platform_mac}
-----
DPI-aware applications must set their `NSPrincipalClass` to `wxNSApplication`
(or at least `NSApplication`) in their `Info.plist` file. Also see Apple [high
resolution guidelines][apple-highdpi] for more information.
[apple-highdpi]: https://developer.apple.com/library/archive/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
GTK {#high_dpi_platform_gtk}
---
GTK 3 doesn't require anything special to be done and, in fact, doesn't support
scaling the application up automatically, i.e. all applications are DPI-aware.
However wxGTK only supports integer scaling factors currently and fractional
scales are rounded to the closest integer.
Older GTK 2 doesn't support application-level DPI-awareness at all and only
supports scaling them up globally on high DPI displays by setting `GDK_SCALE`
or `GDK_DPI_SCALE` environment variables.

View File

@@ -0,0 +1,589 @@
/////////////////////////////////////////////////////////////////////////////
// Name: html.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_html wxHTML Overview
@tableofcontents
The wxHTML library provides classes for parsing and displaying HTML.
It is not intended to be a high-end HTML browser. If you are looking for
something like that use wxWebView.
wxHTML can be used as a generic rich text viewer - for example to display
a nice About Box (like those of GNOME apps) or to display the result of
database searching. There is a wxFileSystem class which allows you to use
your own virtual file systems.
wxHtmlWindow supports tag handlers. This means that you can easily
extend wxHtml library with new, unsupported tags. Not only that,
you can even use your own application-specific tags!
See @c src/html/m_*.cpp files for details.
There is a generic wxHtmlParser class, independent of wxHtmlWindow.
@section overview_html_quickstart wxHTML Quick Start
@subsection overview_html_quickstart_disphtml Displaying HTML
First of all, you must include @c wx/wxhtml.h.
Class wxHtmlWindow (derived from ::wxScrolledWindow) is used to display HTML
documents.
It has two important methods: wxHtmlWindow::LoadPage and wxHtmlWindow::SetPage.
LoadPage loads and displays HTML file while SetPage displays directly the
passed @b string. See the example:
@code
mywin->LoadPage("test.htm");
mywin->SetPage("htmlbody"
"h1Error/h1"
"Some error occurred :-H)"
"/body/hmtl");
@endcode
@subsection overview_html_quickstart_settingup Setting up wxHtmlWindow
Because wxHtmlWindow is derived from ::wxScrolledWindow and not from
wxFrame, it doesn't have visible frame. But the user usually wants to see
the title of HTML page displayed somewhere and the frame's titlebar is
the ideal place for it.
wxHtmlWindow provides 2 methods in order to handle this:
wxHtmlWindow::SetRelatedFrame and wxHtmlWindow::SetRelatedStatusBar.
See the example:
@code
html = new wxHtmlWindow(this);
html->SetRelatedFrame(this, "HTML : %%s");
html->SetRelatedStatusBar(0);
@endcode
The first command associates the HTML object with its parent frame
(this points to wxFrame object there) and sets the format of the title.
Page title "Hello, world!" will be displayed as "HTML : Hello, world!"
in this example.
The second command sets which frame's status bar should be used to display
browser's messages (such as "Loading..." or "Done" or hypertext links).
@subsection overview_html_quickstart_custom Customizing wxHtmlWindow
You can customize wxHtmlWindow by setting font size, font face and
borders (space between border of window and displayed HTML). Related functions:
@li wxHtmlWindow::SetFonts
@li wxHtmlWindow::SetBorders
@li wxHtmlWindow::ReadCustomization
@li wxHtmlWindow::WriteCustomization
The last two functions are used to store user customization info wxConfig stuff
(for example in the registry under Windows, or in a dotfile under Unix).
@section overview_html_printing HTML Printing
The wxHTML library provides printing facilities with several levels of
complexity. The easiest way to print an HTML document is to use the
wxHtmlEasyPrinting class.
It lets you print HTML documents with only one command and you don't have to
worry about deriving from the wxPrintout class at all. It is only a simple
wrapper around the wxHtmlPrintout, normal wxWidgets printout class.
And finally there is the low level class wxHtmlDCRenderer which you can use to
render HTML into a rectangular area on any DC. It supports rendering into
multiple rectangles with the same width. The most common use of this is placing
one rectangle on each page or printing into two columns.
@section overview_html_helpformats Help Files Format
wxHTML library can be used to show an help manual to the user; in fact, it
supports natively (through wxHtmlHelpController) a reduced version of MS HTML
Workshop format.
A @b book consists of three files: the header file, the contents file
and the index file.
You can make a regular zip archive of these files, plus the HTML and any image
files, for wxHTML (or helpview) to read; and the @c ".zip" file can optionally
be renamed to @c ".htb".
@subsection overview_html_helpformats_hhp Header file (.hhp)
The header file must contain these lines (and may contain additional lines
which are ignored):
@code
Contents file=filename.hhc
Index file=filename.hhk
Title=title of your book
Default topic=default page to be displayed.htm
@endcode
All filenames (including the Default topic) are relative to the
location of the @c ".hhp" file.
@note For localization, in addition the @c ".hhp" file may contain the line
@code
Charset=rfc_charset
@endcode
which specifies what charset (e.g. "iso8859_1") was used in contents
and index files. Please note that this line is incompatible with
MS HTML Help Workshop and it would either silently remove it or complain
with some error. See also @ref overview_nonenglish.
@subsection overview_html_helpformats_hhc Contents file (.hhc)
Contents file has HTML syntax and it can be parsed by regular HTML parser.
It contains exactly one list (@c &lt;ul&gt;....@c &lt;/ul&gt; statement):
@code
<ul>
<li><object type="text/sitemap">
<param name="Name" value="@topic name@">
<param name="ID" value=@numeric_id@>
<param name="Local" value="@filename.htm@">
</object>
<li><object type="text/sitemap">
<param name="Name" value="@topic name@">
<param name="ID" value=@numeric_id@>
<param name="Local" value="@filename.htm@">
</object>
...
</ul>
@endcode
You can modify value attributes of param tags. The <em>topic name</em> is name
of chapter/topic as is displayed in contents, <em>filename.htm</em> is the HTML
page name (relative to the @c ".hhp" file) and <em>numeric_id</em> is optional,
it is used only when you use wxHtmlHelpController::Display(int).
Items in the list may be nested - one @c &lt;li&gt; statement may contain a
@c &lt;ul&gt; sub-statement:
@code
<ul>
<li><object type="text/sitemap">
<param name="Name" value="Top node">
<param name="Local" value="top.htm">
</object>
<ul>
<li><object type="text/sitemap">
<param name="Name" value="subnode in topnode">
<param name="Local" value="subnode1.htm">
</object>
...
</ul>
<li><object type="text/sitemap">
<param name="Name" value="Another Top">
<param name="Local" value="top2.htm">
</object>
...
</ul>
@endcode
@subsection overview_html_helpformats_hhk Index Files (.hhk)
Index files have same format as contents files except that ID params are
ignored and sublists are @b not allowed.
@section overview_html_filters Input Filters
The wxHTML library provides a mechanism for reading and displaying
files of many different file formats.
wxHtmlWindow::LoadPage can load not only HTML files but any known file.
To make a file type known to wxHtmlWindow you must create a wxHtmlFilter filter and
register it using wxHtmlWindow::AddFilter.
@section overview_html_cells Cells and Containers
This article describes mechanism used by wxHtmlWinParser and
wxHtmlWindow to parse and display HTML documents.
@subsection overview_html_cells_cells Cells
You can divide any text (or HTML) into small fragments. Let's call these
fragments @b cells. Cell is for example one word, horizontal line, image
or any other part of document. Each cell has width and height (except special
"magic" cells with zero dimensions - e.g. colour changers or font changers).
See wxHtmlCell.
@subsection overview_html_cells_containers Containers
Container is kind of cell that may contain sub-cells. Its size depends
on number and sizes of its sub-cells (and also depends on width of window).
See wxHtmlContainerCell, wxHtmlCell::Layout. This image shows the cells and
containers:
@image html overview_html_contbox.png
@subsection overview_html_cells_conttaghandler Using Containers in Tag Handler
wxHtmlWinParser provides a user-friendly way of managing containers.
It is based on the idea of opening and closing containers.
Use wxHtmlWinParser::OpenContainer to open new a container @e within an already
opened container.
This new container is a @e sub-container of the old one. (If you want to create a
new container with the same depth level you can call @c CloseContainer(); OpenContainer();.)
Use wxHtmlWinParser::CloseContainer to close the container.
This doesn't create a new container with same depth level but it returns "control"
to the parent container. See explanation:
@image html overview_html_cont.png
There clearly must be same number of calls to OpenContainer as to
CloseContainer.
This code creates a new paragraph (container at same depth level) with
"Hello, world!":
@code
m_WParser->CloseContainer();
c = m_WParser->OpenContainer();
m_WParser->AddText("Hello, ");
m_WParser->AddText("world!");
m_WParser->CloseContainer();
m_WParser->OpenContainer();
@endcode
and here is image of the situation:
@image html overview_html_hello.png
You can see that there was an opened container before the code was executed.
We closed it, created our own container, then closed our container and opened
new container.
The result was that we had @e same depth level after executing. This is general
rule that should be followed by tag handlers: leave depth level of containers
unmodified (in other words, number of OpenContainer and CloseContainer calls
should be same within wxHtmlTagHandler::HandleTag's body).
Notice that it would be usually better to use wxHtmlContainerCell::InsertCell
instead of adding text to the parser directly.
@section overview_html_handlers Tag Handlers
The wxHTML library provides architecture of pluggable @e tag handlers.
Tag handler is class that understands particular HTML tag (or tags) and is
able to interpret it.
wxHtmlWinParser has a static table of @b modules.
Each module contains one or more tag handlers. Each time a new wxHtmlWinParser
object is constructed all modules are scanned and handlers are added
to wxHtmlParser's list of available handlers (note: wxHtmlParser's list
is non-static).
@subsection overview_html_handlers_howworks How it works
Common tag handler's wxHtmlTagHandler::HandleTag method works in four steps:
@li Save state of parent parser into local variables
@li Change parser state according to tag's params
@li Parse text between the tag and paired ending tag (if present)
@li Restore original parser state
See wxHtmlWinParser for methods for modifying parser's state.
In general you can do things like opening/closing containers, changing colors, fonts etc.
@subsection overview_html_handlers_custom Providing own tag handlers
You should create a new .cpp file and place the following lines into it:
@code
#include <mod_templ.h>
#include <forcelink.h>
FORCE_LINK_ME(yourmodulefilenamewithoutcpp)
@endcode
Then you must define handlers and one module.
@subsection overview_html_handlers_tag Tag handlers
The handler is derived from wxHtmlWinTagHandler (or directly from wxHtmlTagHandler).
You can use set of macros to define the handler (see src/html/m_*.cpp files
for details). Handler definition must start with @b TAG_HANDLER_BEGIN macro
and end with @b TAG_HANDLER_END macro.
I strongly recommend to have a look at @e include/wxhtml/mod_templ.h file.
Otherwise you won't understand the structure of macros.
See macros reference:
@li @b TAG_HANDLER_BEGIN(@e name, @e tags):
Starts handler definition. @e name is handler identifier (in fact
part of class name), @e tags is string containing list of tags
supported by this handler (in uppercase). This macro derives new class from
wxHtmlWinTagHandler and implements it is wxHtmlTagHandler::GetSupportedTags method.
Example: TAG_HANDLER_BEGIN(FONTS, "B,I,U,T")
@li @b TAG_HANDLER_VARS:
This macro starts block of variables definitions. (Variables are identical
to class attributes.) Example:
@code
TAG_HANDLER_BEGIN(VARS_ONLY, "CRAZYTAG")
TAG_HANDLER_VARS
int my_int_var;
wxString something_else;
TAG_HANDLER_END(VARS_ONLY)
@endcode
This macro is used only in rare cases.
@li @b TAG_HANDLER_CONSTR(@e name):
This macro supplies object constructor. @e name is same name as the one
from TAG_HANDLER_BEGIN macro. Body of constructor follow after
this macro (you must use { and } ). Example:
@code
TAG_HANDLER_BEGIN(VARS2, "CRAZYTAG")
TAG_HANDLER_VARS
int my_int_var;
TAG_HANDLER_CONSTR(vars2)
{ // !!!!!!
my_int_var = 666;
} // !!!!!!
TAG_HANDLER_END(VARS2)
@endcode
Never used in wxHTML :-)
@li @b TAG_HANDLER_PROC(@e varib):
This is very important macro. It defines wxHtmlTagHandler::HandleTag
method. @e varib is name of parameter passed to the method, usually
@e tag. Body of method follows after this macro.
Note than you must use { and } !
Example:
@code
TAG_HANDLER_BEGIN(TITLE, "TITLE")
TAG_HANDLER_PROC(tag)
{
printf("TITLE found...\n");
}
TAG_HANDLER_END(TITLE)
@endcode
@li @b TAG_HANDLER_END(@e name):
Ends definition of tag handler @e name.
@subsection overview_html_handlers_modules Tags Modules
You can use set of 3 macros TAGS_MODULE_BEGIN, TAGS_MODULE_ADD and
TAGS_MODULE_END to inherit new module from
wxHtmlTagsModule and to create instance of it.
See macros reference:
@li @b TAGS_MODULE_BEGIN(@e modname):
Begins module definition. @e modname is part of class name and must be unique.
@li @b TAGS_MODULE_ADD(@e name):
Adds the handler to this module. @e name is the identifier from TAG_HANDLER_BEGIN.
@li @b TAGS_MODULE_END(@e modname):
Ends the definition of module.
Example:
@code
TAGS_MODULE_BEGIN(Examples)
TAGS_MODULE_ADD(VARS_ONLY)
TAGS_MODULE_ADD(VARS2)
TAGS_MODULE_ADD(TITLE)
TAGS_MODULE_END(Examples)
@endcode
@section overview_html_supptags Supported HTML Tags
wxHTML is not full implementation of HTML standard. Instead, it supports most
common tags so that it is possible to display @e simple HTML documents with it.
(For example it works fine with pages created in Netscape Composer or generated
by tex2rtf).
Following tables list all tags known to wxHTML, together with supported
parameters.
A tag has general form of @c tagname param_1 param_2 ... param_n where param_i
is either @c paramname="paramvalue" or @c paramname=paramvalue - these two are
equivalent. Unless stated otherwise, wxHTML is case-insensitive.
@subsection overview_html_supptags_commonvalues Common Parameter Values
We will use these substitutions in tags descriptions:
@code
[alignment] CENTER
LEFT
RIGHT
JUSTIFY
[v_alignment] TOP
BOTTOM
CENTER
[color] HTML 4.0-compliant colour specification
[fontsize] -2
-1
+0
+1
+2
+3
+4
1
2
3
4
5
6
7
[pixels] integer value that represents dimension in pixels
[percent] i%
where i is integer
[url] an URL
[string] text string
[coords] c(1),c(2),c(3),...,c(n)
where c(i) is integer
@endcode
@subsection overview_html_supptags_list List of Supported Tags
@code
A NAME=[string]
HREF=[url]
TARGET=[target window spec]
ADDRESS
AREA SHAPE=POLY
SHAPE=CIRCLE
SHAPE=RECT
COORDS=[coords]
HREF=[url]
B
BIG
BLOCKQUOTE
BODY TEXT=[color]
LINK=[color]
BGCOLOR=[color]
BR ALIGN=[alignment]
CENTER
CITE
CODE
DD
DIV ALIGN=[alignment]
DL
DT
EM
FONT COLOR=[color]
BGCOLOR=[color]
SIZE=[fontsize]
FACE=[comma-separated list of facenames]
HR ALIGN=[alignment]
SIZE=[pixels]
WIDTH=[percent|pixels]
NOSHADE
H1
H2
H3
H4
H5
H6
I
IMG SRC=[url]
WIDTH=[percent|pixels]
HEIGHT=[pixels]
ALIGN=TEXTTOP
ALIGN=CENTER
ALIGN=ABSCENTER
ALIGN=BOTTOM
USEMAP=[url]
KBD
LI
MAP NAME=[string]
META HTTP-EQUIV="Content-Type"
CONTENT=[string]
OL
P ALIGN=[alignment]
PRE
SAMP
SMALL
SPAN
STRIKE
STRONG
SUB
SUP
TABLE ALIGN=[alignment]
WIDTH=[percent|pixels]
BORDER=[pixels]
VALIGN=[v_alignment]
BGCOLOR=[color]
CELLSPACING=[pixels]
CELLPADDING=[pixels]
TD ALIGN=[alignment]
VALIGN=[v_alignment]
BGCOLOR=[color]
WIDTH=[percent|pixels]
COLSPAN=[pixels]
ROWSPAN=[pixels]
NOWRAP
TH ALIGN=[alignment]
VALIGN=[v_alignment]
BGCOLOR=[color]
WIDTH=[percent|pixels]
COLSPAN=[pixels]
ROWSPAN=[pixels]
TITLE
TR ALIGN=[alignment]
VALIGN=[v_alignment]
BGCOLOR=[color]
TT
U
UL
@endcode
@subsection overview_html_suppstyles_list Supported Styles
wxHTML doesn't really have CSS support but it does support a few simple styles:
you can use @c "text-align", @c "width", @c "vertical-align" and @c
"background" with all elements and for @c SPAN elements a few other styles are
additionally recognized:
- @c background-color
- @c color
- @c font-family
- @c font-size (only in point units)
- @c font-style (only "oblique", "italic" and "normal" values are supported)
- @c font-weight (only "bold" and "normal" values are supported)
- @c text-decoration (only "underline" value is supported)
*/

View File

@@ -0,0 +1,246 @@
Installing wxWidgets {#overview_install}
====================
wxWidgets headers and libraries must be available in order to build the
applications using it, so the first step when starting to use wxWidgets is to
install it. This can be done, for all platforms and library versions, by
building wxWidgets from sources, but for the most common platforms pre-built
binaries of the libraries are also provided, so the first decision to make is
whether to use these binaries or build the library yourself. Building the
libraries yourself allows you to compile the latest version using exactly the
options you need, and so is the most flexible solution, but using the binaries
may be simpler and faster -- the choice is yours, just follow the instructions
in the corresponding section below depending on the approach you prefer. Of
course, you only need to do one _or_ the other, _not_ both.
Using Binaries
--------------
How to install binaries depends on your platform:
- For Microsoft Windows (MSW), wxWidgets project provides official binaries
on the [Downloads page][], please see
the [instructions for using them](@ref plat_msw_binaries).
- For Linux, and other free Unix-like systems, wxWidgets packages are available
in system repositories under the name "wxGTK". Note that to develop
applications using wxWidgets you may need to install the "development"
packages and not just the libraries needed for running the applications using
wxWidgets. For example, under Debian and Debian-derived systems such as
Ubuntu, you need to run `apt get libwxgtkX.Y-dev`.
- For macOS, wxWidgets is available in third-party package managers such as
[brew][] or [MacPorts][], and you can install them in the usual way.
[downloads page]: https://www.wxwidgets.org/downloads/
[brew]: https://brew.sh/
[MacPorts]: https://www.macports.org/
Additionally, some third-party C++ package managers also provide wxWidgets
binaries. For example, please see [this post][vcpkg-post] for the instructions
about using [vcpkg][] C++ package manager for installing wxWidgets.
[vcpkg-post]: https://www.wxwidgets.org/blog/2019/01/wxwidgets-and-vcpkg/
[vcpkg]: https://github.com/microsoft/vcpkg
Building from Source
--------------------
### Getting the sources {#install_get_sources}
To build the library you need to get its sources first. The recommended way to
do it is to use Git to check them out from the official wxWidgets repository
using the following command:
$ git clone --recurse-submodules https://github.com/wxWidgets/wxWidgets.git
Alternatively, you can download the sources from the [downloads page][].
Please note that all the source archives in different formats (ZIP, 7z,
tar.bz2) contain the same files, but use different line ending formats: Unix
("LF") for the latter one and DOS ("CR LF") for the two other ones, and it is
usually preferable to choose the format corresponding to the current platform.
When downloading the sources with DOS ends of lines, prefer 7z format for much
smaller file size.
### Selecting the build system
wxWidgets can be built using [CMake](https://cmake.org/) under all platforms.
Please follow [CMake build instructions](@ref overview_cmake) if you prefer to
use it.
Otherwise, please use the appropriate instructions depending on your platform:
- For native wxMSW port under [Microsoft Windows](@ref plat_msw_install).
- For wxGTK under [Linux and other Unix-like systems](@ref plat_gtk_install).
- For native wxOSX port under [macOS](@ref plat_osx_install).
The wxWidgets ports mentioned above are the main ones, however other variants
also exist, see [platform details](@ref page_port) page for the full list.
Building Your Application
-------------------------
After installing wxWidgets, you need to set up your application to be built
using it.
As previously, if you're using CMake, please follow the instructions for
[building your applications with CMake](@ref cmake_apps).
Note that you can use the provided `samples/minimal/CMakeLists.txt` file to
test building the minimal sample using CMake to verify your installation.
Otherwise, choose the appropriate method for your platform and build system:
### Unix, command line
On any Unix-like system, including macOS and Unix-like environments such as
Cygwin or MSYS2 under MSW, very simple applications consisting of a single
source file `hello.cpp` can be built directly from the command line using the
following command:
$ c++ -o hello hello.cpp `wx-config --cxxflags --libs`
Please note that you *must* use `wx-config` to obtain the compiler and linker
flags in this case. Using this method with `samples/minimal/minimal.cpp` is a
simple way of checking that wxWidgets is installed correctly and can be used
and it is recommended to try building it, especially if you are new to
wxWidgets.
### Unix, with GNU Make
For more realistic applications under Unix, a makefile is traditionally used
for building. For a program consisting of the files `hello.cpp` and `bye.cpp` a
minimal makefile could look like the following:
~~~{make}
# wx-config to use, may be overridden on make command line.
WX_CONFIG := wx-config
WX_CXXFLAGS := $(shell $(WX_CONFIG) --cxxflags)
WX_LIBS := $(shell $(WX_CONFIG) --libs)
OBJECTS := hello.o bye.o
hello: $(OBJECTS)
$(CXX) -o $@ $(OBJECTS) $(LDFLAGS) $(WX_LIBS) $(LIBS)
$(OBJECTS): %.o: %.cpp
$(CXX) -c -o $@ $(WX_CXXFLAGS) $(CXXFLAGS) $<
~~~
Please refer to [the manual][gnumake] for more information about writing makefiles
for GNU make. Also notice that you need to replace the leading spaces with TABs
if you are copy-pasting the makefile above into your own.
[gnumake]: https://www.gnu.org/software/make/manual/make.html
### Unix, with autoconf
For building applications using autoconf, you need to have the following lines
in your `configure.ac` file:
~~~{configure}
AC_INIT(...)
dnl Add support for --wxdir, --wx-config and other options allowing to select
dnl the version and location of wxWidgets to use.
WX_CONFIG_OPTIONS
... other preliminary macros ...
dnl A C++ compiler is required.
AC_PROG_CXX
dnl Find wxWidgets 3.1.6 or exit with error. See documentation of this macro
dnl in wxwin.m4 for more information, notably optional arguments allowing to
dnl select the required libraries and optional libraries to detect.
WX_CONFIG_CHECK([3.1.6], [], [AC_MSG_FAILURE([wxWidgets 3.1.6 or later not found])])
dnl Use wxWidgets compilation flags for all files in the project. If you also
dnl use automake, you may prefer to add WX_CXXFLAGS and WX_LIBS to the
dnl individual target_CXXFLAGS and target_LIBADD or target_LDADD variables.
CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS"
CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS"
LIBS="$LIBS $WX_LIBS"
... other macros checking for headers/libraries ...
AC_OUTPUT
~~~
Note that this assumes that `wxwin.m4` file is available in a standard
location, as is the case when using distribution-provided wxWidgets packages or
after building wxWidgets from source and using `make install`. If this is not
the case, you must copy this file from wxWidgets source directory to the
directory containing autoconf macros used by your application (typically `m4`,
e.g. if you use `AC_CONFIG_MACRO_DIRS([m4])`).
### MSW, with Microsoft Visual Studio
For applications using Microsoft Visual Studio IDE, simply add the provided
`wxwidgets.props` property sheet file to your project as explained in the
[instructions](@ref msw_build_apps_msvc) and build the project as usual.
### MSW, with MinGW
If you use MinGW in any Unix-like environment (Cygwin, MSYS2 etc), please
follow the instructions for Unix systems.
Otherwise, i.e. when building using `mingw32-make` or using `g++` directly from
the command line, please follow [these instructions](@ref msw_build_apps_other)
and provide the list of required compiler and build options manually.
### Mac, with Xcode
If you want to use an environment variable (such as WXWIN) in your xcode
project, there are several things you must do.
- Enable the usage of environment variables in xcode:<br>
`defaults write com.apple.dt.Xcode UseSanitizedBuildSystemEnvironment -bool NO`
- Set the variables for use with the launch agent (application to OSX 10.10
and up)
~~~{xml}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>my.startup</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>
launchctl setenv WXWIN /Users/dconnet/devtools/wx/wxWidgets-3.1.5
</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
~~~
### Other IDEs
If you use an IDE with wxWidgets support, such as [Code::Blocks][] or
[CodeLite][], please use the IDE wizards.
[Code::Blocks]: https://www.codeblocks.org/
[CodeLite]: https://codelite.org/
If you use another IDE, under Unix you should run `wx-config --cxxflags` and
`wx-config --libs` commands separately and copy-and-paste their output to the
"Additional preprocessor options" and "Additional linker options" fields in
your IDE, respectively. Under MSW systems you need to configure the IDE using
the instructions in the [manual setup](@ref msw_build_apps_other) section.

View File

@@ -0,0 +1,134 @@
/////////////////////////////////////////////////////////////////////////////
// Name: internationalization.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_i18n Internationalization
@tableofcontents
Although internationalization of an application (i18n for short) involves far
more than just translating its text messages to another message - date, time
and currency formats need changing too, some languages are written left to
right and others right to left, character encoding may differ and many other
things may need changing too - it is a necessary first step. wxWidgets provides
facilities for message translation with its wxLocale class and is itself fully
translated into several languages. Please consult wxWidgets home page for the
most up-to-date translations - and if you translate it into one of the
languages not done yet, your translations would be gratefully accepted for
inclusion into future versions of the library!
The wxWidgets approach to i18n closely follows the GNU gettext package.
wxWidgets uses the message catalogs which are binary compatible with gettext
catalogs and this allows to use all of the programs in this package to work
with them as well as using any of the tools working with message catalogs in
this format such as <a href="http://poedit.net/">Poedit</a>.
Because of this, you will need to use the gettext package to work with the
translations during the program development. However no additional libraries
are needed during run-time, so you have only the message catalogs to distribute
and nothing else.
There are two kinds of message catalogs: source catalogs which are text files
with extension .po and binary catalogs which are created from the source ones
with @e msgfmt program (part of gettext package) and have the extension .mo.
Only the binary files are needed during program execution.
Translating your application involves several steps:
@li Translating the strings in the program text using wxGetTranslation() or
equivalently the @c _() macro.
@li Extracting the strings to be translated from the program: this uses the
work done in the previous step because @c xgettext program used for string
extraction recognises the standard @c _() as well as (using its @c -k
option) our wxGetTranslation() and extracts all strings inside the calls to
these functions. Alternatively, you may use @c -a option to extract all the
strings, but it will usually result in many strings being found which don't
have to be translated at all. This will create a text message catalog - a
.po file.
@li Translating the strings extracted in the previous step to other
language(s). It involves editing the .po file.
@li Compiling the .po file into .mo file to be used by the program.
@li Installing the .mo files with your application in the appropriate location
for the target system (see @ref overview_i18n_mofiles).
@li Setting the appropriate locale in your program to use the strings for the
given language: see wxLocale.
@note Under macOS you also need to list all the supported languages under the
@c CFBundleLocalizations key in your application @c Info.plist file
in order to allow the application to support the corresponding locale.
@section overview_i18n_mofiles Installing translation catalogs
The .mo files with compiled catalogs must be included with the application.
By default, wxFileTranslationsLoader is used to load them from files installed
alongside the application (although you could use wxResourceTranslationsLoader
or some custom loader too).
The files are expected to be in the resources directory (as returned by
wxStandardPaths::GetLocalizedResourcesDir().
If the message catalogs are not installed in this default location you may
explicitly use wxFileTranslationsLoader::AddCatalogLookupPathPrefix() to still
allow wxWidgets to find them, but it is recommended to use the default
locations when possible.
Depending on the platform, the default location differs. On Windows, it is
alongside the executable. On Unix, translations are expected to be in
"$prefix/share/locale". On macOS, application bundle's @em Resources subdirectory
is used.
In all cases, translations are searched for in subdirectories named using the
languages codes from ISO 639. The .mo file(s) should be located either directly
in that directory or in LC_MESSAGES subdirectory. On macOS, the ".lproj" extension
is used for the per-languages Resources subdirectories.
Here's how an app would typically install the files on Unix:
@code
/usr/bin/myapp
/usr/share/locale/de/LC_MESSAGES/myapp.mo
/usr/share/locale/fr/LC_MESSAGES/myapp.mo
@endcode
And on macOS:
@code
MyApp.app/Contents/MacOS/MyApp
MyApp.app/Contents/Resources/de.lproj/myapp.mo
MyApp.app/Contents/Resources/fr.lproj/myapp.mo
@endcode
And on Windows:
@code
C:\Program Files\MyApp\myapp.exe
C:\Program Files\MyApp\de\myapp.mo
C:\Program Files\MyApp\fr\myapp.mo
@endcode
It is of course possible to use the Unix layout everywhere instead.
@section overview_i18n_menuaccel Translating Menu Accelerators
For the translations of the accelerator modifier names (Ctrl, Alt and Shift)
used in the menu labels to work, the translations of the names of these
modifiers in the "keyboard key" context must be provided. The wxWidgets own
translations do provide them for many languages, but not for all of them, so if
you notice that the accelerators don't work when translated, please provide the
translations for these strings in the message catalogs distributed with your
own application or, even better, contribute these translations to wxWidgets
itself.
Note that the same is also true for all the other keys that can be used as
accelerators, e.g. Backspace, End, Insert, etc: ideally, wxWidgets catalogs
should contain their translations, but this is not the case in practice for all
languages.
@see
@li The gettext Manual: http://www.gnu.org/software/gettext/manual/gettext.html
@li @ref overview_nonenglish - It focuses on handling charsets related problems.
@li @ref page_samples_internat - Shows you how all this looks in practice.
*/

View File

@@ -0,0 +1,209 @@
/////////////////////////////////////////////////////////////////////////////
// Name: ipc.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_ipc Interprocess Communication
@tableofcontents
wxWidgets has a number of different classes to help with interprocess
communication and network programming. This section only discusses one family
of classes -- the DDE-like protocol -- but here's a list of other useful
classes:
@li wxSocketEvent, wxSocketBase, wxSocketClient, wxSocketServer - Classes for
the low-level TCP/IP API.
@li wxProtocol, wxURL, wxFTP, wxHTTP - Classes for programming popular
Internet protocols.
wxWidgets' DDE-like protocol is a high-level protocol based on Windows DDE.
There are two implementations of this DDE-like protocol: one using real DDE
running on Windows only, and another using TCP/IP (sockets) that runs on most
platforms. Since the API and virtually all of the behaviour is the same apart
from the names of the classes, you should find it easy to switch between the
two implementations.
Notice that by including @c @<wx/ipc.h@> you may define convenient synonyms for
the IPC classes: wxServer for either wxDDEServer or wxTCPServer depending on
whether DDE-based or socket-based implementation is used and the same thing for
wxClient and wxConnection.
By default, the DDE implementation is used under Windows. DDE works within one
computer only. If you want to use IPC between different workstations you should
define @c wxUSE_DDE_FOR_IPC as 0 before including this header -- this will
force using TCP/IP implementation even under Windows.
The following description refers to wxWidgets, but remember that the equivalent
wxTCP* and wxDDE* classes can be used in much the same way.
Three classes are central to the DDE-like API:
@li wxClient - This represents the client application, and is used only within
a client program.
@li wxServer - This represents the server application, and is used only within
a server program.
@li wxConnection - This represents the connection from the client to the
server. Both the client and the server use an instance of this class, one
per connection. Most DDE transactions operate on this object.
Messages between applications are usually identified by three variables:
connection object, topic name and item name. A data string is a fourth element
of some messages. To create a connection (a conversation in Windows parlance),
the client application uses wxClient::MakeConnection to send a message to the
server object, with a string service name to identify the server and a topic
name to identify the topic for the duration of the connection. Under Unix, the
service name may be either an integer port identifier in which case an Internet
domain socket will be used for the communications or a valid file name (which
shouldn't exist and will be deleted afterwards) in which case a Unix domain
socket is created.
<b>SECURITY NOTE:</b> Using Internet domain sockets is extremely insecure for
IPC as there is absolutely no access control for them, use Unix domain sockets
whenever possible!
The server then responds and either vetoes the connection or allows it. If
allowed, both the server and client objects create wxConnection objects which
persist until the connection is closed. The connection object is then used for
sending and receiving subsequent messages between client and server -
overriding virtual functions in your class derived from wxConnection allows you
to handle the DDE messages.
To create a working server, the programmer must:
@li Derive a class from wxConnection, providing handlers for various messages
sent to the server side of a wxConnection (e.g. OnExecute, OnRequest,
OnPoke). Only the handlers actually required by the application need to be
overridden.
@li Derive a class from wxServer, overriding OnAcceptConnection to accept or
reject a connection on the basis of the topic argument. This member must
create and return an instance of the derived connection class if the
connection is accepted.
@li Create an instance of your server object and call Create to activate it,
giving it a service name.
To create a working client, the programmer must:
@li Derive a class from wxConnection, providing handlers for various messages
sent to the client side of a wxConnection (e.g. OnAdvise). Only the
handlers actually required by the application need to be overridden.
@li Derive a class from wxClient, overriding OnMakeConnection to create and
return an instance of the derived connection class.
@li Create an instance of your client object.
@li When appropriate, create a new connection using wxClient::MakeConnection,
with arguments host name (processed in Unix only, use 'localhost' for local
computer), service name, and topic name for this connection. The client
object will call OnMakeConnection to create a connection object of the
derived class if the connection is successful.
@li Use the wxConnection member functions to send messages to the server.
@section overview_ipc_datatransfer Data Transfer
These are the ways that data can be transferred from one application to
another. These are methods of wxConnection.
@li <b>Execute:</b> the client calls the server with a data string representing
a command to be executed. This succeeds or fails, depending on the server's
willingness to answer. If the client wants to find the result of the
Execute command other than success or failure, it has to explicitly call
Request.
@li <b>Request:</b> the client asks the server for a particular data string
associated with a given item string. If the server is unwilling to reply,
the return value is @NULL. Otherwise, the return value is a string
(actually a pointer to the connection buffer, so it should not be
deallocated by the application).
@li <b>Poke:</b> The client sends a data string associated with an item string
directly to the server. This succeeds or fails.
@li <b>Advise:</b> The client asks to be advised of any change in data
associated with a particular item. If the server agrees, the server will
send an OnAdvise message to the client along with the item and data.
The default data type is wxCF_TEXT (ASCII text), and the default data size is
the length of the null-terminated string. Windows-specific data types could
also be used on the PC.
@section overview_ipc_examples Examples
See the sample programs @e server and @e client in the IPC samples directory.
Run the server, then the client. This demonstrates using the Execute, Request,
and Poke commands from the client, together with an Advise loop: selecting an
item in the server list box causes that item to be highlighted in the client
list box.
@section overview_ipc_dde More DDE Details
A wxClient object initiates the client part of a client-server DDE-like
(Dynamic Data Exchange) conversation (available in both Windows and Unix).
To create a client which can communicate with a suitable server, you need to
derive a class from wxConnection and another from wxClient. The custom
wxConnection class will receive communications in a 'conversation' with a
server. and the custom wxServer is required so that a user-overridden
wxClient::OnMakeConnection member can return a wxConnection of the required
class, when a connection is made.
For example:
@code
class MyConnection: public wxConnection
{
public:
MyConnection(void)::wxConnection() { }
~MyConnection(void) { }
bool OnAdvise(const wxString& topic, const wxString& item, char *data,
int size, wxIPCFormat format)
{
wxMessageBox(topic, data);
}
};
class MyClient: public wxClient
{
public:
MyClient(void) { }
wxConnectionBase* OnMakeConnection(void)
{
return new MyConnection;
}
};
@endcode
Here, @e MyConnection will respond to OnAdvise messages sent by the server by
displaying a message box.
When the client application starts, it must create an instance of the derived
wxClient. In the following, command line arguments are used to pass the host
name (the name of the machine the server is running on) and the server name
(identifying the server process). Calling wxClient::MakeConnection implicitly
creates an instance of @e MyConnection if the request for a connection is
accepted, and the client then requests an @e Advise loop from the server (an
Advise loop is where the server calls the client when data has changed).
@code
wxString server = "4242";
wxString hostName;
wxGetHostName(hostName);
// Create a new client
MyClient *client = new MyClient;
connection = (MyConnection *)client->MakeConnection(hostName, server, "IPC TEST");
if (!connection)
{
wxMessageBox("Failed to make connection to server", "Client Demo Error");
return nullptr;
}
connection->StartAdvise("Item");
@endcode
*/

View File

@@ -0,0 +1,18 @@
/////////////////////////////////////////////////////////////////////////////
// Name: listctrl.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_listctrl wxListCtrl Overview
@tableofcontents
@todo The wxListCtrl topic overview still needs to be written, sorry.
@see wxListCtrl, wxImageList, wxListItem
*/

View File

@@ -0,0 +1,327 @@
/////////////////////////////////////////////////////////////////////////////
// Name: log.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_log Logging Overview
@tableofcontents
This is a general overview of logging classes provided by wxWidgets. The word
logging here has a broad sense, including all of the program output, not only
non-interactive messages. The logging facilities included in wxWidgets provide
the base wxLog class which defines the standard interface for a @e log target
as well as several standard implementations of it and a family of functions to
use with them.
First of all, no knowledge of wxLog classes is needed to use them. For this,
you should only know about @ref group_funcmacro_log "wxLogXXX() functions".
All of them have the same syntax as @e printf() or @e vprintf() , i.e. they
take the format string as the first argument and respectively a variable number
of arguments or a variable argument list pointer. Here are all of them:
@li wxLogFatalError() which is like wxLogError(), but also terminates the program
with the exit code 3 (using @e abort() standard function). Unlike for all
the other logging functions, this function can't be overridden by a log
target.
@li wxLogError() is the function to use for error messages, i.e. the messages
that must be shown to the user. The default processing is to pop up a
message box to inform the user about it.
@li wxLogWarning() for warnings. They are also normally shown to the user, but
don't interrupt the program work.
@li wxLogMessage() is for all normal, informational messages. They also appear in
a message box by default (but it can be changed, see below).
@li wxLogVerbose() is for verbose output. Normally, it is suppressed, but might
be activated if the user wishes to know more details about the program
progress (another, but possibly confusing name for the same function is
wxLogInfo).
@li wxLogStatus() is for status messages. They will go into the status bar of the
active or specified (as the first argument) wxFrame if it has one.
@li wxLogSysError() is mostly used by wxWidgets itself, but might be handy for
logging errors after system call (API function) failure. It logs the
specified message text as well as the last system error code (@e errno or
Windows' @e GetLastError() depending on the platform) and the corresponding error
message. The second form of this function takes the error code explicitly
as the first argument.
@li wxLogDebug() is @b the right function for debug output. It only does anything
at all in the debug mode (when the preprocessor symbol @c \__WXDEBUG__ is
defined) and expands to nothing in release mode (otherwise).
Note that under Windows, you must either run the program under debugger or
use a 3rd party program such as DebugView
(http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx)
to actually see the debug output.
@li wxLogTrace() as wxLogDebug() only does something in debug build. The reason for
making it a separate function from it is that usually there are a lot of
trace messages, so it might make sense to separate them from other debug
messages which would be flooded in them. Moreover, the second version of
this function takes a trace mask as the first argument which allows to
further restrict the amount of messages generated.
@see @ref group_funcmacro_log "Logging Functions and Macros"
The usage of these functions should be fairly straightforward, however it may
be asked why not use the other logging facilities, such as C standard stdio
functions or C++ streams. The short answer is that they're all very good
generic mechanisms, but are not really adapted for wxWidgets, while the log
classes are. Some of advantages in using wxWidgets log functions are:
@li @b Portability: It is a common practice to use @e printf() statements or
cout/cerr C++ streams for writing out some (debug or otherwise)
information. Although it works just fine under Unix, these messages go
strictly nowhere under Windows where the stdout of GUI programs is not
assigned to anything. Thus, you might view wxLogMessage() as a simple
substitute for @e printf().
You can also redirect the @e wxLogXXX calls to @e cout by just writing:
@code
wxLog* logger = new wxLogStream(&cout);
wxLog::SetActiveTarget(logger);
@endcode
Finally, there is also a possibility to redirect the output sent to @e cout
to a wxTextCtrl by using the wxStreamToTextRedirector class.
@li @b Flexibility: The output of wxLog functions can be redirected or
suppressed entirely based on their importance, which is either impossible
or difficult to do with traditional methods. For example, only error
messages, or only error messages and warnings might be logged, filtering
out all informational messages.
@li @b Completeness: Usually, an error message should be presented to the user
when some operation fails. Let's take a quite simple but common case of a
file error: suppose that you're writing your data file on disk and there is
not enough space. The actual error might have been detected inside
wxWidgets code (say, in wxFile::Write), so the calling function doesn't
really know the exact reason of the failure, it only knows that the data
file couldn't be written to the disk. However, as wxWidgets uses
wxLogError() in this situation, the exact error code (and the corresponding
error message) will be given to the user together with "high level" message
about data file writing error.
@section overview_log_enable Log Messages Selection
By default, most log messages are enabled. In particular, this means that
errors logged by wxWidgets code itself (e.g. when it fails to perform some
operation, for instance wxFile::Open() logs an error when it fails to open a
file) will be processed and shown to the user. To disable the logging entirely
you can use wxLog::EnableLogging() method or, more usually, wxLogNull class
which temporarily disables logging and restores it back to the original setting
when it is destroyed.
To limit logging to important messages only, you may use wxLog::SetLogLevel()
with e.g. wxLOG_Warning value -- this will completely disable all logging
messages with the severity less than warnings, so wxLogMessage() output won't
be shown to the user any more.
Moreover, the log level can be set separately for different log components.
Before showing how this can be useful, let us explain what log components are:
they are simply arbitrary strings identifying the component, or module, which
generated the message. They are hierarchical in the sense that "foo/bar/baz"
component is supposed to be a child of "foo". And all components are children
of the unnamed root component.
By default, all messages logged by wxWidgets originate from "wx" component or
one of its subcomponents such as "wx/net/ftp", while the messages logged by
your own code are assigned empty log component. To change this, you need to
define @c wxLOG_COMPONENT to a string uniquely identifying each component, e.g.
you could give it the value "MyProgram" by default and re-define it as
"MyProgram/DB" in the module working with the database and "MyProgram/DB/Trans"
in its part managing the transactions. Then you could use
wxLog::SetComponentLevel() in the following ways:
@code
// disable all database error messages, everybody knows databases never
// fail anyhow
wxLog::SetComponentLevel("MyProgram/DB", wxLOG_FatalError);
// but enable tracing for the transactions as somehow our changes don't
// get committed sometimes
wxLog::SetComponentLevel("MyProgram/DB/Trans", wxLOG_Trace);
// also enable tracing messages from wxWidgets dynamic module loading
// mechanism
wxLog::SetComponentLevel("wx/base/module", wxLOG_Trace);
@endcode
Notice that the log level set explicitly for the transactions code overrides
the log level of the parent component but that all other database code
subcomponents inherit its setting by default and so won't generate any log
messages at all.
@section overview_log_targets Log Targets
After having enumerated all the functions which are normally used to log the
messages, and why would you want to use them, we now describe how all this
works.
wxWidgets has the notion of a <em>log target</em>: it is just a class deriving
from wxLog. As such, it implements the virtual functions of the base class
which are called when a message is logged. Only one log target is @e active at
any moment, this is the one used by @ref group_funcmacro_log "wxLogXXX() functions".
The normal usage of a log object (i.e. object of a class derived from wxLog) is
to install it as the active target with a call to @e SetActiveTarget() and it
will be used automatically by all subsequent calls to
@ref group_funcmacro_log "wxLogXXX() functions".
To create a new log target class you only need to derive it from wxLog and
override one or several of wxLog::DoLogRecord(), wxLog::DoLogTextAtLevel() and
wxLog::DoLogText() in it. The first one is the most flexible and allows you to
change the formatting of the messages, dynamically filter and redirect them and
so on -- all log messages, except for those generated by wxLogFatalError(),
pass by this function. wxLog::DoLogTextAtLevel() should be overridden if you
simply want to redirect the log messages somewhere else, without changing their
formatting. Finally, it is enough to override wxLog::DoLogText() if you only
want to redirect the log messages and the destination doesn't depend on the
message log level.
There are some predefined classes deriving from wxLog and which might be
helpful to see how you can create a new log target class and, of course, may
also be used without any change. There are:
@li wxLogStderr: This class logs messages to a <tt>FILE *</tt>, using stderr by
default as its name suggests.
@li wxLogStream: This class has the same functionality as wxLogStderr, but uses
@e ostream and cerr instead of <tt>FILE *</tt> and stderr.
@li wxLogGui: This is the standard log target for wxWidgets applications (it is
used by default if you don't do anything) and provides the most reasonable
handling of all types of messages for given platform.
@li wxLogWindow: This log target provides a "log console" which collects all
messages generated by the application and also passes them to the previous
active log target. The log window frame has a menu allowing user to clear
the log, close it completely or save all messages to file.
@li wxLogBuffer: This target collects all the logged messages in an internal
buffer allowing to show them later to the user all at once.
@li wxLogNull: The last log class is quite particular: it doesn't do anything.
The objects of this class may be instantiated to (temporarily) suppress
output of @e wxLogXXX() functions. As an example, trying to open a
non-existing file will usually provoke an error message, but if for some
reasons it is unwanted, just use this construction:
@code
wxFile file;
// wxFile.Open() normally complains if file can't be opened, we don't want it
{
wxLogNull logNo;
if ( !file.Open("bar") )
{
// ... process error ourselves ...
}
} // ~wxLogNull called, old log sink restored
wxLogMessage("..."); // ok
@endcode
@see @ref group_class_logging "Logging Classes"
The log targets can also be combined: for example you may wish to redirect the
messages somewhere else (for example, to a log file) but also process them as
normally. For this the wxLogChain, wxLogInterposer, and wxLogInterposerTemp can
be used.
@section overview_log_mt Logging in Multi-Threaded Applications
Starting with wxWidgets 2.9.1, logging functions can be safely called from any
thread. Messages logged from threads other than the main one will be buffered
until wxLog::Flush() is called in the main thread (which usually happens during
idle time, i.e. after processing all pending events) and will be really output
only then. Notice that the default GUI logger already only output the messages
when it is flushed, so by default messages from the other threads will be shown
more or less at the same moment as usual. However if you define a custom log
target, messages may be logged out of order, e.g. messages from the main thread
with later timestamp may appear before messages with earlier timestamp logged
from other threads. wxLog does however guarantee that messages logged by each
thread will appear in order in which they were logged.
Also notice that wxLog::EnableLogging() and wxLogNull class which uses it only
affect the current thread, i.e. logging messages may still be generated by the
other threads after a call to @c EnableLogging(false).
@section overview_log_customize Logging Customization
To completely change the logging behaviour you may define a custom log target.
For example, you could define a class inheriting from wxLog which shows all the
log messages in some part of your main application window reserved for the
message output without interrupting the user work flow with modal message
boxes.
To use your custom log target you may either call wxLog::SetActiveTarget() with
your custom log object or create a wxAppTraits-derived class and override
wxAppTraits::CreateLogTarget() virtual method in it and also override wxApp::CreateTraits()
to return an instance of your custom traits object. Notice that in the latter
case you should be prepared for logging messages early during the program
startup and also during program shutdown so you shouldn't rely on existence of
the main application window, for example. You can however safely assume that
GUI is (already/still) available when your log target as used as wxWidgets
automatically switches to using wxLogStderr if it isn't.
There are several methods which may be overridden in the derived class to
customize log messages handling: wxLog::DoLogRecord(), wxLog::DoLogTextAtLevel()
and wxLog::DoLogText().
The last method is the simplest one: you should override it if you simply
want to redirect the log output elsewhere, without taking into account the
level of the message. If you do want to handle messages of different levels
differently, then you should override wxLog::DoLogTextAtLevel().
Additionally, you can customize the way full log messages are constructed from
the components (such as time stamp, source file information, logging thread ID
and so on). This task is performed by wxLogFormatter class so you need to
derive a custom class from it and override its Format() method to build the log
messages in desired way. Notice that if you just need to modify (or suppress)
the time stamp display, overriding FormatTime() is enough.
Finally, if even more control over the output format is needed, then
DoLogRecord() can be overridden as it allows to construct custom messages
depending on the log level or even do completely different things depending
on the message severity (for example, throw away all messages except
warnings and errors, show warnings on the screen and forward the error
messages to the user's (or programmer's) cell phone -- maybe depending on
whether the timestamp tells us if it is day or night in the current time
zone).
The @e dialog sample illustrates this approach by defining a custom log target
customizing the dialog used by wxLogGui for the single messages.
@section overview_log_tracemasks Using Trace Masks
Notice that the use of log trace masks is hardly necessary any longer in
current wxWidgets version as the same effect can be achieved by using
different log components for different log statements of any level. Please
see @ref overview_log_enable for more information about the log components.
The functions below allow some limited customization of wxLog behaviour
without writing a new log target class (which, aside from being a matter of
several minutes, allows you to do anything you want).
The verbose messages are the trace messages which are not disabled in the
release mode and are generated by wxLogVerbose().
They are not normally shown to the user because they present little interest,
but may be activated, for example, in order to help the user find some program
problem.
As for the (real) trace messages, their handling depends on the currently
enabled trace masks: if wxLog::AddTraceMask() was called for the mask of the given
message, it will be logged, otherwise nothing happens.
For example,
@code
wxLogTrace( wxTRACE_OleCalls, "IFoo::Bar() called" );
@endcode
will log the message if it was preceded by:
@code
wxLog::AddTraceMask( wxTRACE_OleCalls );
@endcode
The standard trace masks are given in wxLogTrace() documentation.
*/

View File

@@ -0,0 +1,149 @@
/////////////////////////////////////////////////////////////////////////////
// Name: mbconvclasses.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_mbconv wxMBConv Overview
@tableofcontents
The wxMBConv classes in wxWidgets enable the application to easily convert
between Unicode and the variety of 8-bit encoding systems if you still need to
use them.
@see @ref group_class_conv
@section overview_mbconv_need Background: The Need for Conversion
wxWidgets always uses Unicode internally, for many good reasons already
abundantly described everywhere. By default is uses UTF-16 under Microsoft
Windows and UTF-32 under all the other systems, but a special build option can
be enabled to use UTF-8 for the internal representation.
Unless this option is enabled, the most common conversion operation is
converting between this internal representation and UTF-8. This can be done
using wxString::utf8_str() and wxString::FromUTF8() functions and, in many
cases, they are the only conversion-related functions that you will need and
you can stop reading this document now.
But if you need to support conversions to other, legacy, encodings, such as
Shift-JIS or KOI8-R, you will need to use the conversion classes directly, in
which case please read on.
@section overview_mbconv_classes wxMBConv Classes
The base class for all these conversions is the wxMBConv class (which itself
implements standard libc locale conversion). Derived classes include
wxMBConvLibc, several different wxMBConvUTFxxx classes, and wxCSConv, which
implement different kinds of conversions. You can also derive your own class
for your own custom encoding and use it, should you need it. All you need to do
is override the `ToWChar()` and `FromWChar()` methods. Note that these methods
are not used when using these classes, however: even if this would be possible,
it is more convenient to use the helper `cMB2WC()` and `cWC2MB()` ones wrapping
them (they read as "convert multi-byte to wide-character" and vice versa,
respectively).
@section overview_mbconv_objects wxMBConv Objects
Several of the wxWidgets-provided wxMBConv classes have predefined instances
(wxConvLibc, wxConvFileName, wxConvUTF7, wxConvUTF8, wxConvLocal). You can use
these predefined objects directly, or you can instantiate your own objects.
A variable, wxConvCurrent, points to the conversion object that is used if the
conversion is not specified. By default, it points to wxConvLibc or
wxConvLocal, depending on which works best on the current platform.
@section overview_mbconv_csconv wxCSConv
The wxCSConv class is special because when it is instantiated, you can tell it
which character set it should use, which makes it meaningful to keep many
instances of them around, each with a different character set (or you can
create a wxCSConv instance on the fly).
The predefined wxCSConv instance, wxConvLocal, is preset to use the default
user character set, but you should rarely need to use it directly, it is better
to go through wxConvCurrent.
@section overview_mbconv_converting Converting Strings
Once you have chosen which object you want to use to convert your text, here is
how you would use them with wxString. These examples all assume that you are
using a Unicode build of wxWidgets, although they will still compile in a
non-Unicode build (they just won't convert anything).
Example 1: Constructing a wxString from input in current encoding.
@code
wxString str(input_data, *wxConvCurrent);
@endcode
Example 2: Input in UTF-8 encoding.
@code
wxString str(input_data, wxConvUTF8);
@endcode
Note that the same task can be accomplished more clearly by using
wxString::FromUTF8().
Example 3: Input in KOI8-R. Construction of wxCSConv instance on the fly.
@code
wxString str(input_data, wxCSConv("koi8-r"));
@endcode
Example 4: Printing a wxString to stdout in UTF-8 encoding.
@code
puts(str.mb_str(wxConvUTF8));
@endcode
Note that the same can be done more easily by using
@code
puts(str.utf8_str());
@endcode
Example 5: Printing a wxString to stdout in custom encoding. Using
preconstructed wxCSConv instance.
@code
wxCSConv cust(user_encoding);
printf("Data: %s\n", (const char*) str.mb_str(cust));
@endcode
@note Since mb_str() returns a temporary wxCharBuffer to hold the result of the
conversion, you need to explicitly cast it to const char* if you use it in a
vararg context (like with printf).
@section overview_mbconv_buffers Converting Buffers
If you have specialized needs, or just don't want to use wxString, you can also
use the conversion methods of the conversion objects directly, e.g. you could
print a wide character buffer to a non-Unicode stdout:
@code
printf("Data: %s\n", (const char*) wxConvCurrent->cWC2MB(unicode_data));
@endcode
If you need to do more complex processing on the converted data, you may want
to store the temporary buffer in a local variable:
@code
const wxCharBuffer tmp_buf = wxConvCurrent->cWC2MB(unicode_data);
const char *tmp_str = (const char*) tmp_buf;
printf("Data: %s\n", tmp_str);
process_data(tmp_str);
@endcode
*/

View File

@@ -0,0 +1,167 @@
/////////////////////////////////////////////////////////////////////////////
// Name: nonenglish.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_nonenglish Writing Non-English Applications
@tableofcontents
This article describes how to write applications that communicate with the user
in a language other than English. Unfortunately many languages use different
charsets under Unix and Windows (and other platforms, to make the situation
even more complicated). These charsets usually differ in so many characters
that it is impossible to use the same texts under all platforms.
The wxWidgets library provides a mechanism that helps you avoid distributing
many identical, only differently encoded, packages with your application (e.g.
help files and menu items in iso8859-13 and windows-1257). Thanks to this
mechanism you can, for example, distribute only iso8859-13 data and it will be
handled transparently under all systems.
Please read the @ref overview_i18n which describes the locales concept.
In the following text, wherever @e iso8859-2 and @e windows-1250 are used, any
encodings are meant and any encodings may be substituted there.
@section overview_nonenglish_locales Locales
The best way to ensure correctly displayed texts in a GUI across platforms is
to use locales. Write your in-code messages in English or without diacritics
and put real messages into the message catalog (see @ref overview_i18n).
A standard .po file begins with a header like this:
@code
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Free Software Foundation, Inc.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 1999-02-19 16:03+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
@endcode
Note this particular line:
@code
"Content-Type: text/plain; charset=CHARSET\n"
@endcode
It specifies the charset used by the catalog. All strings in the catalog are
encoded using this charset.
You have to fill in proper charset information. Your .po file may look like
this after doing so:
@code
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Free Software Foundation, Inc.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 1999-02-19 16:03+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso8859-2\n"
"Content-Transfer-Encoding: 8bit\n"
@endcode
(Make sure that the header is @b not marked as @e fuzzy.)
wxWidgets is able to use this catalog under any supported platform
(although iso8859-2 is a Unix encoding and is normally not understood by
Windows).
How is this done? When you tell the wxLocale class to load a message catalog
that contains a correct header, it checks the charset. The catalog is then
converted to the charset used (see wxLocale::GetSystemEncoding and
wxLocale::GetSystemEncodingName) by the user's operating system.
@section overview_nonenglish_strings Non-English Strings or 8-bit Characters in Source
By convention, you should only use characters without diacritics (i.e. 7-bit
ASCII strings) for msgids in the source code and write them in English.
If you port software to wxWidgets, you may be confronted with legacy source
code containing non-English string literals. Instead of translating the strings
in the source code to English and putting the original strings into message
catalog, you may configure wxWidgets to use non-English msgids and translate to
English using message catalogs:
@li If you use the program @c xgettext to extract the strings from the source
code, specify the option <tt>\--from-code=@<source code charset@></tt>.
@li Specify the source code language and charset as arguments to
wxLocale::AddCatalog. For example:
@code
locale.AddCatalog("myapp", wxLANGUAGE_GERMAN, "iso-8859-1");
@endcode
@section overview_nonenglish_fontmapping Font Mapping
You can use @ref overview_mbconv and wxFontMapper to display text:
@code
if (!wxFontMapper::Get()->IsEncodingAvailable(enc, facename))
{
wxFontEncoding alternative;
if (wxFontMapper::Get()->GetAltForEncoding(enc, &alternative,
facename, false))
{
wxCSConv convFrom(wxFontMapper::Get()->GetEncodingName(enc));
wxCSConv convTo(wxFontMapper::Get()->GetEncodingName(alternative));
text = wxString(text.mb_str(convFrom), convTo);
}
else
...failure (or we may try iso8859-1/7bit ASCII)...
}
...display text...
@endcode
@section overview_nonenglish_converting Converting Data
You may want to store all program data (created documents etc.) in the same
encoding, let's say @c utf-8. You can use wxCSConv to convert data to the
encoding used by the system your application is running on (see
wxLocale::GetSystemEncoding).
@section overview_nonenglish_help Help Files
If you're using wxHtmlHelpController there is no problem at all. You only need
to make sure that all the HTML files contain the META tag:
@code
<meta http-equiv="Content-Type" content="text/html; charset=iso8859-2">
@endcode
Also, the hhp project file needs one additional line in the @c OPTIONS section:
@code
Charset=iso8859-2
@endcode
This additional entry tells the HTML help controller what encoding is used in
contents and index tables.
*/

View File

@@ -0,0 +1,147 @@
/////////////////////////////////////////////////////////////////////////////
// Name: docs/doxygen/overviews/persistence.h
// Purpose: overview of persistent objects
// Author: Vadim Zeitlin
// Created: 2009-01-23
// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_persistence Persistent Objects Overview
@tableofcontents
Persistent objects are simply the objects which automatically save their state
when they are destroyed and restore it when they are recreated, even during
another program invocation.
Most often, persistent objects are, in fact, persistent windows as it is
especially convenient to automatically restore the UI state when the program is
restarted but an object of any class can be made persistent. Moreover,
persistence is implemented in a non-intrusive way so that the original object
class doesn't need to be modified at all in order to add support for saving and
restoring its properties.
The persistence framework includes the following components:
- wxPersistenceManager which all persistent objects register themselves with.
This class handles actual saving and restoring of persistent data as well as
various global aspects of persistence, e.g. it can be used to disable
restoring the saved data.
- wxPersistentObject is the base class for all persistent objects or, rather,
adaptors for the persistent objects as this class main purpose is to provide
the bridge between the original class -- which has no special persistence
support -- and wxPersistenceManager,
- wxPersistentWindow<> which derives from wxPersistentObject and implements some
of its methods using wxWindow-specific functionality. Notably,
wxPersistenceManager handles the destruction of persistent windows
automatically implicitly while it has to be done explicitly for the
arbitrary persistent objects.
- wxCreatePersistentObject() function which is used to create the
appropriate persistence adapter for the object.
@section persistence_using Using Persistent Windows
wxWidgets has built-in support for a (constantly growing) number of controls.
Currently the following classes are supported:
- wxTopLevelWindow (and hence wxFrame and wxDialog), see wxPersistentTLW.
- wxBookCtrlBase (i.e. wxNotebook, wxListbook, wxToolbook and wxChoicebook),
see wxPersistentBookCtrl and wxPersistentTreeBookCtrl.
- wxDataViewCtrl (and derivatives such as wxDataViewListCtrl), see
wxPersistentDataViewCtrl.
- wxCheckBox, see wxPersistentCheckBox.
- wxComboBox, see wxPersistentComboBox.
- wxRadioButton, see wxPersistentRadioButton.
To automatically save and restore the properties of the windows of classes
listed above you need to:
-# Set a unique name for the window by either using this name in its
constructor or calling wxWindow::SetName(): this step is important as the
name is used in the configuration file and so must be unique among all
windows of the same class.
-# Call wxPersistenceManager::Register() at any moment after creating the
window and then wxPersistenceManager::Restore() when the settings may be
restored (which can't be always done immediately, e.g. often the window
needs to be populated first). If settings can be restored immediately after
the window creation, as is often the case for wxTopLevelWindow, for
example, then wxPersistenceManager::RegisterAndRestore() can be used to do
both at once.
-# If you do not want the settings for the window to be saved (for example
the changes to the dialog size are usually not saved if the dialog was
cancelled), you need to call wxPersistenceManager::Unregister() manually.
Otherwise the settings will be automatically saved when the control itself
is destroyed.
A convenient wxPersistentRegisterAndRestore() helper function can be used to
perform the first steps at once, e.g. to automatically save and restore the
position of a @c MyFrame window in your application, you need to only do the
following:
@code
#include <wx/persist/toplevel.h>
...
MyFrame::MyFrame(wxWindow* parent, ...)
: wxFrame(parent, ...)
{
... all the other initialization ...
// Restore the previously saved geometry, if any, and register this frame
// for its geometry to be saved when it is closed using the given wxConfig
// key name.
if ( !wxPersistentRegisterAndRestore(this, "my_frame_name") )
{
// Choose some custom default size for the first run -- or don't do
// anything at all and let the system use the default initial size.
SetClientSize(FromDIP(wxSize(800, 600)));
}
Show(true);
}
@endcode
And here is an example of using a notebook control which automatically
remembers the last open page without using the helper function:
@code
wxNotebook *book = new wxNotebook(parent, wxID_ANY);
book->SetName("MyBook"); // do not use the default name
book->AddPage(...);
book->AddPage(...);
book->AddPage(...);
// We don't check for the return value here as the first page is selected
// by default anyhow and we just keep this selection in this case.
wxPersistenceManager::Get().RegisterAndRestore(book);
@endcode
@section persistence_defining Defining Custom Persistent Windows
User-defined classes can be easily integrated with wxPersistenceManager. To add
support for your custom class @c MyWidget you just need to:
-# Define a new `MyPersistentWidget` class inheriting from
`wxPersistentWindow<MyWidget>`.
-# Implement its pure virtual GetKind() method returning a unique string
identifying all `MyWidget` objects, typically something like `"widget"`
-# Implement its pure virtual Save() and Restore() methods to actually save
and restore the widget settings using wxPersistentObject::SaveValue() and
wxPersistentObject::RestoreValue() methods.
-# Define wxCreatePersistentObject() overload taking `MyWidget*` and
returning a new `MyPersistentWidget` object.
If you want to add persistence support for a class not deriving from wxWindow,
you need to derive `MyPersistentWidget` directly from wxPersistentObject and
so implement its pure virtual wxPersistentObject::GetName() method too.
Additionally, you must ensure that wxPersistenceManager::SaveAndUnregister() is
called when your object is destroyed as this can be only done automatically for
windows.
*/

View File

@@ -0,0 +1,202 @@
/////////////////////////////////////////////////////////////////////////////
// Name: printing.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_printing Printing Framework Overview
@tableofcontents
The printing framework relies on the application to provide classes whose
member functions can respond to particular requests, such as 'print this page'
or 'does this page exist in the document?'. This method allows wxWidgets to
take over the housekeeping duties of turning preview pages, calling the print
dialog box, creating the printer device context, and so on: the application can
concentrate on the rendering of the information onto a device context.
In most cases, the only class you will need to derive from is wxPrintout; all
others will be used as-is.
A brief description of each class's role and how they work together follows.
For the special case of printing under Unix, where various different printing
backends have to be offered, please have a look at @ref overview_unixprinting.
@see @ref group_class_printing
@section overview_printing_printout wxPrintout
A document's printing ability is represented in an application by a derived
wxPrintout class. This class prints a page on request, and can be passed to the
Print function of a wxPrinter object to actually print the document, or can be
passed to a wxPrintPreview object to initiate previewing. The following code
(from the printing sample) shows how easy it is to initiate printing,
previewing and the print setup dialog, once the wxPrintout functionality has
been defined. Notice the use of MyPrintout for both printing and previewing.
All the preview user interface functionality is taken care of by wxWidgets. For
more details on how MyPrintout is defined, please look at the printout sample
code.
@code
case WXPRINT_PRINT:
{
wxPrinter printer;
MyPrintout printout("My printout");
printer.Print(this, &printout, true);
break;
}
case WXPRINT_PREVIEW:
{
// Pass two printout objects: for preview, and possible printing.
wxPrintPreview *preview = new wxPrintPreview(new MyPrintout, new MyPrintout);
wxPreviewFrame *frame = new wxPreviewFrame(preview, this,
"Demo Print Preview");
frame->Initialize();
frame->Centre(wxBOTH);
frame->Show(true);
break;
}
@endcode
wxPrintout assembles the printed page and (using your subclass's overrides)
writes requested pages to a wxDC that is passed to it. This wxDC could be a
wxMemoryDC (for displaying the preview image on-screen), a wxPrinterDC (for
printing under MSW and Mac), or a wxPostScriptDC (for printing under GTK or
generating PostScript output).
The @ref overview_docview "document/view framework" creates a default
wxPrintout object for every view, calling wxView::OnDraw() to achieve a
prepackaged print/preview facility.
If your window classes have a Draw(wxDC *dc) routine to do screen rendering,
your wxPrintout subclass will typically call those routines to create portions
of the image on your printout. Your wxPrintout subclass can also make its own
calls to its wxDC to draw headers, footers, page numbers, etc.
The scaling of the drawn image typically differs from the screen to the preview
and printed images. This class provides a set of routines named
FitThisSizeToXXX(), MapScreenSizeToXXX(), and GetLogicalXXXRect, which can be
used to set the user scale and origin of the wxPrintout's DC so that your class
can easily map your image to the printout without getting into the details of
screen and printer PPI and scaling. See the printing sample for examples of how
these routines are used.
@section overview_printing_printer wxPrinter
Class wxPrinter encapsulates the platform-dependent print function with a common
interface. In most cases, you will not need to derive a class from wxPrinter;
simply create a wxPrinter object in your Print function as in the example above.
@section overview_printing_printpreview wxPrintPreview
Class wxPrintPreview manages the print preview process. Among other things, it
constructs the wxDCs that get passed to your wxPrintout subclass for printing
and manages the display of multiple pages, a zoomable preview image, and so
forth. In most cases you will use this class as-is, but you can create your own
subclass, for example, to change the layout or contents of the preview window.
@section overview_printing_printerdc wxPrinterDC
Class wxPrinterDC is the wxDC that represents the actual printed page under MSW
and Mac. During printing, an object of this class will be passed to your derived
wxPrintout object to draw upon. The size of the wxPrinterDC will depend on the
paper orientation and the resolution of the printer.
There are two important rectangles in printing: the <em>page rectangle</em>
defines the printable area seen by the application, and under MSW and Mac, it
is the printable area specified by the printer. (For PostScript printing, the
page rectangle is the entire page.) The inherited function
wxDC::GetSize() returns the page size in device pixels. The
point (0,0) on the wxPrinterDC represents the top left corner of the page
rectangle; that is, the page rect is given by wxRect(0, 0, w, h), where (w,h)
are the values returned by GetSize.
The <em>paper rectangle</em>, on the other hand, represents the entire paper
area including the non-printable border. Thus, the coordinates of the top left
corner of the paper rectangle will have small negative values, while the width
and height will be somewhat larger than that of the page rectangle. The
wxPrinterDC-specific function wxPrinterDC::GetPaperRect() returns the paper
rectangle of the given wxPrinterDC.
@section overview_printing_postscriptdc wxPostScriptDC
Class wxPostScriptDC is the wxDC that represents the actual printed page under
GTK and other PostScript printing. During printing, an object of this class
will be passed to your derived wxPrintout object to draw upon. The size of the
wxPostScriptDC will depend upon the wxPrintData used to construct it.
Unlike a wxPrinterDC, there is no distinction between the page rectangle and
the paper rectangle in a wxPostScriptDC; both rectangles are taken to represent
the entire sheet of paper.
@section overview_printing_printdialog wxPrintDialog
Class wxPrintDialog puts up the standard print dialog, which allows you to
select the page range for printing (as well as many other print settings, which
may vary from platform to platform). You provide an object of type
wxPrintDialogData to the wxPrintDialog at construction, which is used to
populate the dialog.
@section overview_printing_printdata wxPrintData
Class wxPrintData is a subset of wxPrintDialogData that is used (internally) to
initialize a wxPrinterDC or wxPostScriptDC. (In fact, a wxPrintData is a data
member of a wxPrintDialogData and a wxPageSetupDialogData). Essentially,
wxPrintData contains those bits of information from the two dialogs necessary
to configure the wxPrinterDC or wxPostScriptDC (e.g., size, orientation, etc.).
You might wish to create a global instance of this object to provide
call-to-call persistence to your application's print settings.
@section overview_printing_printdialogdata wxPrintDialogData
Class wxPrintDialogData contains the settings entered by the user in the print
dialog. It contains such things as page range, number of copies, and so forth.
In most cases, you won't need to access this information; the framework takes
care of asking your wxPrintout derived object for the pages requested by the
user.
@section overview_printing_pagesetupdialog wxPageSetupDialog
Class wxPageSetupDialog puts up the standard page setup dialog, which allows
you to specify the orientation, paper size, and related settings. You provide
it with a wxPageSetupDialogData object at initialization, which is used to
populate the dialog; when the dialog is dismissed, this object contains the
settings chosen by the user, including orientation and/or page margins.
Note that on Macintosh, the native page setup dialog does not contain entries
that allow you to change the page margins. You can use the Mac-specific class
wxMacPageMarginsDialog (which, like wxPageSetupDialog, takes a
wxPageSetupDialogData object in its constructor) to provide this capability;
see the printing sample for an example.
@section overview_printing_pagesetupdialogdata wxPageSetupDialogData
Class wxPageSetupDialogData contains settings affecting the page size (paper
size), orientation, margins, and so forth. Note that not all platforms populate
all fields; for example, the MSW page setup dialog lets you set the page
margins while the Mac setup dialog does not.
You will typically create a global instance of each of a wxPrintData and
wxPageSetupDialogData at program initiation, which will contain the default
settings provided by the system. Each time the user calls up either the
wxPrintDialog or the wxPageSetupDialog, you pass these data structures to
initialize the dialog values and to be updated by the dialog. The framework
then queries these data structures to get information like the printed page
range (from the wxPrintDialogData) or the paper size and/or page orientation
(from the wxPageSetupDialogData).
*/

View File

@@ -0,0 +1,951 @@
/////////////////////////////////////////////////////////////////////////////
// Name: propgrid.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_propgrid wxPropertyGrid Overview
@tableofcontents
wxPropertyGrid is a specialized grid for editing properties - in other words
name = value pairs. List of ready-to-use property classes include strings,
numbers, flag sets, fonts, colours and many others. It is possible, for
example, to categorize properties, set up a complete tree-hierarchy, add more
than two columns, and set arbitrary per-property attributes.
@see wxPropertyGrid, wxPropertyGridEvent, wxPropertyGridManager,
wxPropertyGridPage, wxPGProperty
@section propgrid_basics Creating and Populating wxPropertyGrid
As seen here, wxPropertyGrid is constructed in the same way as
other wxWidgets controls:
@code
// Necessary header file
#include <wx/propgrid/propgrid.h>
...
// Assumes code is in frame/dialog constructor
// Construct wxPropertyGrid control
wxPropertyGrid* pg = new wxPropertyGrid(
this, // parent
PGID, // id
wxDefaultPosition, // position
wxDefaultSize, // size
// Here are just some of the supported window styles
wxPG_AUTO_SORT | // Automatic sorting after items added
wxPG_SPLITTER_AUTO_CENTER | // Automatically center splitter until user manually adjusts it
// Default style
wxPG_DEFAULT_STYLE );
// Window style flags are at premium, so some less often needed ones are
// available as extra window styles (wxPG_EX_xxx) which must be set using
// SetExtraStyle member function. wxPG_EX_HELP_AS_TOOLTIPS, for instance,
// allows displaying help strings as tool tips.
pg->SetExtraStyle( wxPG_EX_HELP_AS_TOOLTIPS );
@endcode
(for complete list of new window styles, see @ref propgrid_window_styles)
wxPropertyGrid is usually populated with lines like this:
@code
pg->Append( new wxStringProperty("Label", "Name", "Initial Value") );
@endcode
Naturally, wxStringProperty is a property class. Only the first function argument (label)
is mandatory. Second one, name, defaults to label and, third, the initial value, to
default value. If constant wxPG_LABEL is used as the name argument, then the label is
automatically used as a name as well (this is more efficient than manually defining both
as the same). Use of empty name is discouraged and will sometimes result in run-time error.
Note that all property class constructors have quite similar constructor argument list.
To demonstrate other common property classes, here's another code snippet:
@code
// Add int property
pg->Append( new wxIntProperty("IntProperty", wxPG_LABEL, 12345678) );
// Add float property (value type is actually double)
pg->Append( new wxFloatProperty("FloatProperty", wxPG_LABEL, 12345.678) );
// Add a bool property
pg->Append( new wxBoolProperty("BoolProperty", wxPG_LABEL, false) );
// A string property that can be edited in a separate editor dialog.
pg->Append( new wxLongStringProperty("LongStringProperty",
wxPG_LABEL,
"This is much longer string than the "
"first one. Edit it by clicking the button."));
// String editor with dir selector button.
pg->Append( new wxDirProperty("DirProperty", wxPG_LABEL, ::wxGetUserHome()) );
// wxArrayStringProperty embeds a wxArrayString.
pg->Append( new wxArrayStringProperty("Label of ArrayStringProperty",
"NameOfArrayStringProp"));
// A file selector property.
pg->Append( new wxFileProperty("FileProperty", wxPG_LABEL, wxEmptyString) );
// Extra: set wild card for file property (format same as in wxFileDialog).
pg->SetPropertyAttribute( "FileProperty",
wxPG_FILE_WILDCARD,
"All files (*.*)|*.*" );
@endcode
Operations on properties are usually done by directly calling wxPGProperty's
or wxPropertyGridInterface's member functions. wxPropertyGridInterface is an
abstract base class for property containers such as wxPropertyGrid,
wxPropertyGridManager, and wxPropertyGridPage. Note however that wxPGProperty's
member functions generally do not refresh the grid.
wxPropertyGridInterface's property operation member functions , such as
SetPropertyValue() and DisableProperty(), all accept a special wxPGPropArg id
argument, using which you can refer to properties either by their pointer
(for performance) or by their name (for convenience). For instance:
@code
// Add a file selector property.
wxPGProperty* prop = pg->Append( new wxFileProperty("FileProperty",
wxPG_LABEL,
wxEmptyString) );
// Valid: Set wild card by name
pg->SetPropertyAttribute( "FileProperty",
wxPG_FILE_WILDCARD,
"All files (*.*)|*.*" );
// Also Valid: Set wild card by property pointer
pg->SetPropertyAttribute( prop,
wxPG_FILE_WILDCARD,
"All files (*.*)|*.*" );
@endcode
Using pointer is faster, since it doesn't require hash map lookup. Anyway,
you can always get property pointer (wxPGProperty*) as return value from Append()
or Insert(), or by calling wxPropertyGridInterface::GetPropertyByName() or
just plain GetProperty().
@section propgrid_categories Categories
wxPropertyGrid has a hierarchic property storage and display model, which
allows property categories to hold child properties and even other
categories. Other than that, from the programmer's point of view, categories
can be treated exactly the same as "other" properties. For example, despite
its name, GetPropertyByName() also returns a category by name. Note however
that sometimes the label of a property category may be referred as caption
(for example, there is wxPropertyGrid::SetCaptionTextColour() method
that sets text colour of property category labels).
When category is added at the top (i.e. root) level of the hierarchy,
it becomes a *current category*. This means that all other (non-category)
properties after it are automatically appended to it. You may add
properties to specific categories by using wxPropertyGridInterface::Insert
or wxPropertyGridInterface::AppendIn.
Category code sample:
@code
// One way to add category (similar to how other properties are added)
pg->Append( new wxPropertyCategory("Main") );
// All these are added to "Main" category
pg->Append( new wxStringProperty("Name") );
pg->Append( new wxIntProperty("Age",wxPG_LABEL,25) );
pg->Append( new wxIntProperty("Height",wxPG_LABEL,180) );
pg->Append( new wxIntProperty("Weight") );
// Another one
pg->Append( new wxPropertyCategory("Attributes") );
// All these are added to "Attributes" category
pg->Append( new wxIntProperty("Intelligence") );
pg->Append( new wxIntProperty("Agility") );
pg->Append( new wxIntProperty("Strength") );
@endcode
@section propgrid_parentprops Tree-like Property Structure
Basically any property can have children. There are few limitations, however.
@remarks
- Names of properties with non-category, non-root parents are not stored in global
hash map. Instead, they can be accessed with strings like "Parent.Child".
For instance, in the sample below, child property named "Max. Speed (mph)"
can be accessed by global name "Car.Speeds.Max Speed (mph)".
- If you want to property's value to be a string composed of the child property values,
you must use wxStringProperty as parent and use magic string "<composed>" as its
value.
- Events (eg. change of value) that occur in parent do not propagate to children. Events
that occur in children will propagate to parents, but only if they are wxStringProperties
with "<composed>" value.
Sample:
@code
wxPGProperty* carProp = pg->Append(new wxStringProperty("Car",
wxPG_LABEL,
"<composed>"));
pg->AppendIn(carProp, new wxStringProperty("Model",
wxPG_LABEL,
"Lamborghini Diablo SV"));
pg->AppendIn(carProp, new wxIntProperty("Engine Size (cc)",
wxPG_LABEL,
5707) );
wxPGProperty* speedsProp = pg->AppendIn(carProp,
new wxStringProperty("Speeds",
wxPG_LABEL,
"<composed>"));
pg->AppendIn( speedsProp, new wxIntProperty("Max. Speed (mph)",
wxPG_LABEL,290) );
pg->AppendIn( speedsProp, new wxFloatProperty("0-100 mph (sec)",
wxPG_LABEL,3.9) );
pg->AppendIn( speedsProp, new wxFloatProperty("1/4 mile (sec)",
wxPG_LABEL,8.6) );
// This is how child property can be referred to by name
pg->SetPropertyValue( "Car.Speeds.Max. Speed (mph)", 300 );
pg->AppendIn(carProp, new wxIntProperty("Price ($)",
wxPG_LABEL,
300000) );
// Displayed value of "Car" property is now very close to this:
// "Lamborghini Diablo SV; 5707 [300; 3.9; 8.6] 300000"
@endcode
@section propgrid_enumandflags wxEnumProperty and wxFlagsProperty
wxEnumProperty is used when you want property's (integer or string) value
to be selected from a popup list of choices.
Creating wxEnumProperty is slightly more complex than those described
earlier. You have to provide list of constant labels, and optionally relevant
values (if label indexes are not sufficient).
@remarks
- Value wxPG_INVALID_VALUE (equals INT_MAX) is not allowed as list
item value.
A very simple example:
@code
//
// Using wxArrayString
//
wxArrayString arrDiet;
arrDiet.Add("Herbivore");
arrDiet.Add("Carnivore");
arrDiet.Add("Omnivore");
pg->Append( new wxEnumProperty("Diet",
wxPG_LABEL,
arrDiet) );
//
// Using wxChar* array
//
const wxChar* arrayDiet[] =
{ wxT("Herbivore"), wxT("Carnivore"), wxT("Omnivore"), nullptr };
pg->Append( new wxEnumProperty("Diet",
wxPG_LABEL,
arrayDiet) );
@endcode
Here's extended example using values as well:
@code
//
// Using wxArrayString and wxArrayInt
//
wxArrayString arrDiet;
arrDiet.Add("Herbivore");
arrDiet.Add("Carnivore");
arrDiet.Add("Omnivore");
wxArrayInt arrIds;
arrIds.Add(40);
arrIds.Add(45);
arrIds.Add(50);
// Note that the initial value (the last argument) is the actual value,
// not index or anything like that. Thus, our value selects "Omnivore".
pg->Append( new wxEnumProperty("Diet",
wxPG_LABEL,
arrDiet,
arrIds,
50));
@endcode
wxPGChoices is a class where wxEnumProperty, and other properties which
require storage for list of items, actually stores strings and values. It is
used to facilitate reference counting, and therefore recommended way of
adding items when multiple properties share the same set.
You can use wxPGChoices directly as well, filling it and then passing it
to the constructor. In fact, if you wish to display bitmaps next to labels,
your best choice is to use this approach.
@code
wxPGChoices chs;
chs.Add("Herbivore", 40);
chs.Add("Carnivore", 45);
chs.Add("Omnivore", 50);
// Let's add an item with bitmap, too
chs.Add("None of the above", wxBitmap(), 60);
pg->Append( new wxEnumProperty("Primary Diet",
wxPG_LABEL,
chs) );
// Add same choices to another property as well - this is efficient due
// to reference counting
pg->Append( new wxEnumProperty("Secondary Diet",
wxPG_LABEL,
chs) );
@endcode
You can later change choices of property by using wxPGProperty::AddChoice(),
wxPGProperty::InsertChoice(), wxPGProperty::DeleteChoice(), and
wxPGProperty::SetChoices().
<b>wxEditEnumProperty</b> works exactly like wxEnumProperty, except
is uses non-read-only combo box as default editor, and value is stored as
string when it is not any of the choices.
wxFlagsProperty has similar construction:
@code
const wxChar* flags_prop_labels[] = { wxT("wxICONIZE"),
wxT("wxCAPTION"), wxT("wxMINIMIZE_BOX"), wxT("wxMAXIMIZE_BOX"), nullptr };
// this value array would be optional if values matched string indexes
long flags_prop_values[] = { wxICONIZE, wxCAPTION, wxMINIMIZE_BOX,
wxMAXIMIZE_BOX };
pg->Append( new wxFlagsProperty("Window Style",
wxPG_LABEL,
flags_prop_labels,
flags_prop_values,
wxDEFAULT_FRAME_STYLE) );
@endcode
wxFlagsProperty can use wxPGChoices just the same way as wxEnumProperty
<b>Note:</b> When changing "choices" (ie. flag labels) of wxFlagsProperty,
you will need to use wxPGProperty::SetChoices() to replace all choices
at once - otherwise implicit child properties will not get updated properly.
@section propgrid_advprops Specialized Properties
This section describes the use of less often needed property classes.
To use them, you have to include <wx/propgrid/advprops.h>.
@code
// Necessary extra header file
#include <wx/propgrid/advprops.h>
...
// Date property.
pg->Append( new wxDateProperty("MyDateProperty",
wxPG_LABEL,
wxDateTime::Now()) );
// Image file property. Wild card is auto-generated from available
// image handlers, so it is not set this time.
pg->Append( new wxImageFileProperty("Label of ImageFileProperty",
"NameOfImageFileProp") );
// Font property has sub-properties. Note that we give window's font as
// initial value.
pg->Append( new wxFontProperty("Font",
wxPG_LABEL,
GetFont()) );
// Colour property with arbitrary colour.
pg->Append( new wxColourProperty("My Colour 1",
wxPG_LABEL,
wxColour(242,109,0) ) );
// System colour property.
pg->Append( new wxSystemColourProperty("My SysColour 1",
wxPG_LABEL,
wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)) );
// System colour property with custom colour.
pg->Append( new wxSystemColourProperty("My SysColour 2",
wxPG_LABEL,
wxColour(0,200,160) ) );
// Cursor property
pg->Append( new wxCursorProperty("My Cursor",
wxPG_LABEL,
wxCURSOR_ARROW));
@endcode
@section propgrid_processingvalues Processing Property Values
Properties store their values internally as wxVariant, but is also possible to
obtain them as wxAny, using implicit conversion. You can get property
values with wxPGProperty::GetValue() and
wxPropertyGridInterface::GetPropertyValue().
Below is a code example which handles wxEVT_PG_CHANGED event:
@code
void MyWindowClass::OnPropertyGridChanged(wxPropertyGridEvent& event)
{
wxPGProperty* property = event.GetProperty();
// Do nothing if event did not have associated property
if ( !property )
return;
// GetValue() returns wxVariant, but it is converted transparently to
// wxAny
wxAny value = property->GetValue();
// Also, handle the case where property value is unspecified
if ( value.IsNull() )
return;
// Handle changes in values, as needed
if ( property->GetName() == "MyStringProperty" )
OnMyStringPropertyChanged(value.As<wxString>());
else if ( property->GetName() == "MyColourProperty" )
OnMyColourPropertyChanged(value.As<wxColour>());
}
@endcode
You can get a string-representation of property's value using
wxPGProperty::GetValueAsString() or
wxPropertyGridInterface::GetPropertyValueAsString(). This particular function
is very safe to use with any kind of property.
@note There is a one case in which you may want to take extra care when
dealing with raw wxVariant values. That is, integer-type properties,
such as wxIntProperty and wxUIntProperty, store value internally as
wx(U)LongLong when number doesn't fit into standard long type. Using
<< operator to get wx(U)LongLong from wxVariant is customized to work
quite safely with various types of variant data. However, you can also
bypass this problem by using wxAny in your code instead of wxVariant.
Note that in some cases property value can be Null variant, which means
that property value is unspecified. This usually occurs only when
wxPG_EX_AUTO_UNSPECIFIED_VALUES extra window style is defined or when you
manually set property value to Null (or unspecified).
@section propgrid_iterating Iterating through a property container
You can use somewhat STL'ish iterator classes to iterate through the grid.
Here is a simple example of forward iterating through all individual
properties (not categories nor private child properties that are normally
'transparent' to application code):
@code
wxPropertyGridIterator it;
for ( it = pg->GetIterator();
!it.AtEnd();
it++ )
{
wxPGProperty* p = *it;
// Do something with the property
}
@endcode
As expected there is also a const iterator:
@code
wxPropertyGridConstIterator it;
for ( it = pg->GetIterator();
!it.AtEnd();
it++ )
{
const wxPGProperty* p = *it;
// Do something with the property
}
@endcode
You can give some arguments to GetIterator to determine which properties
get automatically filtered out. For complete list of options, see
@ref propgrid_iterator_flags. GetIterator() also accepts other arguments.
See wxPropertyGridInterface::GetIterator() for details.
This example reverse-iterates through all visible items:
@code
wxPropertyGridIterator it;
for ( it = pg->GetIterator(wxPG_ITERATE_VISIBLE, wxBOTTOM);
!it.AtEnd();
it-- )
{
wxPGProperty* p = *it;
// Do something with the property
}
@endcode
GetIterator() only works with wxPropertyGrid and the individual pages
of wxPropertyGridManager. In order to iterate through an arbitrary
property container (such as entire wxPropertyGridManager), you need to use
wxPropertyGridInterface::GetVIterator(). Note however that this virtual
iterator is limited to forward iteration.
@code
wxPGVIterator it;
for ( it = manager->GetVIterator(wxPG_ITERATE_ALL);
!it.AtEnd();
it.Next() )
{
wxPGProperty* p = it.GetProperty();
// Do something with the property
}
@endcode
@section propgrid_populating Populating wxPropertyGrid Automatically
@subsection propgrid_fromvariants Populating from List of wxVariants
Example of populating an empty wxPropertyGrid from a values stored
in an arbitrary list of wxVariants.
@code
// This is a static method that initializes *all* built-in type handlers
// available, including those for wxColour and wxFont. Refers to *all*
// included properties, so when compiling with static library, this
// method may increase the executable size noticeably.
pg->InitAllTypeHandlers();
// Get contents of the grid as a wxVariant list
wxVariant all_values = pg->GetPropertyValues();
// Populate the list with values. If a property with appropriate
// name is not found, it is created according to the type of variant.
pg->SetPropertyValues( my_list_variant );
@endcode
@subsection propgrid_fromfile Loading Population from a Text-based Storage
Class wxPropertyGridPopulator may be helpful when writing code that
loads properties from a text-source. It is used by wxPropertyGrid XRC handler,
for example.
@subsection editablestate Saving and Restoring User-Editable State
You can use wxPropertyGridInterface::SaveEditableState() and
wxPropertyGridInterface::RestoreEditableState() to save and restore
user-editable state (selected property, expanded/collapsed properties,
selected page, scrolled position, and splitter positions).
@section propgrid_events Event Handling
Probably the most important event is the Changed event which occurs when
value of any property is changed by the user. Use EVT_PG_CHANGED(id,func)
in your event table to use it.
For complete list of event types, see wxPropertyGrid class reference.
However, one type of event that might need focused attention is EVT_PG_CHANGING,
which occurs just prior property value is being changed by user. You can
acquire pending value using wxPropertyGridEvent::GetValue(), and if it is
not acceptable, call wxPropertyGridEvent::Veto() to prevent the value change
from taking place.
@code
void MyForm::OnPropertyGridChanging( wxPropertyGridEvent& event )
{
wxPGProperty* property = event.GetProperty();
if ( property == m_pWatchThisProperty )
{
// GetValue() returns the pending value, but is only
// supported by wxEVT_PG_CHANGING.
if ( event.GetValue().GetString() == g_pThisTextIsNotAllowed )
{
event.Veto();
return;
}
}
}
@endcode
@remarks On Child Property Event Handling
- For properties which have private, implicit children (wxFontProperty and
wxFlagsProperty), events occur for the main parent property only.
For other properties events occur for the children themselves. See
@ref propgrid_parentprops.
- When property's child gets changed, you can use wxPropertyGridEvent::GetMainParent()
to obtain its topmost non-category parent (useful, if you have deeply nested
properties).
@section propgrid_tooltipandhint Help String, Hint and Tool Tips
For each property you can specify two different types of help text. First,
you can use wxPropertyGridInterface::SetPropertyHelpString() or
wxPGProperty::SetHelpString() to set property's help text. Second, you
can use wxPGProperty::SetAttribute() to set property's "Hint" attribute.
Difference between hint and help string is that the hint is shown in an empty
property value cell, while help string is shown either in the description text
box, as a tool tip, or on the status bar, whichever of these is available.
To enable display of help string as tool tips, you must explicitly use
the wxPG_EX_HELP_AS_TOOLTIPS extra window style.
@section propgrid_validating Validating Property Values
There are various ways to make sure user enters only correct values. First, you
can use wxValidators similar to as you would with ordinary controls. Use
wxPropertyGridInterface::SetPropertyValidator() to assign wxValidator to
property.
Second, you can subclass a property and override wxPGProperty::ValidateValue(),
or handle wxEVT_PG_CHANGING for the same effect. Both of these ways do not
actually prevent user from temporarily entering invalid text, but they do give
you an opportunity to warn the user and block changed value from being committed
in a property.
Various validation failure options can be controlled globally with
wxPropertyGrid::SetValidationFailureBehavior(), or on an event basis by
calling wxEvent::SetValidationFailureBehavior(). Here's a code snippet of
how to handle wxEVT_PG_CHANGING, and to set custom failure behaviour and
message.
@code
void MyFrame::OnPropertyGridChanging(wxPropertyGridEvent& event)
{
wxPGProperty* property = event.GetProperty();
// You must use wxPropertyGridEvent::GetValue() to access
// the value to be validated.
wxVariant pendingValue = event.GetValue();
if ( property->GetName() == "Font" )
{
// Make sure value is not unspecified
if ( !pendingValue.IsNull() )
{
wxFont font;
font << pendingValue;
// Let's just allow Arial font
if ( font.GetFaceName() != "Arial" )
{
event.Veto();
event.SetValidationFailureBehavior(wxPG_VFB_STAY_IN_PROPERTY |
wxPG_VFB_BEEP |
wxPG_VFB_SHOW_MESSAGEBOX);
}
}
}
}
@endcode
@section propgrid_cellrender Customizing Individual Cell Appearance
You can control text colour, background colour, and attached image of
each cell in the property grid. Use wxPropertyGridInterface::SetPropertyCell() or
wxPGProperty::SetCell() for this purpose.
In addition, it is possible to control these characteristics for
wxPGChoices list items. See wxPGChoices class reference for more info.
@section propgrid_keyhandling Customizing Keyboard Handling
There is probably one preference for keyboard handling for every developer
out there, and as a conveniency control wxPropertyGrid tries to cater for
that. By the default arrow keys are used for navigating between properties,
and TAB key is used to move focus between the property editor and the
first column. When the focus is in the editor, arrow keys usually no longer
work for navigation since they are consumed by the editor.
There are mainly two functions which you can use this customize things,
wxPropertyGrid::AddActionTrigger() and wxPropertyGrid::DedicateKey().
First one can be used to set a navigation event to occur on a specific key
press and the second is used to divert a key from property editors, making it
possible for the grid to use keys normally consumed by the focused editors.
For example, let's say you want to have an ENTER-based editing scheme. That
is, editor is focused on ENTER press and the next property is selected when
the user finishes editing and presses ENTER again. Code like this would
accomplish the task:
@code
// Have property editor focus on Enter
propgrid->AddActionTrigger( wxPG_ACTION_EDIT, WXK_RETURN );
// Have Enter work as action trigger even when editor is focused
propgrid->DedicateKey( WXK_RETURN );
// Let Enter also navigate to the next property
propgrid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_RETURN );
@endcode
wxPG_ACTION_EDIT is prioritized above wxPG_ACTION_NEXT_PROPERTY so that the
above code can work without conflicts. For a complete list of available
actions, see @ref propgrid_keyboard_actions.
Here's another trick. Normally the up and down cursor keys are consumed by
the focused wxTextCtrl editor and as such can't be used for navigating between
properties when that editor is focused. However, using DedicateKey() we can
change this so that instead of the cursor keys moving the caret inside the
wxTextCtrl, they navigate between adjacent properties. As such:
@code
propgrid->DedicateKey(WXK_UP);
propgrid->DedicateKey(WXK_DOWN);
@endcode
@section propgrid_customizing Customizing Properties (without sub-classing)
In this section are presented miscellaneous ways to have custom appearance
and behaviour for your properties without all the necessary hassle
of sub-classing a property class etc.
@subsection propgrid_customimage Setting Value Image
Every property can have a small value image placed in front of the
actual value text. Built-in example of this can be seen with
wxColourProperty and wxImageFileProperty, but for others it can
be set using wxPropertyGrid::SetPropertyImage method.
@subsection propgrid_customeditor Setting Property's Editor Control(s)
You can set editor control (or controls, in case of a control and button),
of any property using wxPropertyGrid::SetPropertyEditor. Editors are passed
as wxPGEditor_EditorName, and valid built-in EditorNames are
TextCtrl, Choice, ComboBox, CheckBox, TextCtrlAndButton, ChoiceAndButton,
SpinCtrl, and DatePickerCtrl. Two last mentioned ones require call to
static member function wxPropertyGrid::RegisterAdditionalEditors().
Following example changes wxColourProperty's editor from default Choice
to TextCtrlAndButton. wxColourProperty has its internal event handling set
up so that button click events of the button will be used to trigger
colour selection dialog.
@code
wxPGProperty* colProp = new wxColourProperty("Text Colour");
pg->Append(colProp);
pg->SetPropertyEditor(colProp, wxPGEditor_TextCtrlAndButton);
@endcode
Naturally, creating and setting custom editor classes is a possibility as
well. For more information, see wxPGEditor class reference.
@subsection propgrid_editorattrs Property Attributes Recognized by Editors
<b>SpinCtrl</b> editor can make use of property's "Min", "Max", "Step" and
"Wrap" attributes.
@subsection propgrid_multiplebuttons Adding Multiple Buttons Next to an Editor
See wxPGMultiButton class reference.
@subsection propgrid_customeventhandling Handling Events Passed from Properties
@c wxEVT_BUTTON: Occurs when editor button click is not handled by the property
itself (as is the case, for example, if you set property's editor
to TextCtrlAndButton from the original TextCtrl).
@subsection propgrid_attributes Property Attributes
Miscellaneous values, often specific to a property type, can be set
using wxPropertyGridInterface::SetPropertyAttribute() and
wxPropertyGridInterface::SetPropertyAttributeAll() methods.
Attribute names are strings and values wxVariant. Arbitrary names are allowed
in order to store values that are relevant to application only and not
property grid. Constant equivalents of all attribute string names are
provided. Some of them are defined as cached strings, so using these constants
can provide for smaller binary size.
For complete list of attributes, see @ref propgrid_property_attributes.
@section propgrid_usage2 Using wxPropertyGridManager
wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid,
which can optionally have tool bar for mode and page selection, and a help text
box. For more information, see wxPropertyGridManager class reference.
@subsection propgrid_propgridpage wxPropertyGridPage
wxPropertyGridPage is holder of properties for one page in manager. It is derived from
wxEvtHandler, so you can subclass it to process page-specific property grid events. Hand
over your page instance in wxPropertyGridManager::AddPage().
Please note that the wxPropertyGridPage itself only sports subset of wxPropertyGrid API
(but unlike manager, this include item iteration). Naturally it inherits from
wxPropertyGridInterface.
For more information, see wxPropertyGridPage class reference.
@section propgrid_subclassing Sub-classing wxPropertyGrid and wxPropertyGridManager
Few things to note:
- Only a small percentage of member functions are virtual. If you need more,
just e-mail to wx-dev mailing list.
- Data manipulation is done in wxPropertyGridPageState class. So, instead of
overriding wxPropertyGrid::Insert(), you'll probably want to override
wxPropertyGridPageState::DoInsert(). See header file for details.
- Override wxPropertyGrid::CreateState() to instantiate your derivate
wxPropertyGridPageState. For wxPropertyGridManager, you'll need to subclass
wxPropertyGridPage instead (since it is derived from wxPropertyGridPageState),
and hand over instances in wxPropertyGridManager::AddPage() calls.
- You can use a derivate wxPropertyGrid with manager by overriding
wxPropertyGridManager::CreatePropertyGrid() member function.
@section propgrid_misc Miscellaneous Topics
@subsection propgrid_namescope Property Name Scope
All properties which parent is category or root can be accessed
directly by their base name (ie. name given for property in its constructor).
Other properties can be accessed via "ParentsName.BaseName" notation,
Naturally, all property names should be unique.
@subsection propgrid_nonuniquelabels Non-unique Labels
It is possible to have properties with identical label under same parent.
However, care must be taken to ensure that each property still has
unique (base) name.
@subsection propgrid_boolproperty wxBoolProperty
There are few points about wxBoolProperty that require further discussion:
- wxBoolProperty can be shown as either normal combo box or as a check box.
Property attribute wxPG_BOOL_USE_CHECKBOX is used to change this.
For example, if you have a wxFlagsProperty, you can
set its all items to use check box using the following:
@code
pg->SetPropertyAttribute("MyFlagsProperty", wxPG_BOOL_USE_CHECKBOX, true, wxPG_RECURSE);
@endcode
Following will set all individual bool properties in your control to
use check box:
@code
pg->SetPropertyAttributeAll(wxPG_BOOL_USE_CHECKBOX, true);
@endcode
- Default item names for wxBoolProperty are ["False", "True"]. This can be
changed using static function wxPropertyGrid::SetBoolChoices(trueChoice,
falseChoice).
@subsection propgrid_textctrlupdates Updates from wxTextCtrl Based Editor
Changes from wxTextCtrl based property editors are committed (ie.
wxEVT_PG_CHANGED is sent etc.) *only* when (1) user presser enter, (2)
user moves to edit another property, or (3) when focus leaves
the grid.
Because of this, you may find it useful, in some apps, to call
wxPropertyGrid::CommitChangesFromEditor() just before you need to do any
computations based on property grid values. Note that CommitChangesFromEditor()
will dispatch wxEVT_PG_CHANGED with ProcessEvent, so any of your event handlers
will be called immediately.
@subsection propgrid_splittercentering Centering the Splitter
If you need to center the splitter, but only once when the program starts,
then do <b>not</b> use the wxPG_SPLITTER_AUTO_CENTER window style, but the
wxPropertyGrid::CenterSplitter() method. <b>However, be sure to call it after
the sizer setup and SetSize calls!</b> (ie. usually at the end of the
frame/dialog constructor)
Splitter centering behaviour can be customized using
wxPropertyGridInterface::SetColumnProportion(). Usually it is used to set
non-equal column proportions, which in essence stops the splitter(s) from
being 'centered' as such, and instead just auto-resized.
@subsection propgrid_splittersetting Setting Splitter Position When Creating Property Grid
Splitter position cannot exceed grid size, and therefore setting it during
form creation may fail as initial grid size is often smaller than desired
splitter position, especially when sizers are being used.
@subsection propgrid_colourproperty wxColourProperty and wxSystemColourProperty
Through sub-classing, these two property classes provide substantial customization
features. Subclass wxSystemColourProperty if you want to use wxColourPropertyValue
(which features colour type in addition to wxColour), and wxColourProperty if plain
wxColour is enough.
Override wxSystemColourProperty::ColourToString() to redefine how colours are
printed as strings.
Override wxSystemColourProperty::GetCustomColourIndex() to redefine location of
the item that triggers colour picker dialog (default is last).
Override wxSystemColourProperty::GetColour() to determine which colour matches
which choice entry.
@section propgrid_proplist Property Class Descriptions
See @ref pgproperty_properties
*/

View File

@@ -0,0 +1,123 @@
/////////////////////////////////////////////////////////////////////////////
// Name: refcount.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_refcount Reference Counting
@tableofcontents
Many wxWidgets objects use a technique known as <em>reference counting</em>,
also known as <em>copy on write</em> (COW). This means that when an object is
assigned to another, no copying really takes place. Only the reference count on
the shared object data is incremented and both objects share the same data (a
very fast operation).
But as soon as one of the two (or more) objects is modified, the data has to be
copied because the changes to one of the objects shouldn't be seen in the
others. As data copying only happens when the object is written to, this is
known as COW.
What is important to understand is that all this happens absolutely
transparently to the class users and that whether an object is shared or not is
not seen from the outside of the class - in any case, the result of any
operation on it is the same.
@section overview_refcount_equality Object Comparison
The == and != operators of @ref overview_refcount_list "the reference counted classes"
always do a <em>deep comparison</em>. This means that the equality operator
will return @true if two objects are identical and not only if they share the
same data.
Note that wxWidgets follows the <em>STL philosophy</em>: when a comparison
operator cannot be implemented efficiently (like for e.g. wxImage's ==
operator which would need to compare the entire image's data, pixel-by-pixel),
it's not implemented at all. That's why not all reference counted classes
provide comparison operators.
Also note that if you only need to do a @c shallow comparison between two
wxObject derived classes, you should not use the == and != operators but
rather the wxObject::IsSameAs() function.
@section overview_refcount_destruct Object Destruction
When a COW object destructor is called, it may not delete the data: if it's
shared, the destructor will just decrement the shared data's reference count
without destroying it. Only when the destructor of the last object owning the
data is called, the data is really destroyed. Just like all other COW-things,
this happens transparently to the class users so that you shouldn't care about
it.
@section overview_refcount_list List of Reference Counted Classes
The following classes in wxWidgets have efficient (i.e. fast) assignment
operators and copy constructors since they are reference-counted:
@li wxAcceleratorTable
@li wxAnimation
@li wxBitmap
@li wxBrush
@li wxCursor
@li wxFont
@li wxGraphicsBrush
@li wxGraphicsContext
@li wxGraphicsFont
@li wxGraphicsMatrix
@li wxGraphicsPath
@li wxGraphicsPen
@li wxIcon
@li wxImage
@li wxMetafile
@li wxPalette
@li wxPen
@li wxRegion
@li wxVariant
@li wxVariantData
Note that the list above reports the objects which are reference counted in all
ports of wxWidgets; some ports may use this technique also for other classes.
All the objects implement a function @b IsOk() to test if they are referencing
valid data; when the objects are in uninitialized state, you can only use the
@b IsOk() getter; trying to call any other getter, e.g. wxBrush::GetStyle() on
the ::wxNullBrush object, will result in an assert failure in debug builds.
@section overview_refcount_object Making Your Own Reference Counted Class
Reference counting can be implemented easily using wxObject or using the
intermediate wxRefCounter class directly. Alternatively, you can also use the
wxObjectDataPtr<T> template.
First, derive a new class from wxRefCounter (or wxObjectRefData when using a
wxObject derived class) and put the memory-consuming data in it.
Then derive a new class from wxObject and implement there the public interface
which will be seen by the user of your class. You'll probably want to add a
function to your class which does the cast from wxObjectRefData to your
class-specific shared data. For example:
@code
MyClassRefData* GetData() const
{
return static_cast<MyClassRefData*>(m_refData);
}
@endcode
In fact, any time you need to read the data from your wxObject-derived class,
you will need to call this function.
@note Any time you need to actually modify the data placed inside your wxObject
derived class, you must first call the wxObject::UnShare() function to ensure
that the modifications won't affect other instances which are eventually
sharing your object's data.
*/

View File

@@ -0,0 +1,23 @@
/////////////////////////////////////////////////////////////////////////////
// Name: referencenotes.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_referencenotes Notes on Using this Reference Manual
@tableofcontents
In the descriptions of the wxWidgets classes and their member functions, note
that descriptions of inherited member functions are not duplicated in derived
classes unless their behaviour is different. So in using a class such as
wxScrolledWindow, be aware that wxWindow functions may be relevant.
Where not explicitly stated, size and position arguments may usually be given a
value of ::wxDefaultSize and ::wxDefaultPosition, in which case wxWidgets will
choose suitable values.
*/

View File

@@ -0,0 +1,651 @@
/////////////////////////////////////////////////////////////////////////////
// Name: resyntax.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_resyntax Regular Expressions
@tableofcontents
A <em>regular expression</em> describes strings of characters. It's a pattern
that matches certain strings and doesn't match others.
@see wxRegEx
@section overview_resyntax_differentflavors Different Flavors of Regular Expressions
Regular expressions (RE), as defined by POSIX, come in two flavors:
<em>extended regular expressions</em> (ERE) and <em>basic regular
expressions</em> (BRE). EREs are roughly those of the traditional @e egrep,
while BREs are roughly those of the traditional @e ed. This implementation
adds a third flavor: <em>advanced regular expressions</em> (ARE), basically
EREs with some significant extensions.
This manual page primarily describes AREs. BREs mostly exist for backward
compatibility in some old programs. POSIX EREs are almost an exact subset of
AREs. Features of AREs that are not present in EREs will be indicated.
@section overview_resyntax_syntax Regular Expression Syntax
These regular expressions are implemented using the package written by Henry
Spencer, based on the 1003.2 spec and some (not quite all) of the Perl5
extensions (thanks, Henry!). Much of the description of regular expressions
below is copied verbatim from his manual entry.
An ARE is one or more @e branches, separated by "|", matching anything that
matches any of the branches.
A branch is zero or more @e constraints or @e quantified atoms, concatenated.
It matches a match for the first, followed by a match for the second, etc; an
empty branch matches the empty string.
A quantified atom is an @e atom possibly followed by a single @e quantifier.
Without a quantifier, it matches a match for the atom. The quantifiers, and
what a so-quantified atom matches, are:
@beginTable
@row2col{ <tt>*</tt> ,
A sequence of 0 or more matches of the atom. }
@row2col{ <tt>+</tt> ,
A sequence of 1 or more matches of the atom. }
@row2col{ <tt>?</tt> ,
A sequence of 0 or 1 matches of the atom. }
@row2col{ <tt>{m}</tt> ,
A sequence of exactly @e m matches of the atom. }
@row2col{ <tt>{m\,}</tt> ,
A sequence of @e m or more matches of the atom. }
@row2col{ <tt>{m\,n}</tt> ,
A sequence of @e m through @e n (inclusive) matches of the atom; @e m may
not exceed @e n. }
@row2col{ <tt>*? +? ?? {m}? {m\,}? {m\,n}?</tt> ,
@e Non-greedy quantifiers, which match the same possibilities, but prefer
the smallest number rather than the largest number of matches (see
@ref overview_resyntax_matching). }
@endTable
The forms using @b { and @b } are known as @e bounds. The numbers @e m and
@e n are unsigned decimal integers with permissible values from 0 to 255
inclusive. An atom is one of:
@beginTable
@row2col{ <tt>(re)</tt> ,
Where @e re is any regular expression, matches for @e re, with the match
captured for possible reporting. }
@row2col{ <tt>(?:re)</tt> ,
As previous, but does no reporting (a "non-capturing" set of
parentheses). }
@row2col{ <tt>()</tt> ,
Matches an empty string, captured for possible reporting. }
@row2col{ <tt>(?:)</tt> ,
Matches an empty string, without reporting. }
@row2col{ <tt>[chars]</tt> ,
A <em>bracket expression</em>, matching any one of the @e chars (see
@ref overview_resyntax_bracket for more details). }
@row2col{ <tt>.</tt> ,
Matches any single character. }
@row2col{ <tt>@\k</tt> ,
Where @e k is a non-alphanumeric character, matches that character taken
as an ordinary character, e.g. @\@\ matches a backslash character. }
@row2col{ <tt>@\c</tt> ,
Where @e c is alphanumeric (possibly followed by other characters), an
@e escape (AREs only), see @ref overview_resyntax_escapes below. }
@row2col{ <tt>@leftCurly</tt> ,
When followed by a character other than a digit, matches the left-brace
character "@leftCurly"; when followed by a digit, it is the beginning of a
@e bound (see above). }
@row2col{ <tt>x</tt> ,
Where @e x is a single character with no other significance, matches that
character. }
@endTable
A @e constraint matches an empty string when specific conditions are met. A
constraint may not be followed by a quantifier. The simple constraints are as
follows; some more constraints are described later, under
@ref overview_resyntax_escapes.
@beginTable
@row2col{ <tt>^</tt> ,
Matches at the beginning of a line. }
@row2col{ <tt>@$</tt> ,
Matches at the end of a line. }
@row2col{ <tt>(?=re)</tt> ,
@e Positive lookahead (AREs only), matches at any point where a substring
matching @e re begins. }
@row2col{ <tt>(?!re)</tt> ,
@e Negative lookahead (AREs only), matches at any point where no substring
matching @e re begins. }
@endTable
The lookahead constraints may not contain back references (see later), and all
parentheses within them are considered non-capturing. A RE may not end with
\"\\\".
@section overview_resyntax_bracket Bracket Expressions
A <em>bracket expression</em> is a list of characters enclosed in <tt>[]</tt>.
It normally matches any single character from the list (but see below). If the
list begins with @c ^, it matches any single character (but see below) @e not
from the rest of the list.
If two characters in the list are separated by <tt>-</tt>, this is shorthand
for the full @e range of characters between those two (inclusive) in the
collating sequence, e.g. <tt>[0-9]</tt> in ASCII matches any decimal digit.
Two ranges may not share an endpoint, so e.g. <tt>a-c-e</tt> is illegal.
Ranges are very collating-sequence-dependent, and portable programs should
avoid relying on them.
To include a literal <tt>]</tt> or <tt>-</tt> in the list, the simplest method
is to enclose it in <tt>[.</tt> and <tt>.]</tt> to make it a collating element
(see below). Alternatively, make it the first character (following a possible
<tt>^</tt>), or (AREs only) precede it with <tt>@\</tt>. Alternatively, for
<tt>-</tt>, make it the last character, or the second endpoint of a range. To
use a literal <tt>-</tt> as the first endpoint of a range, make it a collating
element or (AREs only) precede it with <tt>@\</tt>. With the exception of
these, some combinations using <tt>[</tt> (see next paragraphs), and escapes,
all other special characters lose their special significance within a bracket
expression.
Within a bracket expression, a collating element (a character, a
multi-character sequence that collates as if it were a single character, or a
collating-sequence name for either) enclosed in <tt>[.</tt> and <tt>.]</tt>
stands for the sequence of characters of that collating element.
@e wxWidgets: Currently no multi-character collating elements are defined. So
in <tt>[.X.]</tt>, @c X can either be a single character literal or the name
of a character. For example, the following are both identical:
<tt>[[.0.]-[.9.]]</tt> and <tt>[[.zero.]-[.nine.]]</tt> and mean the same as
<tt>[0-9]</tt>. See @ref overview_resyntax_characters.
Within a bracket expression, a collating element enclosed in <tt>[=</tt> and
<tt>=]</tt> is an equivalence class, standing for the sequences of characters
of all collating elements equivalent to that one, including itself. An
equivalence class may not be an endpoint of a range.
@e wxWidgets: Currently no equivalence classes are defined, so <tt>[=X=]</tt>
stands for just the single character @c X. @c X can either be a single
character literal or the name of a character, see
@ref overview_resyntax_characters.
Within a bracket expression, the name of a @e character class enclosed in
<tt>[:</tt> and <tt>:]</tt> stands for the list of all characters (not all
collating elements!) belonging to that class. Standard character classes are:
@beginTable
@row2col{ <tt>alpha</tt> , A letter. }
@row2col{ <tt>upper</tt> , An upper-case letter. }
@row2col{ <tt>lower</tt> , A lower-case letter. }
@row2col{ <tt>digit</tt> , A decimal digit. }
@row2col{ <tt>xdigit</tt> , A hexadecimal digit. }
@row2col{ <tt>alnum</tt> , An alphanumeric (letter or digit). }
@row2col{ <tt>print</tt> , An alphanumeric (same as alnum). }
@row2col{ <tt>blank</tt> , A space or tab character. }
@row2col{ <tt>space</tt> , A character producing white space in displayed text. }
@row2col{ <tt>punct</tt> , A punctuation character. }
@row2col{ <tt>graph</tt> , A character with a visible representation. }
@row2col{ <tt>cntrl</tt> , A control character. }
@endTable
A character class may not be used as an endpoint of a range.
@e wxWidgets: In a non-Unicode build, these character classifications depend on
the current locale, and correspond to the values return by the ANSI C "is"
functions: <tt>isalpha</tt>, <tt>isupper</tt>, etc. In Unicode mode they are
based on Unicode classifications, and are not affected by the current locale.
There are two special cases of bracket expressions: the bracket expressions
<tt>[[:@<:]]</tt> and <tt>[[:@>:]]</tt> are constraints, matching empty strings at
the beginning and end of a word respectively. A word is defined as a sequence
of word characters that is neither preceded nor followed by word characters. A
word character is an @e alnum character or an underscore (_). These special
bracket expressions are deprecated; users of AREs should use constraint escapes
instead (see escapes below).
@section overview_resyntax_escapes Escapes
Escapes (AREs only), which begin with a <tt>@\</tt> followed by an alphanumeric
character, come in several varieties: character entry, class shorthands,
constraint escapes, and back references. A <tt>@\</tt> followed by an
alphanumeric character but not constituting a valid escape is illegal in AREs.
In EREs, there are no escapes: outside a bracket expression, a <tt>@\</tt>
followed by an alphanumeric character merely stands for that character as an
ordinary character, and inside a bracket expression, <tt>@\</tt> is an ordinary
character. (The latter is the one actual incompatibility between EREs and
AREs.)
Character-entry escapes (AREs only) exist to make it easier to specify
non-printing and otherwise inconvenient characters in REs:
@beginTable
@row2col{ <tt>@\a</tt> , Alert (bell) character, as in C. }
@row2col{ <tt>@\b</tt> , Backspace, as in C. }
@row2col{ <tt>@\B</tt> ,
Synonym for <tt>@\</tt> to help reduce backslash doubling in some
applications where there are multiple levels of backslash processing. }
@row2col{ <tt>@\cX</tt> ,
The character whose low-order 5 bits are the same as those of @e X, and
whose other bits are all zero, where @e X is any character. }
@row2col{ <tt>@\e</tt> ,
The character whose collating-sequence name is @c ESC, or failing that,
the character with octal value 033. }
@row2col{ <tt>@\f</tt> , Formfeed, as in C. }
@row2col{ <tt>@\n</tt> , Newline, as in C. }
@row2col{ <tt>@\r</tt> , Carriage return, as in C. }
@row2col{ <tt>@\t</tt> , Horizontal tab, as in C. }
@row2col{ <tt>@\uwxyz</tt> ,
The Unicode character <tt>U+wxyz</tt> in the local byte ordering, where
@e wxyz is exactly four hexadecimal digits. }
@row2col{ <tt>@\Ustuvwxyz</tt> ,
Reserved for a somewhat-hypothetical Unicode extension to 32 bits, where
@e stuvwxyz is exactly eight hexadecimal digits. }
@row2col{ <tt>@\v</tt> , Vertical tab, as in C are all available. }
@row2col{ <tt>@\xhhh</tt> ,
The single character whose hexadecimal value is @e 0xhhh, where @e hhh is
any sequence of hexadecimal digits. }
@row2col{ <tt>@\0</tt> , The character whose value is 0. }
@row2col{ <tt>@\xy</tt> ,
The character whose octal value is @e 0xy, where @e xy is exactly two octal
digits, and is not a <em>back reference</em> (see below). }
@row2col{ <tt>@\xyz</tt> ,
The character whose octal value is @e 0xyz, where @e xyz is exactly three
octal digits, and is not a <em>back reference</em> (see below). }
@endTable
Hexadecimal digits are 0-9, a-f, and A-F. Octal digits are 0-7.
The character-entry escapes are always taken as ordinary characters. For
example, <tt>@\135</tt> is <tt>]</tt> in ASCII, but <tt>@\135</tt> does not
terminate a bracket expression. Beware, however, that some applications (e.g.,
C compilers) interpret such sequences themselves before the regular-expression
package gets to see them, which may require doubling (quadrupling, etc.) the
'<tt>@\</tt>'.
Class-shorthand escapes (AREs only) provide shorthands for certain
commonly-used character classes:
@beginTable
@row2col{ <tt>@\d</tt> , <tt>[[:digit:]]</tt> }
@row2col{ <tt>@\s</tt> , <tt>[[:space:]]</tt> }
@row2col{ <tt>@\w</tt> , <tt>[[:alnum:]_]</tt> (note underscore) }
@row2col{ <tt>@\D</tt> , <tt>[^[:digit:]]</tt> }
@row2col{ <tt>@\S</tt> , <tt>[^[:space:]]</tt> }
@row2col{ <tt>@\W</tt> , <tt>[^[:alnum:]_]</tt> (note underscore) }
@endTable
Within bracket expressions, <tt>@\d</tt>, <tt>@\s</tt>, and <tt>@\w</tt> lose
their outer brackets, and <tt>@\D</tt>, <tt>@\S</tt>, <tt>@\W</tt> are illegal.
So, for example, <tt>[a-c@\d]</tt> is equivalent to <tt>[a-c[:digit:]]</tt>.
Also, <tt>[a-c@\D]</tt>, which is equivalent to <tt>[a-c^[:digit:]]</tt>, is
illegal.
A constraint escape (AREs only) is a constraint, matching the empty string if
specific conditions are met, written as an escape:
@beginTable
@row2col{ <tt>@\A</tt> , Matches only at the beginning of the string, see
@ref overview_resyntax_matching for how this differs
from <tt>^</tt>. }
@row2col{ <tt>@\m</tt> , Matches only at the beginning of a word. }
@row2col{ <tt>@\M</tt> , Matches only at the end of a word. }
@row2col{ <tt>@\y</tt> , Matches only at the beginning or end of a word. }
@row2col{ <tt>@\Y</tt> , Matches only at a point that is not the beginning or
end of a word. }
@row2col{ <tt>@\Z</tt> , Matches only at the end of the string, see
@ref overview_resyntax_matching for how this differs
from <tt>@$</tt>. }
@row2col{ <tt>@\m</tt> , A <em>back reference</em>, where @e m is a non-zero
digit. See below. }
@row2col{ <tt>@\mnn</tt> ,
A <em>back reference</em>, where @e m is a nonzero digit, and @e nn is some
more digits, and the decimal value @e mnn is not greater than the number of
closing capturing parentheses seen so far. See below. }
@endTable
A word is defined as in the specification of <tt>[[:@<:]]</tt> and
<tt>[[:@>:]]</tt> above. Constraint escapes are illegal within bracket
expressions.
A back reference (AREs only) matches the same string matched by the
parenthesized subexpression specified by the number. For example, "([bc])\1"
matches "bb" or "cc" but not "bc". The subexpression must entirely precede the
back reference in the RE.Subexpressions are numbered in the order of their
leading parentheses. Non-capturing parentheses do not define subexpressions.
There is an inherent historical ambiguity between octal character-entry escapes
and back references, which is resolved by heuristics, as hinted at above. A
leading zero always indicates an octal escape. A single non-zero digit, not
followed by another digit, is always taken as a back reference. A multi-digit
sequence not starting with a zero is taken as a back reference if it comes
after a suitable subexpression (i.e. the number is in the legal range for a
back reference), and otherwise is taken as octal.
@section overview_resyntax_metasyntax Metasyntax
In addition to the main syntax described above, there are some special forms
and miscellaneous syntactic facilities available.
Normally the flavor of RE being used is specified by application-dependent
means. However, this can be overridden by a @e director. If an RE of any flavor
begins with <tt>***:</tt>, the rest of the RE is an ARE. If an RE of any
flavor begins with <tt>***=</tt>, the rest of the RE is taken to be a literal
string, with all characters considered ordinary characters.
An ARE may begin with <em>embedded options</em>: a sequence <tt>(?xyz)</tt>
(where @e xyz is one or more alphabetic characters) specifies options affecting
the rest of the RE. These supplement, and can override, any options specified
by the application. The available option letters are:
@beginTable
@row2col{ <tt>b</tt> , Rest of RE is a BRE. }
@row2col{ <tt>c</tt> , Case-sensitive matching (usual default). }
@row2col{ <tt>e</tt> , Rest of RE is an ERE. }
@row2col{ <tt>i</tt> , Case-insensitive matching (see
@ref overview_resyntax_matching, below). }
@row2col{ <tt>m</tt> , Historical synonym for @e n. }
@row2col{ <tt>n</tt> , Newline-sensitive matching (see
@ref overview_resyntax_matching, below). }
@row2col{ <tt>p</tt> , Partial newline-sensitive matching (see
@ref overview_resyntax_matching, below). }
@row2col{ <tt>q</tt> , Rest of RE is a literal ("quoted") string, all ordinary
characters. }
@row2col{ <tt>s</tt> , Non-newline-sensitive matching (usual default). }
@row2col{ <tt>t</tt> , Tight syntax (usual default; see below). }
@row2col{ <tt>w</tt> , Inverse partial newline-sensitive ("weird") matching
(see @ref overview_resyntax_matching, below). }
@row2col{ <tt>x</tt> , Expanded syntax (see below). }
@endTable
Embedded options take effect at the <tt>)</tt> terminating the sequence. They
are available only at the start of an ARE, and may not be used later within it.
In addition to the usual (@e tight) RE syntax, in which all characters are
significant, there is an @e expanded syntax, available in AREs with the
embedded x option. In the expanded syntax, white-space characters are ignored
and all characters between a <tt>@#</tt> and the following newline (or the end
of the RE) are ignored, permitting paragraphing and commenting a complex RE.
There are three exceptions to that basic rule:
@li A white-space character or <tt>@#</tt> preceded by <tt>@\</tt> is retained.
@li White space or <tt>@#</tt> within a bracket expression is retained.
@li White space and comments are illegal within multi-character symbols like
the ARE <tt>(?:</tt> or the BRE <tt>\(</tt>.
Expanded-syntax white-space characters are blank, tab, newline, and any
character that belongs to the @e space character class.
Finally, in an ARE, outside bracket expressions, the sequence <tt>(?@#ttt)</tt>
(where @e ttt is any text not containing a <tt>)</tt>) is a comment, completely
ignored. Again, this is not allowed between the characters of multi-character
symbols like <tt>(?:</tt>. Such comments are more a historical artifact than a
useful facility, and their use is deprecated; use the expanded syntax instead.
@e None of these metasyntax extensions is available if the application (or an
initial <tt>***=</tt> director) has specified that the user's input be treated
as a literal string rather than as an RE.
@section overview_resyntax_matching Matching
In the event that an RE could match more than one substring of a given string,
the RE matches the one starting earliest in the string. If the RE could match
more than one substring starting at that point, the choice is determined by
it's @e preference: either the longest substring, or the shortest.
Most atoms, and all constraints, have no preference. A parenthesized RE has the
same preference (possibly none) as the RE. A quantified atom with quantifier
<tt>{m}</tt> or <tt>{m}?</tt> has the same preference (possibly none) as the
atom itself. A quantified atom with other normal quantifiers (including
<tt>{m,n}</tt> with @e m equal to @e n) prefers longest match. A quantified
atom with other non-greedy quantifiers (including <tt>{m,n}?</tt> with @e m
equal to @e n) prefers shortest match. A branch has the same preference as the
first quantified atom in it which has a preference. An RE consisting of two or
more branches connected by the @c | operator prefers longest match.
Subject to the constraints imposed by the rules for matching the whole RE,
subexpressions also match the longest or shortest possible substrings, based on
their preferences, with subexpressions starting earlier in the RE taking
priority over ones starting later. Note that outer subexpressions thus take
priority over their component subexpressions.
Note that the quantifiers <tt>{1,1}</tt> and <tt>{1,1}?</tt> can be used to
force longest and shortest preference, respectively, on a subexpression or a
whole RE.
Match lengths are measured in characters, not collating elements. An empty
string is considered longer than no match at all. For example, <tt>bb*</tt>
matches the three middle characters of "abbbc",
<tt>(week|wee)(night|knights)</tt> matches all ten characters of "weeknights",
when <tt>(.*).*</tt> is matched against "abc" the parenthesized subexpression
matches all three characters, and when <tt>(a*)*</tt> is matched against "bc"
both the whole RE and the parenthesized subexpression match an empty string.
If case-independent matching is specified, the effect is much as if all case
distinctions had vanished from the alphabet. When an alphabetic that exists in
multiple cases appears as an ordinary character outside a bracket expression,
it is effectively transformed into a bracket expression containing both cases,
so that @c x becomes @c [xX]. When it appears inside a bracket expression, all
case counterparts of it are added to the bracket expression, so that @c [x]
becomes @c [xX] and @c [^x] becomes @c [^xX].
If newline-sensitive matching is specified, "." and bracket expressions using
"^" will never match the newline character (so that matches will never cross
newlines unless the RE explicitly arranges it) and "^" and "$" will match the
empty string after and before a newline respectively, in addition to matching
at beginning and end of string respectively. ARE <tt>@\A</tt> and <tt>@\Z</tt>
continue to match beginning or end of string @e only.
If partial newline-sensitive matching is specified, this affects "." and
bracket expressions as with newline-sensitive matching, but not "^" and "$".
If inverse partial newline-sensitive matching is specified, this affects "^"
and "$" as with newline-sensitive matching, but not "." and bracket
expressions. This isn't very useful but is provided for symmetry.
@section overview_resyntax_limits Limits and Compatibility
No particular limit is imposed on the length of REs. Programs intended to be
highly portable should not employ REs longer than 256 bytes, as a
POSIX-compliant implementation can refuse to accept such REs.
The only feature of AREs that is actually incompatible with POSIX EREs is that
<tt>@\</tt> does not lose its special significance inside bracket expressions.
All other ARE features use syntax which is illegal or has undefined or
unspecified effects in POSIX EREs; the <tt>***</tt> syntax of directors
likewise is outside the POSIX syntax for both BREs and EREs.
Many of the ARE extensions are borrowed from Perl, but some have been changed
to clean them up, and a few Perl extensions are not present. Incompatibilities
of note include <tt>@\b</tt>, <tt>@\B</tt>, the lack of special treatment for a
trailing newline, the addition of complemented bracket expressions to the
things affected by newline-sensitive matching, the restrictions on parentheses
and back references in lookahead constraints, and the longest/shortest-match
(rather than first-match) matching semantics.
The matching rules for REs containing both normal and non-greedy quantifiers
have changed since early beta-test versions of this package. The new rules are
much simpler and cleaner, but don't work as hard at guessing the user's real
intentions.
Henry Spencer's original 1986 @e regexp package, still in widespread use,
implemented an early version of today's EREs. There are four incompatibilities
between @e regexp's near-EREs (RREs for short) and AREs. In roughly increasing
order of significance:
@li In AREs, <tt>@\</tt> followed by an alphanumeric character is either an
escape or an error, while in RREs, it was just another way of writing the
alphanumeric. This should not be a problem because there was no reason to
write such a sequence in RREs.
@li @c { followed by a digit in an ARE is the beginning of a bound, while in
RREs, @c { was always an ordinary character. Such sequences should be rare,
and will often result in an error because following characters will not
look like a valid bound.
@li In AREs, @c @\ remains a special character within @c [], so a literal @c @\
within @c [] must be written as <tt>@\@\</tt>. <tt>@\@\</tt> also gives a
literal @c @\ within @c [] in RREs, but only truly paranoid programmers
routinely doubled the backslash.
@li AREs report the longest/shortest match for the RE, rather than the first
found in a specified search order. This may affect some RREs which were
written in the expectation that the first match would be reported. The
careful crafting of RREs to optimize the search order for fast matching is
obsolete (AREs examine all possible matches in parallel, and their
performance is largely insensitive to their complexity) but cases where the
search order was exploited to deliberately find a match which was @e not
the longest/shortest will need rewriting.
@section overview_resyntax_bre Basic Regular Expressions
BREs differ from EREs in several respects. @c |, @c +, and @c ? are ordinary
characters and there is no equivalent for their functionality. The delimiters
for bounds are @c @\{ and @c @\}, with @c { and @c } by themselves ordinary
characters. The parentheses for nested subexpressions are @c @\( and @c @\),
with @c ( and @c ) by themselves ordinary characters. @c ^ is an ordinary
character except at the beginning of the RE or the beginning of a parenthesized
subexpression, @c $ is an ordinary character except at the end of the RE or the
end of a parenthesized subexpression, and @c * is an ordinary character if it
appears at the beginning of the RE or the beginning of a parenthesized
subexpression (after a possible leading <tt>^</tt>). Finally, single-digit back
references are available, and @c @\@< and @c @\@> are synonyms for
<tt>[[:@<:]]</tt> and <tt>[[:@>:]]</tt> respectively; no other escapes are
available.
@section overview_resyntax_characters Regular Expression Character Names
Note that the character names are case sensitive.
<center><table class='doctable' border='0' cellspacing='5' cellpadding='4'><tr>
<td>
@beginTable
@row2col{ <tt>NUL</tt> , @\0 }
@row2col{ <tt>SOH</tt> , @\001 }
@row2col{ <tt>STX</tt> , @\002 }
@row2col{ <tt>ETX</tt> , @\003 }
@row2col{ <tt>EOT</tt> , @\004 }
@row2col{ <tt>ENQ</tt> , @\005 }
@row2col{ <tt>ACK</tt> , @\006 }
@row2col{ <tt>BEL</tt> , @\007 }
@row2col{ <tt>alert</tt> , @\007 }
@row2col{ <tt>BS</tt> , @\010 }
@row2col{ <tt>backspace</tt> , @\b }
@row2col{ <tt>HT</tt> , @\011 }
@row2col{ <tt>tab</tt> , @\t }
@row2col{ <tt>LF</tt> , @\012 }
@row2col{ <tt>newline</tt> , @\n }
@row2col{ <tt>VT</tt> , @\013 }
@row2col{ <tt>vertical-tab</tt> , @\v }
@row2col{ <tt>FF</tt> , @\014 }
@row2col{ <tt>form-feed</tt> , @\f }
@endTable
</td>
<td>
@beginTable
@row2col{ <tt>CR</tt> , @\015 }
@row2col{ <tt>carriage-return</tt> , @\r }
@row2col{ <tt>SO</tt> , @\016 }
@row2col{ <tt>SI</tt> , @\017 }
@row2col{ <tt>DLE</tt> , @\020 }
@row2col{ <tt>DC1</tt> , @\021 }
@row2col{ <tt>DC2</tt> , @\022 }
@row2col{ <tt>DC3</tt> , @\023 }
@row2col{ <tt>DC4</tt> , @\024 }
@row2col{ <tt>NAK</tt> , @\025 }
@row2col{ <tt>SYN</tt> , @\026 }
@row2col{ <tt>ETB</tt> , @\027 }
@row2col{ <tt>CAN</tt> , @\030 }
@row2col{ <tt>EM</tt> , @\031 }
@row2col{ <tt>SUB</tt> , @\032 }
@row2col{ <tt>ESC</tt> , @\033 }
@row2col{ <tt>IS4</tt> , @\034 }
@row2col{ <tt>FS</tt> , @\034 }
@row2col{ <tt>IS3</tt> , @\035 }
@endTable
</td>
<td>
@beginTable
@row2col{ <tt>GS</tt> , @\035 }
@row2col{ <tt>IS2</tt> , @\036 }
@row2col{ <tt>RS</tt> , @\036 }
@row2col{ <tt>IS1</tt> , @\037 }
@row2col{ <tt>US</tt> , @\037 }
@row2col{ <tt>space</tt> , " " (space) }
@row2col{ <tt>exclamation-mark</tt> , ! }
@row2col{ <tt>quotation-mark</tt> , " }
@row2col{ <tt>number-sign</tt> , @# }
@row2col{ <tt>dollar-sign</tt> , @$ }
@row2col{ <tt>percent-sign</tt> , @% }
@row2col{ <tt>ampersand</tt> , @& }
@row2col{ <tt>apostrophe</tt> , ' }
@row2col{ <tt>left-parenthesis</tt> , ( }
@row2col{ <tt>right-parenthesis</tt> , ) }
@row2col{ <tt>asterisk</tt> , * }
@row2col{ <tt>plus-sign</tt> , + }
@row2col{ <tt>comma</tt> , \, }
@row2col{ <tt>hyphen</tt> , - }
@endTable
</td>
<td>
@beginTable
@row2col{ <tt>hyphen-minus</tt> , - }
@row2col{ <tt>period</tt> , . }
@row2col{ <tt>full-stop</tt> , . }
@row2col{ <tt>slash</tt> , / }
@row2col{ <tt>solidus</tt> , / }
@row2col{ <tt>zero</tt> , 0 }
@row2col{ <tt>one</tt> , 1 }
@row2col{ <tt>two</tt> , 2 }
@row2col{ <tt>three</tt> , 3 }
@row2col{ <tt>four</tt> , 4 }
@row2col{ <tt>five</tt> , 5 }
@row2col{ <tt>six</tt> , 6 }
@row2col{ <tt>seven</tt> , 7 }
@row2col{ <tt>eight</tt> , 8 }
@row2col{ <tt>nine</tt> , 9 }
@row2col{ <tt>colon</tt> , : }
@row2col{ <tt>semicolon</tt> , ; }
@row2col{ <tt>less-than-sign</tt> , @< }
@row2col{ <tt>equals-sign</tt> , = }
@endTable
</td>
<td>
@beginTable
@row2col{ <tt>greater-than-sign</tt> , @> }
@row2col{ <tt>question-mark</tt> , ? }
@row2col{ <tt>commercial-at</tt> , @@ }
@row2col{ <tt>left-square-bracket</tt> , [ }
@row2col{ <tt>backslash</tt> , @\ }
@row2col{ <tt>reverse-solidus</tt> , @\ }
@row2col{ <tt>right-square-bracket</tt> , ] }
@row2col{ <tt>circumflex</tt> , ^ }
@row2col{ <tt>circumflex-accent</tt> , ^ }
@row2col{ <tt>underscore</tt> , _ }
@row2col{ <tt>low-line</tt> , _ }
@row2col{ <tt>grave-accent</tt> , ' }
@row2col{ <tt>left-brace</tt> , @leftCurly }
@row2col{ <tt>left-curly-bracket</tt> , @leftCurly }
@row2col{ <tt>vertical-line</tt> , | }
@row2col{ <tt>right-brace</tt> , @rightCurly }
@row2col{ <tt>right-curly-bracket</tt> , @rightCurly }
@row2col{ <tt>tilde</tt> , ~ }
@row2col{ <tt>DEL</tt> , @\177 }
@endTable
</td>
</tr></table></center>
*/

View File

@@ -0,0 +1,502 @@
/////////////////////////////////////////////////////////////////////////////
// Name: richtextctrl.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_richtextctrl wxRichTextCtrl Overview
@tableofcontents
wxRichTextCtrl provides a generic implementation of a rich text editor that can
handle different character styles, paragraph formatting, and images. It's aimed
at editing 'natural' language text - if you need an editor that supports code
editing, wxStyledTextCtrl is a better choice.
Despite its name, it cannot currently read or write RTF (rich text format)
files. Instead, it uses its own XML format, and can also read and write plain
text. In future we expect to provide RTF or OpenDocument file capabilities.
Custom file formats can be supported by creating additional file handlers and
registering them with the control.
wxRichTextCtrl is largely compatible with the wxTextCtrl API, but extends it
where necessary. The control can be used where the native rich text
capabilities of wxTextCtrl are not adequate (this is particularly true on
Windows) and where more direct access to the content representation is
required. It is difficult and inefficient to read the style information in a
wxTextCtrl, whereas this information is readily available in wxRichTextCtrl.
Since it's written in pure wxWidgets, any customizations you make to
wxRichTextCtrl will be reflected on all platforms.
wxRichTextCtrl supports basic printing via the easy-to-use wxRichTextPrinting
class. Creating applications with simple word processing features is simplified
with the inclusion of wxRichTextFormattingDialog, a tabbed dialog allowing
interactive tailoring of paragraph and character styling. Also provided is the
multi-purpose dialog wxRichTextStyleOrganiserDialog that can be used for
managing style definitions, browsing styles and applying them, or selecting
list styles with a renumber option.
There are a few disadvantages to using wxRichTextCtrl. It is not native, so
does not behave exactly as a native wxTextCtrl, although common editing
conventions are followed. Users may miss the built-in spelling correction on
macOS, or any special character input that may be provided by the native
control. It would also be a poor choice if intended users rely on screen
readers that would be not work well with non-native text input implementation.
You might mitigate this by providing the choice between wxTextCtrl and
wxRichTextCtrl, with fewer features in the former case.
A good way to understand wxRichTextCtrl's capabilities is to compile and run
the sample, @c samples/richtext, and browse the code.
@section overview_richtextctrl_classes Related Classes
<b>Major classes:</b>
wxRichTextCtrl, wxRichTextBuffer, wxRichTextEvent
<b>Helper classes:</b>
wxTextAttr, wxRichTextRange
<b>File handler classes:</b>
wxRichTextFileHandler, wxRichTextHTMLHandler, wxRichTextXMLHandler
<b>Style classes:</b>
wxRichTextCharacterStyleDefinition, wxRichTextParagraphStyleDefinition,
wxRichTextListStyleDefinition, wxRichTextStyleSheet
<b>Additional controls:</b>
wxRichTextStyleComboCtrl, wxRichTextStyleListBox, wxRichTextStyleListCtrl
<b>Printing classes:</b>
wxRichTextPrinting, wxRichTextPrintout, wxRichTextHeaderFooterData
<b>Dialog classes:</b>
wxRichTextStyleOrganiserDialog, wxRichTextFormattingDialog,
wxSymbolPickerDialog
@section overview_richtextctrl_example Code Example
The following code is an example taken from the sample, and adds text and
styles to a rich text control programmatically.
@code
wxRichTextCtrl* richTextCtrl = new wxRichTextCtrl(
splitter, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize(200, 200), wxVSCROLL | wxHSCROLL | wxBORDER_NONE | wxWANTS_CHARS);
wxFont textFont = wxFont(12, wxROMAN, wxNORMAL, wxNORMAL);
wxFont boldFont = wxFont(12, wxROMAN, wxNORMAL, wxBOLD);
wxFont italicFont = wxFont(12, wxROMAN, wxITALIC, wxNORMAL);
wxFont font(12, wxROMAN, wxNORMAL, wxNORMAL);
m_richTextCtrl->SetFont(font);
wxRichTextCtrl& r = richTextCtrl;
r.BeginSuppressUndo();
r.BeginParagraphSpacing(0, 20);
r.BeginAlignment(wxTEXT_ALIGNMENT_CENTRE);
r.BeginBold();
r.BeginFontSize(14);
r.WriteText("Welcome to wxRichTextCtrl, a wxWidgets control for editing and presenting styled text and images");
r.EndFontSize();
r.Newline();
r.BeginItalic();
r.WriteText("by Julian Smart");
r.EndItalic();
r.EndBold();
r.Newline();
r.WriteImage(wxBitmap(zebra_xpm));
r.EndAlignment();
r.Newline();
r.Newline();
r.WriteText("What can you do with this thing? ");
r.WriteImage(wxBitmap(smiley_xpm));
r.WriteText(" Well, you can change text ");
r.BeginTextColour(wxColour(255, 0, 0));
r.WriteText("colour, like this red bit.");
r.EndTextColour();
r.BeginTextColour(wxColour(0, 0, 255));
r.WriteText(" And this blue bit.");
r.EndTextColour();
r.WriteText(" Naturally you can make things ");
r.BeginBold();
r.WriteText("bold ");
r.EndBold();
r.BeginItalic();
r.WriteText("or italic ");
r.EndItalic();
r.BeginUnderline();
r.WriteText("or underlined.");
r.EndUnderline();
r.BeginFontSize(14);
r.WriteText(" Different font sizes on the same line is allowed, too.");
r.EndFontSize();
r.WriteText(" Next we'll show an indented paragraph.");
r.BeginLeftIndent(60);
r.Newline();
r.WriteText("Indented paragraph.");
r.EndLeftIndent();
r.Newline();
r.WriteText("Next, we'll show a first-line indent, achieved using BeginLeftIndent(100, -40).");
r.BeginLeftIndent(100, -40);
r.Newline();
r.WriteText("It was in January, the most down-trodden month of an Edinburgh winter.");
r.EndLeftIndent();
r.Newline();
r.WriteText("Numbered bullets are possible, again using subindents:");
r.BeginNumberedBullet(1, 100, 60);
r.Newline();
r.WriteText("This is my first item. Note that wxRichTextCtrl doesn't automatically do numbering, but this will be added later.");
r.EndNumberedBullet();
r.BeginNumberedBullet(2, 100, 60);
r.Newline();
r.WriteText("This is my second item.");
r.EndNumberedBullet();
r.Newline();
r.WriteText("The following paragraph is right-indented:");
r.BeginRightIndent(200);
r.Newline();
r.WriteText("It was in January, the most down-trodden month of an Edinburgh winter. An attractive woman came into the cafe, which is nothing remarkable.");
r.EndRightIndent();
r.Newline();
wxArrayInt tabs;
tabs.Add(400);
tabs.Add(600);
tabs.Add(800);
tabs.Add(1000);
wxTextAttr attr;
attr.SetFlags(wxTEXT_ATTR_TABS);
attr.SetTabs(tabs);
r.SetDefaultStyle(attr);
r.WriteText("This line contains tabs:\tFirst tab\tSecond tab\tThird tab");
r.Newline();
r.WriteText("Other notable features of wxRichTextCtrl include:");
r.BeginSymbolBullet('*', 100, 60);
r.Newline();
r.WriteText("Compatibility with wxTextCtrl API");
r.EndSymbolBullet();
r.WriteText("Note: this sample content was generated programmatically from within the MyFrame constructor in the demo. The images were loaded from inline XPMs. Enjoy wxRichTextCtrl!");
r.EndSuppressUndo();
@endcode
@section overview_richtextctrl_starting Starting to Use wxRichTextCtrl
You need to include @c @<wx/richtext/richtextctrl.h@> in your source, and link
with the appropriate wxWidgets library with @c richtext suffix. Put the rich
text library first in your link line to avoid unresolved symbols.
Then you can create a wxRichTextCtrl, with the wxWANT_CHARS style if you want
tabs to be processed by the control rather than being used for navigation
between controls.
@section overview_richtextctrl_styles Text Styles
Styling attributes are represented by wxTextAttr, or for more control over
attributes such as margins and size, the derived class wxRichTextAttr.
When setting a style, the flags of the attribute object determine which
attributes are applied. When querying a style, the passed flags are ignored
except (optionally) to determine whether attributes should be retrieved from
character content or from the paragraph object.
wxRichTextCtrl takes a layered approach to styles, so that different parts of
the content may be responsible for contributing different attributes to the
final style you see on the screen.
There are four main notions of style within a control:
@li <b>Basic style</b>: The fundamental style of a control, onto which any
other styles are layered. It provides default attributes, and changing the
basic style may immediately change the look of the content depending on
what other styles the content uses. Calling wxRichTextCtrl::SetFont changes
the font for the basic style. The basic style is set with
wxRichTextCtrl::SetBasicStyle.
@li <b>Paragraph style</b>: Each paragraph has attributes that are set
independently from other paragraphs and independently from the content
within the paragraph. Normally, these attributes are paragraph-related,
such as alignment and indentation, but it is possible to set character
attributes too. The paragraph style can be set independently of its content
by passing wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY to
wxRichTextCtrl::SetStyleEx.
@li <b>Character style</b>: Characters within each paragraph can have
attributes. A single character, or a run of characters, can have a
particular set of attributes. The character style can be with
wxRichTextCtrl::SetStyle or wxRichTextCtrl::SetStyleEx.
@li <b>Default style</b>: This is the 'current' style that determines the style
of content that is subsequently typed, pasted or programmatically inserted.
The default style is set with wxRichTextCtrl::SetDefaultStyle.
What you see on the screen is the dynamically @e combined style, found by
merging the first three of the above style types (the fourth is only a guide
for future content insertion and therefore does not affect the currently
displayed content).
To make all this more concrete, here are examples of where you might set these
different styles:
@li You might set the <em>basic style</em> to have a Times Roman font in 12
point, left-aligned, with two millimetres of spacing after each paragraph.
@li You might set the <em>paragraph style</em> (for one particular paragraph)
to be centred.
@li You might set the <em>character style</em> of one particular word to bold.
@li You might set the <em>default style</em> to be underlined, for subsequent
inserted text.
Naturally you can do any of these things either using your own UI, or
programmatically.
The basic wxTextCtrl doesn't make the same distinctions as wxRichTextCtrl
regarding attribute storage. So we need finer control when setting and
retrieving attributes. wxRichTextCtrl::SetStyleEx takes a @e flags parameter:
@li wxRICHTEXT_SETSTYLE_OPTIMIZE specifies that the style should be changed
only if the combined attributes are different from the attributes for the
current object. This is important when applying styling that has been
edited by the user, because he has just edited the @e combined (visible)
style, and wxRichTextCtrl wants to leave unchanged attributes associated
with their original objects instead of applying them to both paragraph and
content objects.
@li wxRICHTEXT_SETSTYLE_PARAGRAPHS_ONLY specifies that only paragraph objects
within the given range should take on the attributes.
@li wxRICHTEXT_SETSTYLE_CHARACTERS_ONLY specifies that only content objects
(text or images) within the given range should take on the attributes.
@li wxRICHTEXT_SETSTYLE_WITH_UNDO specifies that the operation should be
undoable.
It's great to be able to change arbitrary attributes in a wxRichTextCtrl, but
it can be unwieldy for the user or programmer to set attributes separately.
Word processors have collections of styles that you can tailor or use as-is,
and this means that you can set a heading with one click instead of marking
text in bold, specifying a large font size, and applying a certain paragraph
spacing and alignment for every such heading. Similarly, wxWidgets provides a
class called wxRichTextStyleSheet which manages style definitions
(wxRichTextParagraphStyleDefinition, wxRichTextListStyleDefinition and
wxRichTextCharacterStyleDefinition). Once you have added definitions to a style
sheet and associated it with a wxRichTextCtrl, you can apply a named definition
to a range of text. The classes wxRichTextStyleComboCtrl and
wxRichTextStyleListBox can be used to present the user with a list of styles in
a sheet, and apply them to the selected text.
You can reapply a style sheet to the contents of the control, by calling
wxRichTextCtrl::ApplyStyleSheet. This is useful if the style definitions have
changed, and you want the content to reflect this. It relies on the fact that
when you apply a named style, the style definition name is recorded in the
content. So ApplyStyleSheet works by finding the paragraph attributes with
style names and re-applying the definition's attributes to the paragraph.
Currently, this works with paragraph and list style definitions only.
@section overview_richtextctrl_dialogs Included Dialogs
wxRichTextCtrl comes with standard dialogs to make it easier to implement text
editing functionality.
wxRichTextFormattingDialog can be used for character or paragraph formatting,
or a combination of both. It's a wxPropertySheetDialog with the following
available tabs: Font, Indents @& Spacing, Tabs, Bullets, Style, Borders,
Margins, Background, Size, and List Style.
You can select which pages will be shown by supplying flags to the dialog
constructor. In a character formatting dialog, typically only the Font page
will be shown. In a paragraph formatting dialog, you'll show the Indents @&
Spacing, Tabs and Bullets pages. The Style tab is useful when editing a style
definition.
You can customize this dialog by providing your own
wxRichTextFormattingDialogFactory object, which tells the formatting dialog how
many pages are supported, what their identifiers are, and how to creates the
pages.
wxRichTextStyleOrganiserDialog is a multi-purpose dialog that can be used for
managing style definitions, browsing styles and applying them, or selecting
list styles with a renumber option. See the sample for usage - it is used for
the "Manage Styles" and "Bullets and Numbering" menu commands.
wxSymbolPickerDialog lets the user insert a symbol from a specified font. It
has no wxRichTextCtrl dependencies besides being included in the rich text
library.
@section overview_richtextctrl_impl How wxRichTextCtrl is Implemented
Data representation is handled by wxRichTextBuffer, and a wxRichTextCtrl always
has one such buffer.
The content is represented by a hierarchy of objects, all derived from
wxRichTextObject. An object might be an image, a fragment of text, a paragraph,
or a further composite object. Objects store a wxRichTextAttr containing style information; a
paragraph object can contain both paragraph and character information, but
content objects such as text can only store character information. The final
style displayed in the control or in a printout is a combination of base style,
paragraph style and content (character) style.
The top of the hierarchy is the buffer, a kind of wxRichTextParagraphLayoutBox,
containing further wxRichTextParagraph objects, each of which can include text,
images and potentially other types of object.
Each object maintains a range (start and end position) measured from the start
of the main parent object.
When Layout is called on an object, it is given a size which the object must
limit itself to, or one or more flexible directions (vertical or horizontal).
So, for example, a centred paragraph is given the page width to play with
(minus any margins), but can extend indefinitely in the vertical direction.
The implementation of Layout caches the calculated size and position.
When the buffer is modified, a range is invalidated (marked as requiring
layout), so that only the minimum amount of layout is performed.
A paragraph of pure text with the same style contains just one further object,
a wxRichTextPlainText object. When styling is applied to part of this object,
the object is decomposed into separate objects, one object for each different
character style. So each object within a paragraph always has just one
wxTextAttr object to denote its character style. Of course, this can lead to
fragmentation after a lot of edit operations, potentially leading to several
objects with the same style where just one would do. So a Defragment function
is called when updating the control's display, to ensure that the minimum
number of objects is used.
@section overview_richtextctrl_nested_object Nested Objects
wxRichTextCtrl supports nested objects such as text boxes and tables. To
achieve compatibility with the existing API, there is the concept of @e object
@e focus. When the user clicks on a nested text box, the object focus is set to
that container object so all keyboard input and API functions apply to that
container. The application can change the focus using
wxRichTextCtrl::SetObjectFocus. Call this function with a @c null parameter to
set the focus back to the top-level object.
An event will be sent to the control when the focus changes.
When the user clicks on the control, wxRichTextCtrl determines which container
to set as the current object focus by calling the found container's overridden
wxRichTextObject::AcceptsFocus function. For example, although a table is a
container, it must not itself be the object focus because there is no text
editing at the table level. Instead, a cell within the table must accept the
focus.
Since with nested objects it is not possible to represent a section with merely
a start position and an end position, the class wxRichTextSelection is provided
which stores multiple ranges (for non-contiguous selections such as table
cells) and a pointer to the container object in question. You can pass
wxRichTextSelection to wxRichTextCtrl::SetSelection or get an instance of it
from wxRichTextCtrl::GetSelection.
When selecting multiple objects, such as cell tables, the wxRichTextCtrl
dragging handler code calls the function
wxRichTextObject::HandlesChildSelections to determine whether the children can
be individual selections. Currently only table cells can be multiply-selected
in this way.
@section overview_richtextctrl_context_menus Context Menus and Property Dialogs
There are three ways you can make use of context menus: you can let
wxRichTextCtrl handle everything and provide a basic menu; you can set your own
context menu using wxRichTextCtrl::SetContextMenu but let wxRichTextCtrl handle
showing it and adding property items; or you can override the default context
menu behaviour by adding a context menu event handler to your class in the
normal way.
If you right-click over a text box in cell in a table, you may want to edit the
properties of one of these objects - but which properties will you be editing?
Well, the default behaviour allows up to three property-editing menu items
simultaneously - for the object clicked on, the container of that object, and
the container's parent (depending on whether any of these objects return @true
from their wxRichTextObject::CanEditProperties functions). If you supply a
context menu, add a property command item using the wxID_RICHTEXT_PROPERTIES1
identifier, so that wxRichTextCtrl can find the position to add command items.
The object should tell the control what label to use by returning a string from
wxRichTextObject::GetPropertiesMenuLabel.
Since there may be several property-editing commands showing, it is recommended
that you don't include the word Properties - just the name of the object, such
as Text Box or Table.
@section overview_richtextctrl_roadmap Development Roadmap
@subsection overview_richtextctrl_roadmap_bugs Bugs
This is an incomplete list of bugs.
@li Moving the caret up at the beginning of a line sometimes incorrectly
positions the caret.
@li As the selection is expanded, the text jumps slightly due to kerning
differences between drawing a single text string versus drawing several
fragments separately. This could be improved by using
wxDC::GetPartialTextExtents to calculate exactly where the separate
fragments should be drawn. Note that this problem also applies to
separation of text fragments due to difference in their attributes.
@subsection overview_richtextctrl_roadmap_features Features
This is a list of some of the features that have yet to be implemented. Help
with them will be appreciated.
@li support for composite objects in some functions where it's not yet implemented, for example ApplyStyleSheet
@li Table API enhancements and dialogs; improved table layout especially row spans and fitting
@li Conversion from HTML, and a rewrite of the HTML output handler that includes CSS,
tables, text boxes, and floating images, in addition to a simplified-HTML mode for wxHTML compatibility
@li Open Office input and output
@li RTF input and output
@li A ruler control
@li Standard editing toolbars
@li Bitmap bullets
@li Justified text, in print/preview at least
@li scaling: either everything scaled, or rendering using a custom reference point size and an optional dimension scale
There are also things that could be done to take advantage of the underlying
text capabilities of the platform; higher-level text formatting APIs are
available on some platforms, such as macOS, and some of translation from
high level to low level wxDC API is unnecessary. However this would require
additions to the wxWidgets API.
*/

View File

@@ -0,0 +1,71 @@
/////////////////////////////////////////////////////////////////////////////
// Name: roughguide.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_roughguide A Quick Guide to Writing Applications
@tableofcontents
@section overview_roughguide_structure Application Structure
To set a wxWidgets application going, you will need to derive a wxApp class and
override wxApp::OnInit() in which you will typically create your application
main top-level window.
This window can be a wxFrame or a wxDialog and may contain one or more
instances of classes such as wxPanel, wxSplitterWindow or other windows and
controls. These windows can be created from C++ code or loaded from resource
definitions in @ref overview_xrc "XRC format".
A frame can have a wxMenuBar, a wxToolBar, a wxStatusBar, and a wxIcon for when
the frame is iconized.
A wxPanel is used to place controls (classes derived from wxControl) which are
used for user interaction. Examples of controls are wxButton, wxCheckBox,
wxChoice, wxListBox, wxRadioBox, and wxSlider. Such controls need to be
positioned correctly -- and also repositioned when the top-level window is
resized by the user -- and to do this you use wxSizer-derived classes, such as
wxBoxSizer and wxFlexGridSizer, to layout everything correctly.
Instances of wxDialog can also be used for controls and they have the advantage
of not requiring a separate panel inside them.
Instead of creating a dialog box and populating it with items, it is possible
to choose one of the convenient common dialog classes, such as wxMessageDialog
and wxFileDialog.
@section overview_roughguide_draw Drawing on the Screen
You never draw directly onto a window -- you use either one of the older
<em>device context</em> (DC) classes or the newer <em>graphics context</em>
(GC) one, that support features such as alpha transparency or anti-aliasing.
wxDC is the base for wxClientDC, wxPaintDC, wxMemoryDC, wxPostScriptDC,
wxMemoryDC, wxMetafileDC and wxPrinterDC. If your drawing functions have wxDC
as a parameter, you can pass any of these DCs to the function, and thus use the
same code to draw to several different devices. You can draw using the member
functions of wxDC, such as wxDC::DrawLine and wxDC::DrawText. Control colour on
a window (wxColour) with brushes (wxBrush) and pens (wxPen).
With wxGraphicsContext, you create it using one of the methods of
wxGraphicsRenderer and then construct your drawing from wxGraphicsPath objects,
finally using wxGraphicsContext::StrokePath() or wxGraphicsContext::FillPath().
@section overview_roughguide_events Event Handling
GUI programs spend most of their time waiting for the user-initiated events --
and then processing them. To do it, you use wxEvtHandler::Bind() to specify the
handler for an event of the given time. Event handlers receive the object
describing the event, such as wxKeyEvent or wxMouseEvent, and perform whichever
action corresponds to it. See @ref overview_events "events handling" overview
for much more information about this subject.
@see @ref group_class
*/

View File

@@ -0,0 +1,113 @@
/////////////////////////////////////////////////////////////////////////////
// Name: runtimeclass.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_rtti Runtime Type Information (RTTI)
@tableofcontents
One of the failings of C++ used to be that no runtime information was provided
about a class and its position in the inheritance hierarchy. Another, which
still persists, is that instances of a class cannot be created just by knowing
the name of a class, which makes facilities such as persistent storage hard to
implement.
Most C++ GUI frameworks overcome these limitations by means of a set of macros
and functions and wxWidgets is no exception. As it originated before the
addition of RTTI to the C++ standard and as support for it is still missing
from some (albeit old) compilers, wxWidgets doesn't (yet) use it, but provides
its own macro-based RTTI system.
In the future, the standard C++ RTTI will be used though and you're encouraged
to use whenever possible the wxDynamicCast macro which, for the implementations
that support it, is defined just as dynamic_cast and uses wxWidgets RTTI for
all the others. This macro is limited to wxWidgets classes only and only works
with pointers (unlike the real dynamic_cast which also accepts references).
Each class that you wish to be known to the type system should have a macro
such as wxDECLARE_DYNAMIC_CLASS just inside the class declaration. The macro
wxIMPLEMENT_DYNAMIC_CLASS should be in the implementation file. Note that these
are entirely optional; use them if you wish to check object types, or create
instances of classes using the class name. However, it is good to get into the
habit of adding these macros for all classes.
Variations on these macros are used for multiple inheritance, and abstract
classes that cannot be instantiated dynamically or otherwise.
wxDECLARE_DYNAMIC_CLASS inserts a static wxClassInfo declaration into the
class, initialized by wxIMPLEMENT_DYNAMIC_CLASS. When initialized, the
wxClassInfo object inserts itself into a linked list (accessed through
wxClassInfo::first and wxClassInfo::next pointers). The linked list is fully
created by the time all global initialisation is done.
wxIMPLEMENT_DYNAMIC_CLASS is a macro that not only initialises the static
wxClassInfo member, but defines a global function capable of creating a dynamic
object of the class in question. A pointer to this function is stored in
wxClassInfo, and is used when an object should be created dynamically.
wxObject::IsKindOf uses the linked list of wxClassInfo. It takes a wxClassInfo
argument, so use CLASSINFO(className) to return an appropriate wxClassInfo
pointer to use in this function.
The function wxCreateDynamicObject can be used to construct a new object of a
given type, by supplying a string name. If you have a pointer to the
wxClassInfo object instead, then you can simply call wxClassInfo::CreateObject.
@see wxObject
@section overview_rtti_classinfo wxClassInfo
This class stores meta-information about classes. An application may use
macros such as wxDECLARE_DYNAMIC_CLASS and wxIMPLEMENT_DYNAMIC_CLASS to
record runtime information about a class, including:
@li Its position in the inheritance hierarchy.
@li The base class name(s) (up to two base classes are permitted).
@li A string representation of the class name.
@li A function that can be called to construct an instance of this class.
The wxDECLARE_... macros declare a static wxClassInfo variable in a class, which
is initialized by macros of the form wxIMPLEMENT_... in the implementation C++
file. Classes whose instances may be constructed dynamically are given a global
constructor function which returns a new object.
You can get the wxClassInfo for a class by using the CLASSINFO macro, e.g.
CLASSINFO(wxFrame). You can get the wxClassInfo for an object using
wxObject::GetClassInfo.
@section overview_rtti_example Example
In a header file frame.h:
@code
class wxFrame : public wxWindow
{
wxDECLARE_DYNAMIC_CLASS(wxFrame);
private:
wxString m_title;
public:
...
};
@endcode
In a C++ file frame.cpp:
@code
wxIMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow);
wxFrame::wxFrame()
{
...
}
@endcode
*/

View File

@@ -0,0 +1,95 @@
/////////////////////////////////////////////////////////////////////////////
// Name: scrolling.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_scrolling Scrolled Windows
@tableofcontents
Scrollbars come in various guises in wxWidgets. All windows have the potential
to show a vertical scrollbar and/or a horizontal scrollbar: it is a basic
capability of a window. However, in practice, not all windows do make use of
scrollbars, such as a single-line wxTextCtrl.
Because any class derived from wxWindow may have scrollbars, there are
functions to manipulate the scrollbars and event handlers to intercept scroll
events. But just because a window generates a scroll event, doesn't mean that
the window necessarily handles it and physically scrolls the window. The base
class wxWindow in fact doesn't have any default functionality to handle scroll
events. If you created a wxWindow object with scrollbars, and then clicked on
the scrollbars, nothing at all would happen. This is deliberate, because the
@e interpretation of scroll events varies from one window class to another.
::wxScrolledWindow (formerly wxCanvas) is an example of a window that adds
functionality to make scrolling really work. It assumes that scrolling happens
in consistent units, not different-sized jumps, and that page size is
represented by the visible portion of the window. It is suited to drawing
applications, but perhaps not so suitable for a sophisticated editor in which
the amount scrolled may vary according to the size of text on a given line. For
this, you would derive from wxWindow and implement scrolling yourself. wxGrid
is an example of a class that implements its own scrolling, largely because
columns and rows can vary in size.
@see wxScrollBar
@section overview_scrolling_model The Scrollbar Model
The function wxWindow::SetScrollbar gives a clue about the way a scrollbar is
modeled. This function takes the following arguments:
@beginTable
@row2col{ @c orientation , Which scrollbar: wxVERTICAL or wxHORIZONTAL. }
@row2col{ @c position , The position of the scrollbar in scroll units. }
@row2col{ @c visible , The size of the visible portion of the scrollbar,
in scroll units. }
@row2col{ @c range , The maximum position of the scrollbar. }
@row2col{ @c refresh , Whether the scrollbar should be repainted. }
@endTable
@c orientation determines whether we're talking about the built-in horizontal
or vertical scrollbar.
@c position is simply the position of the 'thumb' (the bit you drag to scroll
around). It is given in scroll units, and so is relative to the total range of
the scrollbar.
@c visible gives the number of scroll units that represents the portion of the
window currently visible. Normally, a scrollbar is capable of indicating this
visually by showing a different length of thumb.
@c range is the maximum value of the scrollbar, where zero is the start
position. You choose the units that suit you, so if you wanted to display text
that has 100 lines, you would set this to 100. Note that this doesn't have to
correspond to the number of pixels scrolled - it is up to you how you actually
show the contents of the window.
@c refresh just indicates whether the scrollbar should be repainted immediately
or not.
@section overview_scrolling_example An Example
Let's say you wish to display 50 lines of text, using the same font. The window
is sized so that you can only see 16 lines at a time. You would use:
@code
SetScrollbar(wxVERTICAL, 0, 16, 50);
@endcode
Note that with the window at this size, the thumb position can never go above
50 minus 16, or 34. You can determine how many lines are currently visible by
dividing the current view size by the character height in pixels.
When defining your own scrollbar behaviour, you will always need to recalculate
the scrollbar settings when the window size changes. You could therefore put
your scrollbar calculations and SetScrollbar call into a function named
AdjustScrollbars, which can be called initially and also from your wxSizeEvent
handler function.
*/

View File

@@ -0,0 +1,330 @@
/////////////////////////////////////////////////////////////////////////////
// Name: sizer.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_sizer Sizers Overview
@tableofcontents
Sizers, as represented by the wxSizer class and its descendants in the
wxWidgets class hierarchy, have become the method of choice to define the
layout of controls in dialogs in wxWidgets because of their ability to create
visually appealing dialogs independent of the platform, taking into account
the differences in size and style of the individual controls.
The next section describes and shows what can be done with sizers. The
following sections briefly describe how to program with individual sizer
classes.
For information about the wxWidgets resource system, which can describe
sizer-based dialogs, see the @ref overview_xrc.
@see wxSizer, wxBoxSizer, wxStaticBoxSizer, wxStdDialogButtonSizer, wxWrapSizer,
wxGridSizer, wxFlexGridSizer, wxGridBagSizer, @ref overview_windowsizing
@section overview_sizer_idea The Idea Behind Sizers
The layout algorithm used by sizers in wxWidgets is closely related to layout
systems in other GUI toolkits, such as Java's AWT, the GTK toolkit or the Qt
toolkit. It is based upon the idea of individual subwindows reporting their
minimal required size and their ability to get stretched if the size of the
parent window has changed. This will most often mean that the programmer does
not set the start-up size of a dialog, the dialog will rather be assigned a
sizer and this sizer will be queried about the recommended size. This sizer in
turn will query its children (which can be normal windows, empty space or other
sizers) so that a hierarchy of sizers can be constructed. Note that wxSizer
does not derive from wxWindow and thus does not interfere with tab ordering and
requires very few resources compared to a real window on screen.
What makes sizers so well fitted for use in wxWidgets is the fact that every
control reports its own minimal size and the algorithm can handle differences
in font sizes or different window (dialog item) sizes on different platforms
without problems. For example, if the standard font as well as the overall
design of Linux/GTK widgets requires more space than on Windows, the initial
dialog size will automatically be bigger on Linux/GTK than on Windows.
There are currently seven different kinds of sizers available in wxWidgets. Each
represents either a certain way to lay out dialog items in a dialog or it
fulfills a special task such as wrapping a static box around a dialog item (or
another sizer). These sizers will be discussed one by one in the text below.
For more detailed information on how to use sizers programmatically, please
refer to the section @ref overview_sizer_box.
@section overview_sizer_features Common Features
All sizers are containers, that is, they are used to lay out one dialog item
(or several dialog items), which they contain. Such items are sometimes
referred to as the children of the sizer. Independent of how the individual
sizers lay out their children, all children have certain features in common:
<b>A minimal size</b>: This minimal size is usually identical to the initial
size of the controls and may either be set explicitly in the wxSize field of
the control constructor or may be calculated by wxWidgets, typically by setting
the height and/or the width of the item to -1. Note that only some controls can
calculate their size (such as a checkbox) whereas others (such as a listbox)
don't have any natural width or height and thus require an explicit size. Some
controls can calculate their height, but not their width (e.g. a single line
text control):
@image html overview_sizer_03.png
@image html overview_sizer_04.png
@image html overview_sizer_05.png
<b>A border</b>: The border is just empty space and is used to separate dialog
items in a dialog. This border can either be all around, or at any combination
of sides such as only above and below the control. The thickness of this border
must be set explicitly, typically 5 points. The following samples show dialogs
with only one dialog item (a button) and a border of 0, 5, and 10 pixels around
the button:
@image html overview_sizer_00.png
@image html overview_sizer_01.png
@image html overview_sizer_02.png
<b>An alignment</b>: Often, a dialog item is given more space than its minimal
size plus its border. Depending on what flags are used for the respective
dialog item, the dialog item can be made to fill out the available space
entirely, i.e. it will grow to a size larger than the minimal size, or it will
be moved to either the centre of the available space or to either side of the
space. The following sample shows a listbox and three buttons in a horizontal
box sizer; one button is centred, one is aligned at the top, one is aligned at
the bottom:
@image html overview_sizer_06.png
<b>A stretch factor</b>: If a sizer contains more than one child and it is
offered more space than its children and their borders need, the question
arises how to distribute the surplus space among the children. For this
purpose, a stretch factor may be assigned to each child, where the default
value of @c 0 indicates that the child will not get more space than its requested
minimum size. A value of more than zero is interpreted in relation to the sum
of all stretch factors in the children of the respective sizer, i.e. if two
children get a stretch factor of @c 1, they will get half the extra space each
<em>independent of whether one control has a minimal sizer inferior to the
other or not</em>. The following sample shows a dialog with three buttons, the
first one has a stretch factor of @c 1 and thus gets stretched, whereas the other
two buttons have a stretch factor of @c 0 and keep their initial width:
@image html overview_sizer_07.png
@section overview_sizer_hiding Hiding Controls Using Sizers
You can hide controls contained in sizers the same way you would hide any
control, using the wxWindow::Show() method. However, wxSizer also offers a
separate method which can tell the sizer not to consider that control in its
size calculations. To hide a window using the sizer, call wxSizer::Show(). You
must then call Layout on the sizer to force an update.
This is useful when hiding parts of the interface, since you can avoid removing
the controls from the sizer and having to add them back later.
@note This is supported only by wxBoxSizer and wxFlexGridSizer.
@section overview_sizer_box wxBoxSizer
wxBoxSizer can lay out its children either vertically or horizontally,
depending on what flag is being used in its constructor. When using a vertical
sizer, each child can be centered, aligned to the right or aligned to the left.
Correspondingly, when using a horizontal sizer, each child can be centered,
aligned at the bottom or aligned at the top. The stretch factor described in
the last paragraph is used for the main orientation, i.e. when using a
horizontal box sizer, the stretch factor determines how much the child can be
stretched horizontally. The following sample shows the same dialog as in the
last sample, only the box sizer is a vertical box sizer now:
@image html overview_sizer_08.png
@section overview_sizer_staticbox wxStaticBoxSizer
wxStaticBoxSizer is the same as a wxBoxSizer, but surrounded by a static box.
Here is a sample:
@image html overview_sizer_09.png
@section overview_sizer_grid wxGridSizer
wxGridSizer is a two-dimensional sizer. All children are given the same size,
which is the minimal size required by the biggest child, in this case the text
control in the left bottom border. Either the number of columns or the number
or rows is fixed and the grid sizer will grow in the respectively other
orientation if new children are added:
@image html overview_sizer_10.png
@section overview_sizer_flexgrid wxFlexGridSizer
wxFlexGridSizer is a two-dimensional sizer derived from wxGridSizer. The width of each
column and the height of each row are calculated individually according to the
minimal requirements from the respectively biggest child. Additionally, columns
and rows can be declared to be stretchable if the sizer is assigned a size
different from the one it requested. The following sample shows the same dialog
as the one above, but using a flex grid sizer:
@image html overview_sizer_11.png
@section overview_sizer_programming_box Programming with wxBoxSizer
The basic idea behind a wxBoxSizer is that windows will most often be laid out
in rather simple basic geometry, typically in a row or a column or several
hierarchies of either.
As an example, we will construct a dialog that will contain a text field at the
top and two buttons at the bottom. This can be seen as a top-hierarchy column
with the text at the top and buttons at the bottom and a low-hierarchy row with
an OK button to the left and a Cancel button to the right. In many cases
(particularly dialogs under Unix and normal frames) the main window will be
resizable by the user and this change of size will have to get propagated to
its children. In our case, we want the text area to grow with the dialog,
whereas the button shall have a fixed size. In addition, there will be a thin
border around all controls to make the dialog look nice and - to make matter
worse - the buttons shall be centred as the width of the dialog changes.
It is the unique feature of a box sizer, that it can grow in both directions
(height and width) but can distribute its growth in the main direction
(horizontal for a row) @e unevenly among its children. In our example case, the
vertical sizer is supposed to propagate all its height changes to only the text
area, not to the button area. This is determined by the @e proportion parameter
when adding a window (or another sizer) to a sizer. It is interpreted as a
weight factor, i.e. it can be zero, indicating that the window may not be
resized at all, or above zero. If several windows have a value above zero, the
value is interpreted relative to the sum of all weight factors of the sizer, so
when adding two windows with a value of @c 1, they will both get resized equally
much and each half as much as the sizer owning them. Then what do we do when a
column sizer changes its width? This behaviour is controlled by @e flags (the
second parameter of the Add() function): Zero or no flag indicates that the
window will preserve it is original size, @c wxGROW flag (same as @c wxEXPAND) forces
the window to grow with the sizer, and @c wxSHAPED flag tells the window to change
it is size proportionally, preserving original aspect ratio. When @c wxGROW flag
is not used, the item can be aligned within available space. @c wxALIGN_LEFT,
@c wxALIGN_TOP, @c wxALIGN_RIGHT, @c wxALIGN_BOTTOM, @c wxALIGN_CENTER_HORIZONTAL
and @c wxALIGN_CENTER_VERTICAL do what they say. @c wxALIGN_CENTRE (same as
@c wxALIGN_CENTER) is defined as (<tt>wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL</tt>).
Default alignment is <tt>wxALIGN_LEFT | wxALIGN_TOP</tt>.
As mentioned above, any window belonging to a sizer may have a border, and it
can be specified which of the four sides may have this border, using the @c wxTOP,
@c wxLEFT, @c wxRIGHT and @c wxBOTTOM constants or wxALL for all directions (and you may
also use @c wxNORTH, @c wxWEST etc instead). These flags can be used in combination
with the alignment flags above as the second parameter of the Add() method
using the binary @c or operator @c |. The sizer of the border also must be made
known, and it is the third parameter in the Add() method. This means, that the
entire behaviour of a sizer and its children can be controlled by the three
parameters of the Add() method.
@code
// We want to get a dialog that is stretchable because it
// has a text ctrl at the top and two buttons at the bottom.
MyDialog::MyDialog(wxFrame *parent, wxWindowID id, const wxString &title )
: wxDialog(parent, id, title, wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
// create text ctrl with minimal size 100x60
topsizer->Add(
new wxTextCtrl( this, -1, "My text.", wxDefaultPosition, wxSize(100,60), wxTE_MULTILINE),
1, // make vertically stretchable
wxEXPAND | // make horizontally stretchable
wxALL, // and make border all around
10 ); // set border width to 10
wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
button_sizer->Add(
new wxButton( this, wxID_OK, "OK" ),
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
10 ); // set border width to 10
button_sizer->Add(
new wxButton( this, wxID_CANCEL, "Cancel" ),
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
10 ); // set border width to 10
topsizer->Add(
button_sizer,
0, // make vertically unstretchable
wxALIGN_CENTER ); // no border and centre horizontally
SetSizerAndFit(topsizer); // use the sizer for layout and size window
// accordingly and prevent it from being resized
// to smaller size
}
@endcode
Note that the recommended way of specifying flags to wxSizer is via wxSizerFlags.
This class greatly eases the burden of passing flags to a wxSizer.
Here's how you'd do the previous example with wxSizerFlags:
@code
// We want to get a dialog that is stretchable because it
// has a text ctrl at the top and two buttons at the bottom.
MyDialog::MyDialog(wxFrame *parent, wxWindowID id, const wxString &title )
: wxDialog(parent, id, title, wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
// create text ctrl with minimal size 100x60 that is horizontally and
// vertically stretchable with a border width of 10
topsizer->Add(
new wxTextCtrl( this, -1, "My text.", wxDefaultPosition, wxSize(100,60), wxTE_MULTILINE),
wxSizerFlags(1).Align().Expand().DoubleBorder(wxALL));
wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
//create two buttons that are horizontally unstretchable,
// with an all-around border with a width of 10 and implicit top alignment
button_sizer->Add(
new wxButton( this, wxID_OK, "OK" ),
wxSizerFlags(0).Align().DoubleBorder(wxALL));
button_sizer->Add(
new wxButton( this, wxID_CANCEL, "Cancel" ),
wxSizerFlags(0).Align().DoubleBorder(wxALL));
//create a sizer with no border and centered horizontally
topsizer->Add(
button_sizer,
wxSizerFlags(0).Center() );
SetSizerAndFit(topsizer); // use the sizer for layout and set size and hints
}
@endcode
@section overview_sizer_types Other Types of Sizers
wxStdDialogButtonSizer is a sizer that creates button layouts in dialogs
which conform to the standard button spacing and ordering defined by
the platform or toolkit's user interface guidelines (if such things exist).
As a convenience, wxDialog::CreateButtonSizer() can be used to create this sizer.
wxWrapSizer is a sizer that lays out its items in a single line, like a box
sizer -- as long as there is space available in that direction. Once all available
space in the primary direction has been used, a new line is added and items
are added there.
wxGridBagSizer is a rather special kind of sizer which, unlike the other
classes, allows to directly put the elements at the given position in the
sizer.
*/

View File

@@ -0,0 +1,79 @@
/////////////////////////////////////////////////////////////////////////////
// Name: splitterwindow.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_splitterwindow wxSplitterWindow Overview
@tableofcontents
@see wxSplitterWindow
@section overview_splitterwindow_appearance Appearance
The following screenshot shows the appearance of a splitter window with a
horizontal split.
The style wxSP_3D has been used to show a 3D border and 3D sash.
@image html overview_splitter_3d.png
@section overview_splitterwindow_example Example
The following fragment shows how to create a splitter window, creating two
subwindows and hiding one of them.
@code
splitter = new wxSplitterWindow(this, -1, wxPoint(0, 0),
wxSize(400, 400), wxSP_3D);
leftWindow = new MyWindow(splitter);
leftWindow->SetScrollbars(20, 20, 50, 50);
rightWindow = new MyWindow(splitter);
rightWindow->SetScrollbars(20, 20, 50, 50);
rightWindow->Show(false);
splitter->Initialize(leftWindow);
// Set this to prevent unsplitting
// splitter->SetMinimumPaneSize(20);
@endcode
The next fragment shows how the splitter window can be manipulated after
creation.
@code
void MyFrame::OnSplitVertical(wxCommandEvent& event)
{
if ( splitter->IsSplit() )
splitter->Unsplit();
leftWindow->Show(true);
rightWindow->Show(true);
splitter->SplitVertically( leftWindow, rightWindow );
}
void MyFrame::OnSplitHorizontal(wxCommandEvent& event)
{
if ( splitter->IsSplit() )
splitter->Unsplit();
leftWindow->Show(true);
rightWindow->Show(true);
splitter->SplitHorizontally( leftWindow, rightWindow );
}
void MyFrame::OnUnsplit(wxCommandEvent& event)
{
if ( splitter->IsSplit() )
splitter->Unsplit();
}
@endcode
*/

View File

@@ -0,0 +1,105 @@
/////////////////////////////////////////////////////////////////////////////
// Name: stream.h
// Purpose: stream classes overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_stream Stream Classes Overview
@tableofcontents
wxWidgets provides its own set of stream classes in order to support platforms
not providing standard C++ streams implementation and also to make it possible
to provide binary versions of wxWidgets application not depending on any
particular standard library version. The wxWidgets stream classes also provide
some functionality not available in the standard library such as support for
several compression formats and possibility to work with sockets or text
controls (for output only in the latter case).
Nevertheless wxWidgets programs can also use standard stream classes and are
encouraged to do so if the above considerations don't apply. Moreover,
wxStdInputStream and wxStdOutputStream classes are provided to provide a degree
of interoperability between the two and make it possible to use any wxWidgets
stream as a standard stream (the converse possibility to use a standard stream
as a wxWidgets stream is planned for a future release).
@section overview_stream_classes Stream Classes
wxStream classes are divided in two main groups:
@li The core: wxStreamBase, wxStreamBuffer, wxInputStream, wxOutputStream,
wxFilterInputStream, wxFilterOutputStream
@li The "IO" classes: wxSocketInputStream, wxSocketOutputStream,
wxFileInputStream, wxFileOutputStream, ...
@li Classes for reading text or binary data from a particular stream
such as wxTextInputStream, wxTextOutputStream, wxDataInputStream
and wxDataOutputStream
wxStreamBase is the base definition of a stream. It defines, for example, the
API of OnSysRead(), OnSysWrite(), OnSysSeek() and OnSysTell(). These functions are
really implemented by the "IO" classes.
wxInputStream and wxOutputStream classes inherit from wxStreamBase and provide
specialized methods for input and output.
wxStreamBuffer is a cache manager for wxStreamBase: it manages a stream buffer
linked to a stream. One stream can have multiple stream buffers but one stream
has always one autoinitialized stream buffer.
wxInputStream is the base class for read-only streams. It implements Read(),
SeekI() (I for Input), and all read or IO generic related functions.
wxOutputStream does the same thing for write-only streams.
wxFilterInputStream and wxFileterOutputStream are the base class definitions for
stream filtering.
Stream filtering means a stream which does no syscall but filters data which
are passed to it and then pass them to another stream.
For example, wxZLibInputStream is an inline stream decompressor.
The "IO" classes implements the specific parts of the stream. This could be
nothing in the case of wxMemoryInputStream and wxMemoryOutputStream which base
themselves on wxStreamBuffer.
This could also be a simple link to the true syscall (for example read(...), write(...)).
@section overview_stream_example Example
Usage is simple. We can take the example of wxFileInputStream and here is some
sample code:
@code
...
// The constructor initializes the stream buffer and open the file descriptor
// associated to the name of the file.
wxFileInputStream in_stream("the_file_to_be_read");
// Ok, read some bytes ... nb_datas is expressed in bytes.
in_stream.Read(data, nb_datas);
if (in_stream.LastError() != wxSTREAM_NOERROR) {
// Oh oh, something bad happens.
// For a complete list, look into the documentation at wxStreamBase.
}
// You can also inline all like this.
if (in_stream.Read(data, nb_datas).LastError() != wxSTREAM_NOERROR) {
// Do something.
}
// You can also get the last number of bytes REALLY put into the buffer.
size_t really_read = in_stream.LastRead();
// Ok, moves to the beginning of the stream. SeekI returns the last position
// in the stream counted from the beginning.
off_t old_position = in_stream.SeekI(0, wxFromBeginning);
// What is my current position ?
off_t position = in_stream.TellI();
// wxFileInputStream will close the file descriptor on destruction.
@endcode
*/

View File

@@ -0,0 +1,156 @@
/////////////////////////////////////////////////////////////////////////////
// Name: string.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_string wxString Overview
@tableofcontents
wxString is used for all strings in wxWidgets. This class is very similar to
the standard string class, and is implemented using it, but provides additional
compatibility functions to allow applications originally written for the much
older versions of wxWidgets to continue to work with the latest ones.
When writing new code, you're encouraged to use wxString as if it were
`std::wstring` and use only functions compatible with the standard class.
@section overview_string_settings wxString Related Compilation Settings
The main build options affecting wxString are `wxUSE_UNICODE_WCHAR` and
`wxUSE_UNICODE_UTF8`, exactly one of which must be set to determine whether
fixed-width `wchar_t` or variable-width `char`-based strings are used
internally. Please see @ref overview_unicode_support_utf for more information
about this choice.
The other options all affect the presence, or absence, of various implicit
conversions provided by this class. By default, wxString can be implicitly
created from `char*`, `wchar_t*`, `std::string` and `std::wstring` and can be
implicitly converted to `char*` or `wchar_t*`. This behaviour is convenient
and compatible with the previous wxWidgets versions, but is dangerous and may
result in unwanted conversions, please see @ref string_conv for how to disable
them.
@section overview_string_iterating Iterating over wxString
It is possible to iterate over strings using indices, but the recommended way
to do it is to use iterators, either explicitly:
@code
wxString s = "hello";
wxString::const_iterator i;
for (i = s.begin(); i != s.end(); ++i)
{
wxUniChar uni_ch = *i;
// do something with it
}
@endcode
or, even simpler, implicitly, using range for loop:
@code
wxString s = "hello";
for ( auto c : s )
{
// do something with "c"
}
@endcode
@note wxString iterators have unusual proxy-like semantics and can be used to
modify the string even when @e not using references, i.e. with just @c
auto, as in the example above.
@section overview_string_internal wxString Internal Representation
@note This section can be skipped at first reading and is provided solely for
informational purposes.
As mentioned above, wxString may use any of @c UTF-16 (under Windows, using
the native 16 bit @c wchar_t), @c UTF-32 (under Unix, using the native 32
bit @c wchar_t) or @c UTF-8 (under both Windows and Unix) to store its
content. By default, @c wchar_t is used under all platforms, but wxWidgets can
be compiled with <tt>wxUSE_UNICODE_UTF8=1</tt> to use UTF-8 instead.
For simplicity of implementation, wxString uses <em>per code unit indexing</em>
instead of <em>per code point indexing</em> when using UTF-16, i.e. in the
default <tt>wxUSE_UNICODE_WCHAR==1</tt> build under Windows and doesn't know
anything about surrogate pairs. In other words it always considers code points
to be composed by 1 code unit, while this is really true only for characters in
the @e BMP (Basic Multilingual Plane), as explained in more details in the @ref
overview_unicode_encodings section. Thus when iterating over a UTF-16 string
stored in a wxString under Windows, the user code has to take care of
<em>surrogate pairs</em> manually if it needs to handle them (note however that
Windows itself has built-in support for surrogate pairs in UTF-16, such as for
drawing strings on screen, so nothing special needs to be done when just
passing strings containing surrogates to wxWidgets functions).
@remarks
Note that while the behaviour of wxString when <tt>wxUSE_UNICODE_WCHAR==1</tt>
resembles UCS-2 encoding, it's not completely correct to refer to wxString as
UCS-2 encoded since you can encode code points outside the @e BMP in a wxString
as two code units (i.e. as a surrogate pair; as already mentioned however wxString
will "see" them as two different code points)
In <tt>wxUSE_UNICODE_UTF8==1</tt> case, wxString handles UTF-8 multi-bytes
sequences just fine also for characters outside the BMP (it implements <em>per
code point indexing</em>), so that you can use UTF-8 in a completely transparent
way:
Example:
@code
// first test, using exotic characters outside of the Unicode BMP:
wxString test = wxString::FromUTF8("\xF0\x90\x8C\x80");
// U+10300 is "OLD ITALIC LETTER A" and is part of Unicode Plane 1
// in UTF8 it's encoded as 0xF0 0x90 0x8C 0x80
// it's a single Unicode code-point encoded as:
// - a UTF16 surrogate pair under Windows
// - a UTF8 multiple-bytes sequence under Linux
// (without considering the final NUL)
wxPrintf("wxString reports a length of %d character(s)", test.length());
// prints "wxString reports a length of 1 character(s)" on Linux
// prints "wxString reports a length of 2 character(s)" on Windows
// since wxString on Windows doesn't have surrogate pairs support!
// second test, this time using characters part of the Unicode BMP:
wxString test2 = wxString::FromUTF8("\x41\xC3\xA0\xE2\x82\xAC");
// this is the UTF8 encoding of capital letter A followed by
// 'small case letter a with grave' followed by the 'euro sign'
// they are 3 Unicode code-points encoded as:
// - 3 UTF16 code units under Windows
// - 6 UTF8 code units under Linux
// (without considering the final NUL)
wxPrintf("wxString reports a length of %d character(s)", test2.length());
// prints "wxString reports a length of 3 character(s)" on Linux
// prints "wxString reports a length of 3 character(s)" on Windows
@endcode
To better explain what stated above, consider the second string of the example
above; it's composed by 3 characters and the final @NUL:
@image html overview_wxstring_encoding.png
As you can see, UTF16 encoding is straightforward (for characters in the @e BMP)
and in this example the UTF16-encoded wxString takes 8 bytes.
UTF8 encoding is more elaborated and in this example takes 7 bytes.
In general, for strings containing many latin characters UTF8 provides a big
advantage with regards to the memory footprint respect UTF16, but requires some
more processing for common operations like e.g. length calculation.
Finally, note that the type used by wxString to store Unicode code units
(@c wchar_t or @c char) is always @c typedef-ined to be ::wxStringCharType.
*/

View File

@@ -0,0 +1,90 @@
/////////////////////////////////////////////////////////////////////////////
// Name: thread.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/*
NOTE: we explicitly don't name wxMutexGUIEnter() and wxMutexGUILeave()
as they're not safe. See also ticket #10366.
*/
/**
@page overview_thread Multithreading Overview
@tableofcontents
@note In the new code, it is highly recommended to use concurrency classes
provided in C++11 and newer, instead of their wxWidgets counterparts.
The warning about not using GUI classes from non-GUI threads still applies.
wxWidgets provides a complete set of classes encapsulating objects necessary in
multi-threaded (MT) applications: the wxThread class itself and different
synchronization objects: mutexes (see wxMutex) and critical sections (see
wxCriticalSection) with conditions (see wxCondition). The thread API in
wxWidgets resembles to POSIX thread API (a.k.a. pthreads), although several
functions have different names and some features inspired by Win32 thread API
are there as well.
These classes hopefully make writing MT programs easier and they also provide
some extra error checking (compared to the native - be it Win32 or Posix -
thread API).
To implement non-blocking operations @e without using multiple threads you have
two possible implementation choices:
- use wxIdleEvent (e.g. to perform a long calculation while updating a progress dialog)
- do everything at once but call wxWindow::Update() or wxEventLoopBase::YieldFor(wxEVT_CATEGORY_UI)
periodically to update the screen.
However, it is generally much better to run time-consuming tasks in worker threads instead
of trying to work around blocked GUI (and risk reentrancy problems).
@see wxThread, wxThreadHelper, wxMutex, wxCriticalSection, wxCondition,
wxSemaphore
@section overview_thread_notes Important Notes for Multi-threaded Applications
When writing a multi-threaded application, it is strongly recommended that
<b>no secondary threads call GUI functions</b>. The design which uses one GUI
thread and several worker threads which communicate with the main one using
@b events is much more robust and will undoubtedly save you countless problems
(example: under Win32 a thread can only access GDI objects such as pens,
brushes, device contexts created by itself and not by the other threads).
The GUI thread is the thread in which wxWidgets was initialized, where
wxIsMainThread() returns @true.
For communication between secondary threads and the main thread, you may use
wxEvtHandler::QueueEvent() or its short version ::wxQueueEvent(). These functions
have a thread-safe implementation so that they can be used as they are for
sending events from one thread to another. However there is no built in method
to send messages to the worker threads and you will need to use the available
synchronization classes to implement the solution which suits your needs
yourself. In particular, please note that it is not enough to derive your class
from wxThread and wxEvtHandler to send messages to it: in fact, this does not
work at all. You're instead encouraged to use wxThreadHelper as it greatly
simplifies the communication and the sharing of resources.
For communication between the main thread and worker threads, you can use
wxMessageQueue<> class that allows to send any kind of custom messages. It is
often convenient to have a special message asking the thread to terminate.
You should also look at the wxThread docs for important notes about secondary
threads and their deletion.
Last, remember that if wxEventLoopBase::YieldFor() is used directly or
indirectly (e.g. through wxProgressDialog) in your code, then you may have both
re-entrancy problems and also problems caused by the processing of events out
of order. To resolve the last problem wxThreadEvent can be used: thanks to its
implementation of the wxThreadEvent::GetEventCategory function wxThreadEvent
classes in fact do not get processed by wxEventLoopBase::YieldFor() unless you
specify the @c wxEVT_CATEGORY_THREAD flag.
See also the @sample{thread} for a sample showing some simple interactions
between the main and secondary threads.
*/

View File

@@ -0,0 +1,76 @@
/////////////////////////////////////////////////////////////////////////////
// Name: tips.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_tips wxTipProvider Overview
@tableofcontents
Many "modern" Windows programs have a feature (some would say annoyance) of
presenting the user tips at program startup. While this is probably useless to
the advanced users of the program, the experience shows that the tips may be
quite helpful for the novices and so more and more programs now do this. For a
wxWidgets programmer, implementing this feature is extremely easy. To show a
tip, it is enough to just call wxShowTip function like this:
@code
if ( ...show tips at startup?... )
{
wxTipProvider *tipProvider = wxCreateFileTipProvider("tips.txt", 0);
wxShowTip(windowParent, tipProvider);
delete tipProvider;
}
@endcode
Of course, you need to get the text of the tips from somewhere - in the example
above, the text is supposed to be in the file tips.txt from where it is read by
the <em>tip provider</em>. The tip provider is just an object of a class
deriving from wxTipProvider. It has to implement one pure virtual function of
the base class: GetTip. In the case of the tip provider created by
wxCreateFileTipProvider, the tips are just the lines of the text file.
If you want to implement your own tip provider (for example, if you wish to
hardcode the tips inside your program), you just have to derive another class
from wxTipProvider and pass a pointer to the object of this class to
wxShowTip - then you don't need wxCreateFileTipProvider at all.
You will probably want to save somewhere the index of the tip last shown - so
that the program doesn't always show the same tip on startup. As you also need
to remember whether to show tips or not (you shouldn't do it if the user
unchecked "Show tips on startup" checkbox in the dialog), you will probably
want to store both the index of the last shown tip (as returned by
wxTipProvider::GetCurrentTip and the flag telling whether to show the tips at
startup at all.
In a tips.txt file, lines that begin with a # character are considered comments
and are automatically skipped. Blank lines and lines only having spaces are
also skipped.
You can easily add runtime-translation capacity by placing each line of the
tips.txt file inside the usual translation macro. For example, your tips.txt
file would look like this:
@code
_("This is my first tip")
_("This is my second tip")
@endcode
Now add your tips.txt file into the list of files that gettext searches for
translatable strings. The tips will thus get included into your generated .po
file catalog and be translated at runtime along with the rest of your
application's translatable strings.
@note Each line in the tips.txt file needs to strictly begin with exactly the 3
characters of underscore-parenthesis-doublequote, and end with
doublequote-parenthesis, as shown above. Also, remember to escape any
doublequote characters within the tip string with a backslash-doublequote.
See the dialogs program in your samples folder for a working example inside a
program.
*/

View File

@@ -0,0 +1,61 @@
/////////////////////////////////////////////////////////////////////////////
// Name: toolbar.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_toolbar Toolbar Overview
@tableofcontents
The toolbar family of classes allows an application to use toolbars in a
variety of configurations and styles.
The toolbar is a popular user interface component and contains a set of bitmap
buttons or toggles. A toolbar gives faster access to an application's
facilities than menus, which have to be popped up and selected rather
laboriously.
Instead of supplying one toolbar class with a number of different
implementations depending on platform, wxWidgets separates out the classes.
This is because there are a number of different toolbar styles that you may
wish to use simultaneously, and also, future toolbar implementations will
emerge which cannot all be shoe-horned into the one class.
For each platform, the symbol wxToolBar is defined to be one of the specific
toolbar classes.
The following is a summary of the toolbar classes and their differences:
@li wxToolBarBase: This is a base class with pure virtual functions, and should
not be used directly.
A toolbar might appear as a single row of images under the menubar, or it might
be in a separate frame layout in several rows and columns. The class handles
the layout of the images, unless explicit positioning is requested.
A tool is a bitmap which can either be a button (there is no 'state', it just
generates an event when clicked) or it can be a toggle. If a toggle, a second
bitmap can be provided to depict the 'on' state; if the second bitmap is
omitted, either the inverse of the first bitmap will be used (for monochrome
displays) or a thick border is drawn around the bitmap (for colour displays
where inverting will not have the desired result).
The Windows-specific toolbar classes expect 16-colour bitmaps that are 16
pixels wide and 15 pixels high. If you want to use a different size, call
@c SetToolBitmapSize as the demo shows, before adding tools to the button bar.
Don't supply more than one bitmap for each tool, because the toolbar generates
all three images (normal, depressed, and checked) from the single bitmap you
give it.
@section overview_toolbar_library Using the Toolbar Library
Include @c "wx/toolbar.h"
An example of using a toolbar is given in the "toolbar" sample.
*/

View File

@@ -0,0 +1,82 @@
/////////////////////////////////////////////////////////////////////////////
// Name: treectrl.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_treectrl wxTreeCtrl Overview
@tableofcontents
The tree control displays its items in a tree like structure. Each item has
its own (optional) icon and a label. An item may be either collapsed (meaning
that its children are not visible) or expanded (meaning that its children are
shown). Each item in the tree is identified by its @c itemId which is of opaque
data type wxTreeItemId. You can test whether an item is valid by calling
wxTreeItemId::IsOk.
@see wxTreeCtrl, wxImageList
The items text and image may be retrieved and changed with (Get|Set)ItemText
and (Get|Set)ItemImage. In fact, an item may even have two images associated
with it: the normal one and another one for selected state which is
set/retrieved with (Get|Set)ItemSelectedImage functions, but this functionality
might be unavailable on some platforms.
Tree items have several attributes: an item may be selected or not, visible or
not, bold or not. It may also be expanded or collapsed. All these attributes
may be retrieved with the corresponding functions: IsSelected, IsVisible,
IsBold and IsExpanded. Only one item at a time may be selected, selecting
another one (with SelectItem) automatically unselects the previously selected
one.
In addition to its icon and label, a user-specific data structure may be
associated with all tree items. If you wish to do it, you should derive a class
from wxTreeItemData which is a very simple class having only one function
GetId() which returns the id of the item this data is associated with. This
data will be freed by the control itself when the associated item is deleted
(all items are deleted when the control is destroyed), so you shouldn't delete
it yourself (if you do it, you should call SetItemData(@NULL) to prevent the
tree from deleting the pointer second time). The associated data may be
retrieved with GetItemData() function.
Working with trees is relatively straightforward if all the items are added to
the tree at the moment of its creation. However, for large trees it may be
very inefficient. To improve the performance you may want to delay adding the
items to the tree until the branch containing the items is expanded: so, in the
beginning, only the root item is created (with AddRoot). Other items are added
when EVT_TREE_ITEM_EXPANDING event is received: then all items lying
immediately under the item being expanded should be added, but, of course, only
when this event is received for the first time for this item - otherwise, the
items would be added twice if the user expands/collapses/re-expands the branch.
The tree control provides functions for enumerating its items. There are 3
groups of enumeration functions: for the children of a given item, for the
sibling of the given item and for the visible items (those which are currently
shown to the user: an item may be invisible either because its branch is
collapsed or because it is scrolled out of view). Child enumeration functions
require the caller to give them a @e cookie parameter: it is a number which
is opaque to the caller but is used by the tree control itself to allow
multiple enumerations to run simultaneously (this is explicitly allowed). The
only thing to remember is that the @e cookie passed to GetFirstChild and to
GetNextChild should be the same variable (and that nothing should be done with
it by the user code).
Among other features of the tree control are: item sorting with SortChildren
which uses the user-defined comparison function OnCompareItems (by default the
comparison is the alphabetic comparison of tree labels), hit testing
(determining to which portion of the control the given point belongs, useful
for implementing drag-and-drop in the tree) with HitTest and editing of the
tree item labels in place (see EditLabel).
Finally, the tree control has a keyboard interface: the cursor navigation
(arrow) keys may be used to change the current selection. HOME and END are used
to go to the first/last sibling of the current item. '+', '-' and '*' expand,
collapse and toggle the current branch. Note, however, that DEL and INS keys do
nothing by default, but it is common to associate them with deleting an item
from a tree and inserting a new one into it.
*/

View File

@@ -0,0 +1,435 @@
/////////////////////////////////////////////////////////////////////////////
// Name: unicode.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_unicode Unicode Support in wxWidgets
@tableofcontents
This section describes how does wxWidgets support Unicode and how can it affect
your programs.
Notice that Unicode support has changed radically in wxWidgets 3.0 and a lot of
existing material pertaining to the previous versions of the library is not
correct any more. Please see @ref overview_changes_unicode for the details of
these changes.
You can skip the first two sections if you're already familiar with Unicode and
wish to jump directly in the details of its support in the library.
@section overview_unicode_what What is Unicode?
Unicode is a standard for character encoding which addresses the shortcomings
of the previous standards (e.g. the ASCII standard), by using 8, 16 or 32 bits
for encoding each character.
This allows enough code points (see below for the definition) sufficient to
encode all of the world languages at once.
More details about Unicode may be found at http://www.unicode.org/.
From a practical point of view, using Unicode is almost a requirement when
writing applications for international audience. Moreover, any application
reading files which it didn't produce or receiving data from the network from
other services should be ready to deal with Unicode.
@section overview_unicode_encodings Unicode Representations and Terminology
When working with Unicode, it's important to define the meaning of some terms.
A <b><em>glyph</em></b> is a particular image (usually part of a font) that
represents a character or part of a character.
Any character may have one or more glyph associated; e.g. some of the possible
glyphs for the capital letter 'A' are:
@image html overview_unicode_glyphs.png
Unicode assigns each character of almost any existing alphabet/script a number,
which is called <b><em>code point</em></b>; it's typically indicated in documentation
manuals and in the Unicode website as @c U+xxxx where @c xxxx is an hexadecimal number.
Note that typically one character is assigned exactly one code point, but there
are exceptions; the so-called <em>precomposed characters</em>
(see http://en.wikipedia.org/wiki/Precomposed_character) or the <em>ligatures</em>.
In these cases a single "character" may be mapped to more than one code point or
vice versa more than one character may be mapped to a single code point.
The Unicode standard divides the space of all possible code points in <b><em>planes</em></b>;
a plane is a range of 65,536 (1000016) contiguous Unicode code points.
Planes are numbered from 0 to 16, where the first one is the @e BMP, or Basic
Multilingual Plane.
The BMP contains characters for all modern languages, and a large number of
special characters. The other planes in fact contain mainly historic scripts,
special-purpose characters or are unused.
Code points are represented in computer memory as a sequence of one or more
<b><em>code units</em></b>, where a code unit is a unit of memory: 8, 16, or 32 bits.
More precisely, a code unit is the minimal bit combination that can represent a
unit of encoded text for processing or interchange.
The <b><em>UTF</em></b> or Unicode Transformation Formats are algorithms mapping the Unicode
code points to code unit sequences. The simplest of them is <b>UTF-32</b> where
each code unit is composed by 32 bits (4 bytes) and each code point is always
represented by a single code unit (fixed length encoding).
(Note that even UTF-32 is still not completely trivial as the mapping is different
for little and big-endian architectures). UTF-32 is commonly used under Unix systems for
internal representation of Unicode strings.
Another very widespread standard is <b>UTF-16</b> which is used by Microsoft Windows:
it encodes the first (approximately) 64 thousands of Unicode code points
(the BMP plane) using 16-bit code units (2 bytes) and uses a pair of 16-bit code
units to encode the characters beyond this. These pairs are called @e surrogate.
Thus UTF16 uses a variable number of code units to encode each code point.
Finally, the most widespread encoding used for the external Unicode storage
(e.g. files and network protocols) is <b>UTF-8</b> which is byte-oriented and so
avoids the endianness ambiguities of UTF-16 and UTF-32.
UTF-8 uses code units of 8 bits (1 byte); code points beyond the usual english
alphabet are represented using a variable number of bytes, which makes it less
efficient than UTF-32 for internal representation.
As visual aid to understand the differences between the various concepts described
so far, look at the different UTF representations of the same code point:
@image html overview_unicode_codes.png
In this particular case UTF8 requires more space than UTF16 (3 bytes instead of 2).
Note that from the C/C++ programmer perspective the situation is further complicated
by the fact that the standard type @c wchar_t which is usually used to represent the
Unicode ("wide") strings in C/C++ doesn't have the same size on all platforms.
It is 4 bytes under Unix systems, corresponding to the tradition of using
UTF-32, but only 2 bytes under Windows which is required by compatibility with
the OS which uses UTF-16.
Typically when UTF8 is used, code units are stored into @c char types, since
@c char are 8bit wide on almost all systems; when using UTF16 typically code
units are stored into @c wchar_t types since @c wchar_t is at least 16bits on
all systems. This is also the approach used by wxString.
See @ref overview_string for more info.
See also http://unicode.org/glossary/ for the official definitions of the
terms reported above.
@section overview_unicode_supportin Unicode Support in wxWidgets
@subsection overview_unicode_support_default Unicode is Always Used by Default
Since wxWidgets 3.0 Unicode support is always enabled and while building the
library without it is still possible, it is not recommended any longer and will
cease to be supported in the near future. This means that internally only
Unicode strings are used and that, under Microsoft Windows, Unicode system API
is used.
However, unlike the Unicode build mode of the previous versions of wxWidgets, this
support is mostly transparent: you can still continue to work with the @b narrow
(i.e. current locale-encoded @c char*) strings even if @b wide
(i.e. UTF16-encoded @c wchar_t* or UTF8-encoded @c char*) strings are also
supported. Any wxWidgets function accepts arguments of either type as both
kinds of strings are implicitly converted to wxString, so both
@code
wxMessageBox("Hello, world!");
@endcode
and the somewhat less usual
@code
wxMessageBox(L"Salut \u00E0 toi!"); // U+00E0 is "Latin Small Letter a with Grave"
@endcode
work as expected.
Notice that the narrow strings used with wxWidgets are @e always assumed to be
in the current locale encoding, so writing
@code
wxMessageBox("Salut à toi!");
@endcode
wouldn't work if the encoding used on the user system is incompatible with
ISO-8859-1 (or even if the sources were compiled under different locale
in the case of gcc). In particular, the most common encoding used under
modern Unix systems is UTF-8 and as the string above is not a valid UTF-8 byte
sequence, nothing would be displayed at all in this case. Thus it is important
to <b>never use 8-bit (instead of 7-bit) characters directly in the program source</b>
but use wide strings or, alternatively, write:
@code
wxMessageBox(wxString::FromUTF8("Salut \xC3\xA0 toi!"));
// in UTF8 the character U+00E0 is encoded as 0xC3A0
@endcode
In a similar way, wxString provides access to its contents as either @c wchar_t or
@c char character buffer. Of course, the latter only works if the string contains
data representable in the current locale encoding. This will always be the case
if the string had been initially constructed from a narrow string or if it
contains only 7-bit ASCII data but otherwise this conversion is not guaranteed
to succeed. And as with wxString::FromUTF8() example above, you can always use
wxString::ToUTF8() to retrieve the string contents in UTF-8 encoding -- this,
unlike converting to @c char* using the current locale, never fails.
For more info about how wxString works, please see the @ref overview_string.
To summarize, Unicode support in wxWidgets is mostly @b transparent for the
application and if you use wxString objects for storing all the character data
in your program there is really nothing special to do. However you should be
aware of the potential problems covered by the following section.
@subsection overview_unicode_support_utf Choosing Unicode Representation
wxWidgets uses the system @c wchar_t in wxString implementation by default
under all systems. Thus, under Microsoft Windows, UCS-2 (simplified version of
UTF-16 without support for surrogate characters) is used as @c wchar_t is 2
bytes on this platform. Under Unix systems, including macOS, UCS-4 (also
known as UTF-32) is used by default, however it is also possible to build
wxWidgets to use UTF-8 internally by passing @c \--enable-utf8 option to
configure or setting `wxUSE_UNICODE_UTF8` to 1 in `wx/setup.h`.
The interface provided by wxString is the same independently of the format used
internally. However different formats have specific advantages and
disadvantages. Notably, under Unix, the underlying graphical toolkit (e.g.
GTK+) usually uses UTF-8 encoded strings and using the same representations for
the strings in wxWidgets allows to avoid conversion from UTF-32 to UTF-8 and
vice versa each time a string is shown in the UI or retrieved from it. The
overhead of such conversions is usually negligible for small strings but may be
important for some programs. If you believe that it would be advantageous to
use UTF-8 for the strings in your particular application, you may rebuild
wxWidgets to use UTF-8 as explained above (notice that this is currently not
supported under Microsoft Windows and arguably doesn't make much sense there as
Windows itself uses UTF-16 and not UTF-8) but be sure to be aware of the
performance implications (see @ref overview_unicode_performance) of using UTF-8
in wxString before doing this!
Generally speaking you should only use non-default UTF-8 build in specific
circumstances e.g. building for resource-constrained systems where the overhead
of conversions (and also reduced memory usage of UTF-8 compared to UTF-32 for
the European languages) can be important. If the environment in which your
program is running is under your control -- as is quite often the case in such
scenarios -- consider ensuring that the system always uses UTF-8 locale and
use @c \--enable-utf8only configure option to disable support for the other
locales and consider all strings to be in UTF-8. This further reduces the code
size and removes the need for conversions in more cases.
@subsection overview_unicode_settings Unicode Related Preprocessor Symbols
@c wxUSE_UNICODE is always defined as 1 in wxWidgets 3.3 or later. By default, @c
wxUSE_UNICODE_WCHAR is also defined as 1, however in UTF-8 build (described in
the previous section), it is set to 0 and @c wxUSE_UNICODE_UTF8, which is
usually 0, is set to 1 instead. In the latter case, @c wxUSE_UTF8_LOCALE_ONLY
can also be set to 1 to indicate that all strings are considered to be in UTF-8.
@section overview_unicode_pitfalls Potential Unicode Pitfalls
The problems can be separated into three broad classes:
@subsection overview_unicode_compilation_errors Unicode-Related Compilation Errors
Because of the need to support implicit conversions to both @c char and
@c wchar_t, wxString implementation is rather involved and many of its operators
don't return the types which they could be naively expected to return.
For example, the @c operator[] doesn't return either a @c char or a @c wchar_t
and instead returns an object of a helper class wxUniChar or wxUniCharRef that is
implicitly convertible to either. Usually you don't need to worry about this as
the conversions do their work behind the scenes however in some cases it doesn't
work. Here are some examples, using a wxString object @c s and some integer @c
n:
- Writing @code switch ( s[n] ) @endcode doesn't work because the argument of
the switch statement must be an integer expression so you need to replace
@c s[n] with @code s[n].GetValue() @endcode. You may also force the
conversion to @c char or @c wchar_t by using an explicit cast but beware that
converting the value to char uses the conversion to current locale and may
return 0 if it fails. Finally notice that writing @code (wxChar)s[n] @endcode
works both with wxWidgets 3.0 and previous library versions and so should be
used for writing code which should be compatible with both 2.8 and 3.0.
- Similarly, @code &s[n] @endcode doesn't yield a pointer to char so you may
not pass it to functions expecting @c char* or @c wchar_t*. Consider using
string iterators instead if possible or replace this expression with
@code s.c_str() + n @endcode otherwise.
- When using C++11 range-based for loop, the natural construct for iterating
over wxString @code for ( auto& ch: s ) @endcode doesn't compile because of
the unusual iterator type and @code for ( wxUniCharRef ch: s ) @endcode
needs to be used instead.
Another class of problems is related to the fact that the value returned by
@c c_str() itself is also not just a pointer to a buffer but a value of helper
class wxCStrData which is implicitly convertible to both narrow and wide
strings. Again, this mostly will be unnoticeable but can result in some
problems:
- You shouldn't pass @c c_str() result to vararg functions such as standard
@c printf(). Some compilers (notably g++) warn about this but even if they
don't, this @code printf("Hello, %s", s.c_str()) @endcode is not going to
work. It can be corrected in one of the following ways:
- Preferred: @code wxPrintf("Hello, %s", s) @endcode (notice the absence
of @c c_str(), it is not needed at all with wxWidgets functions)
- Compatible with wxWidgets 2.8: @code wxPrintf("Hello, %s", s.c_str()) @endcode
- Using an explicit conversion to narrow, multibyte, string:
@code printf("Hello, %s", (const char *)s.mb_str()) @endcode
- Using a cast to force the issue (listed only for completeness):
@code printf("Hello, %s", (const char *)s.c_str()) @endcode
- The result of @c c_str() cannot be cast to @c char* but only to @c const @c
@c char*. Of course, modifying the string via the pointer returned by this
method has never been possible but unfortunately it was occasionally useful
to use a @c const_cast here to pass the value to const-incorrect functions.
This can be done either using new wxString::char_str() (and matching
wchar_str()) method or by writing a double cast:
@code (char *)(const char *)s.c_str() @endcode
- One of the unfortunate consequences of the possibility to pass wxString to
@c wxPrintf() without using @c c_str() is that it is now impossible to pass
the elements of unnamed enumerations to @c wxPrintf() and other similar
vararg functions, i.e.
@code
enum { Red, Green, Blue };
wxPrintf("Red is %d", Red);
@endcode
doesn't compile. The easiest workaround is to give a name to the enum.
Other unexpected compilation errors may arise but they should happen even more
rarely than the above-mentioned ones and the solution should usually be quite
simple: just use the explicit methods of wxUniChar and wxCStrData classes
instead of relying on their implicit conversions if the compiler can't choose
among them.
@subsection overview_unicode_data_loss Data Loss due To Unicode Conversion Errors
wxString API provides implicit conversion of the internal Unicode string
contents to narrow, char strings. This can be very convenient and is absolutely
necessary for backwards compatibility with the existing code using wxWidgets
however it is a rather dangerous operation as it can easily give unexpected
results if the string contents isn't convertible to the current locale.
To be precise, the conversion will always succeed if the string was created
from a narrow string initially. It will also succeed if the current encoding is
UTF-8 as all Unicode strings are representable in this encoding. However
initializing the string using wxString::FromUTF8() method and then accessing it
as a char string via its wxString::c_str() method is a recipe for disaster as the
program may work perfectly well during testing on Unix systems using UTF-8 locale
but completely fail under Windows where UTF-8 locales are never used because
wxString::c_str() would return an empty string.
The simplest way to ensure that this doesn't happen is to avoid conversions to
@c char* completely by using wxString throughout your program. However if the
program never manipulates 8 bit strings internally, using @c char* pointers is
safe as well. So the existing code needs to be reviewed when upgrading to
wxWidgets 3.0 and the new code should be used with this in mind and ideally
avoiding implicit conversions to @c char*.
@subsection overview_unicode_performance Performance Implications of Using UTF-8
As mentioned above, under Unix systems wxString class can use variable-width
UTF-8 encoding for internal representation. In this case it can't guarantee
constant-time access to N-th element of the string any longer as to find the
position of this character in the string we have to examine all the preceding
ones. Usually this doesn't matter much because most algorithms used on the
strings examine them sequentially anyhow and because wxString implements a
cache for iterating over the string by index but it can have serious
consequences for algorithms using random access to string elements as they
typically acquire O(N^2) time complexity instead of O(N) where N is the length
of the string.
Even despite caching the index, indexed access should be replaced with
sequential access using string iterators. For example a typical loop:
@code
wxString s("hello");
for ( size_t i = 0; i < s.length(); i++ )
{
wchar_t ch = s[i];
// do something with it
}
@endcode
should be rewritten as
@code
wxString s("hello");
for ( wxString::const_iterator i = s.begin(); i != s.end(); ++i )
{
wchar_t ch = *i
// do something with it
}
@endcode
Another, similar, alternative is to use pointer arithmetic:
@code
wxString s("hello");
for ( const wchar_t *p = s.wc_str(); *p; p++ )
{
wchar_t ch = *i
// do something with it
}
@endcode
however this doesn't work correctly for strings with embedded @c NUL characters
and the use of iterators is generally preferred as they provide some run-time
checks (at least in debug build) unlike the raw pointers. But if you do use
them, it is better to use @c wchar_t pointers rather than @c char ones to avoid the
data loss problems due to conversion as discussed in the previous section.
@section overview_unicode_supportout Unicode and the Outside World
Even though wxWidgets always uses Unicode internally, not all the other
libraries and programs do and even those that do use Unicode may use a
different encoding of it. So you need to be able to convert the data to various
representations and the wxString methods wxString::ToAscii(), wxString::ToUTF8()
(or its synonym wxString::utf8_str()), wxString::mb_str(), wxString::c_str() and
wxString::wc_str() can be used for this.
The first of them should be only used for the string containing 7-bit ASCII characters
only, anything else will be replaced by some substitution character.
wxString::mb_str() converts the string to the encoding used by the current locale
and so can return an empty string if the string contains characters not representable in
it as explained in @ref overview_unicode_data_loss. The same applies to wxString::c_str()
if its result is used as a narrow string. Finally, wxString::ToUTF8() and wxString::wc_str()
functions never fail and always return a pointer to char string containing the
UTF-8 representation of the string or @c wchar_t string.
wxString also provides two convenience functions: wxString::From8BitData() and
wxString::To8BitData(). They can be used to create a wxString from arbitrary binary
data without supposing that it is in current locale encoding, and then get it back,
again, without any conversion or, rather, undoing the conversion used by
wxString::From8BitData(). Because of this you should only use wxString::From8BitData()
for the strings created using wxString::To8BitData(). Also notice that in spite
of the availability of these functions, wxString is not the ideal class for storing
arbitrary binary data as they can take up to 4 times more space than needed
(when using @c wchar_t internal representation on the systems where size of
wide characters is 4 bytes) and you should consider using wxMemoryBuffer
instead.
Final word of caution: most of these functions may return either directly the
pointer to internal string buffer or a temporary wxCharBuffer or wxWCharBuffer
object. Such objects are implicitly convertible to @c char and @c wchar_t pointers,
respectively, and so the result of, for example, wxString::ToUTF8() can always be
passed directly to a function taking <tt>const char*</tt>. However code such as
@code
const char *p = s.ToUTF8();
...
puts(p); // or call any other function taking const char *
@endcode
does @b not work because the temporary buffer returned by wxString::ToUTF8() is
destroyed and @c p is left pointing nowhere. To correct this you should use
@code
const wxScopedCharBuffer p(s.ToUTF8());
puts(p);
@endcode
which does work.
Similarly, wxWX2WCbuf can be used for the return type of wxString::wc_str().
But, once again, none of these cryptic types is really needed if you just pass
the return value of any of the functions mentioned in this section to another
function directly.
*/

View File

@@ -0,0 +1,30 @@
/////////////////////////////////////////////////////////////////////////////
// Name: unixprinting.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_unixprinting Printing Under Unix (GTK+)
Printing under Unix has always been a cause of problems as Unix does not
provide a standard way to display text and graphics on screen and print it to a
printer using the same application programming interface - instead, displaying
on screen is done via the X11 library while printing has to be done with using
PostScript commands. This was particularly difficult to handle for the case of
fonts with the result that only a selected number of application could offer
WYSIWYG under Unix. Equally, wxWidgets offered its own printing implementation
using PostScript which never really matched the screen display.
Since GTK+ 2.10, support for printing has been added to GTK+ itself and
beginning with wxWidgets 2.9, GTK+ printing is used by default (i.e. unless
<tt>\--without-gtkprint</tt> was explicitly used when configuring the library).
Support for GTK+ print is detected dynamically, i.e. during the run-time: if it
is found, printing will be done through GTK+, otherwise the application will
fall back to the old PostScript printing code. This allows the applications
built with wxWidgets to still work on the very old systems using GTK+ earlier
than 2.10.
*/

View File

@@ -0,0 +1,141 @@
/////////////////////////////////////////////////////////////////////////////
// Name: validator.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_validator wxValidator Overview
@tableofcontents
The aim of the validator concept is to make dialogs very much easier to write.
A validator is an object that can be plugged into a control (such as a
wxTextCtrl), and mediates between C++ data and the control, transferring the
data in either direction and validating it. It also is able to intercept events
generated by the control, providing filtering behaviour without the need to
derive a new control class.
You can use a stock validator, such as wxTextValidator (which does text control
data transfer, validation and filtering) and wxGenericValidator (which does
data transfer for a range of controls); or you can write your own.
Here is an example of wxTextValidator usage.
@code
wxTextCtrl *txt1 = new wxTextCtrl(
this, -1, "", wxDefaultPosition, wxDefaultSize, 0,
wxTextValidator(wxFILTER_ALPHA, &g_data.m_string));
@endcode
In this example, the text validator object provides the following
functionality:
@li It transfers the value of g_data.m_string (a wxString variable) to the
wxTextCtrl when the dialog is initialised.
@li It transfers the wxTextCtrl data back to this variable when the dialog is
dismissed.
@li It filters input characters so that only alphabetic characters are allowed.
The validation and filtering of input is accomplished in two ways. When a
character is input, wxTextValidator checks the character against the allowed
filter flag (@c wxFILTER_ALPHA in this case). If the character is inappropriate,
it is vetoed (does not appear) and a warning beep sounds (unless
wxValidator::SetBellOnError(false) has been called).
The second type of validation is performed when the dialog is about to be dismissed,
so if the default string contained invalid characters already, a dialog box is shown
giving the error, and the dialog is not dismissed.
Note that any wxWindow may have a validator and it will be used when
transferring data to or from the parent window.
@see wxValidator, wxTextValidator, wxGenericValidator, wxIntegerValidator,
wxFloatingPointValidator
@section overview_validator_anatomy Anatomy of a Validator
A programmer creating a new validator class should provide the following
functionality.
A validator constructor is responsible for allowing the programmer to specify
the kind of validation required, and perhaps a pointer to a C++ variable that
is used for storing the data for the control. If such a variable address is not
supplied by the user, then the validator should store the data internally.
The wxValidator::Validate member function should return @true if the data in
the control (not the C++ variable) is valid. It should also show an appropriate
message if data was not valid.
The wxValidator::TransferToWindow member function should transfer the data from
the validator or associated C++ variable to the control.
The wxValidator::TransferFromWindow member function should transfer the data
from the control to the validator or associated C++ variable.
There should be a copy constructor, and a wxValidator::Clone function which
returns a copy of the validator object. This is important because validators
are passed by reference to window constructors, and must therefore be cloned
internally.
You can optionally define event handlers for the validator, to implement
filtering. These handlers will capture events before the control itself does
(see @ref overview_events_processing).
For an example implementation, see the @c valtext.h and @c valtext.cpp files in the
wxWidgets library.
@section overview_validator_dialogs How Validators Interact with Dialogs
For validators to work correctly, validator functions must be called at the
right times during dialog initialisation and dismissal.
When a wxDialog::Show is called (for a modeless dialog) or wxDialog::ShowModal
is called (for a modal dialog), the function wxWindow::InitDialog is
automatically called. This in turn sends an initialisation event to the dialog.
The default handler for the @c wxEVT_INIT_DIALOG event is defined in the wxWindow
class to simply call the function wxWindow::TransferDataToWindow.
This function finds all the validators in the window's children and calls the
wxValidator::TransferToWindow function for each. Thus, data is transferred from C++
variables to the dialog just as the dialog is being shown.
@note If you are using a window or panel instead of a dialog, you will need to
call wxWindow::InitDialog explicitly before showing the window.
When the user clicks on a button, for example the OK button, the application
should first call wxWindow::Validate, which returns @false if any of the child
window validators failed to validate the window data. The button handler should
return immediately if validation failed. Secondly, the application should call
wxWindow::TransferDataFromWindow and return if this failed. It is then safe to
end the dialog by calling wxDialog::EndModal (if modal) or wxDialog::Show (if modeless).
In fact, wxDialog contains a default command event handler for the @c wxID_OK
button. It goes like this:
@code
void wxDialog::OnOK(wxCommandEvent& event)
{
if ( Validate() && TransferDataFromWindow() )
{
if ( IsModal() )
EndModal(wxID_OK);
else
{
SetReturnCode(wxID_OK);
this->Show(false);
}
}
}
@endcode
So if using validators and a normal OK button, you may not even need to write
any code for handling dialog dismissal.
If you load your dialog from a resource file, you will need to iterate through
the controls setting validators, since validators can't be specified in a
dialog resource.
*/

View File

@@ -0,0 +1,111 @@
/////////////////////////////////////////////////////////////////////////////
// Name: windowdeletion.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_windowdeletion Window Deletion
@tableofcontents
Window deletion can be a confusing subject, so this overview is provided to
help make it clear when and how you delete windows, or respond to user requests
to close windows.
@see wxCloseEvent, wxWindow
@section overview_windowdeletion_sequence Sequence of Events During Window Deletion
When the user clicks on the system close button or system close command, in a
frame or a dialog, wxWidgets calls wxWindow::Close. This in turn generates an
EVT_CLOSE event: see wxCloseEvent.
It is the duty of the application to define a suitable event handler, and
decide whether or not to destroy the window. If the application is for some
reason forcing the application to close (wxCloseEvent::CanVeto returns @false),
the window should always be destroyed, otherwise there is the option to ignore
the request, or maybe wait until the user has answered a question before
deciding whether it is safe to close. The handler for EVT_CLOSE should signal
to the calling code if it does not destroy the window, by calling
wxCloseEvent::Veto. Calling this provides useful information to the calling
code.
The wxCloseEvent handler should only call wxWindow::Destroy to delete the
window, and not use the @c delete operator. This is because for some window
classes, wxWidgets delays actual deletion of the window until all events have
been processed, since otherwise there is the danger that events will be sent to
a non-existent window.
As reinforced in the next section, calling Close does not guarantee that the window
will be destroyed. Call wxWindow::Destroy if you want to be
certain that the window is destroyed.
@section overview_windowdeletion_close Closing Windows
Your application can either use wxWindow::Close event just as the framework
does, or it can call wxWindow::Destroy directly. If using Close(), you can pass
a @true argument to this function to tell the event handler that we definitely
want to delete the frame and it cannot be vetoed.
The advantage of using Close instead of Destroy is that it will call any
clean-up code defined by the EVT_CLOSE handler; for example it may close a
document contained in a window after first asking the user whether the work
should be saved. Close can be vetoed by this process (return @false), whereas
Destroy definitely destroys the window.
@section overview_windowdeletion_default Default Window Close Behaviour
The default close event handler for wxDialog simulates a Cancel command,
generating a wxID_CANCEL event. Since the handler for this cancel event might
itself call Close, there is a check for infinite looping. The default handler
for wxID_CANCEL hides the dialog (if modeless) or calls EndModal(wxID_CANCEL)
(if modal). In other words, by default, the dialog @e is not destroyed (it
might have been created on the stack, so the assumption of dynamic creation
cannot be made).
The default close event handler for wxFrame destroys the frame using Destroy().
@section overview_windowdeletion_menuexit User Calls to Exit From a Menu
What should I do when the user calls up Exit from a menu? You can simply call
wxWindow::Close on the frame. This will invoke your own close event handler
which may destroy the frame.
You can do checking to see if your application can be safely exited at this
point, either from within your close event handler, or from within your exit
menu command handler. For example, you may wish to check that all files have
been saved. Give the user a chance to save and quit, to not save but quit
anyway, or to cancel the exit command altogether.
@section overview_windowdeletion_exitapp Exiting the Application Gracefully
A wxWidgets application automatically exits when the last top level window
(wxFrame or wxDialog), is destroyed. Put any application-wide cleanup code in
wxApp::OnExit (this is a virtual function, not an event handler).
@section overview_windowdeletion_deletion Automatic Deletion of Child Windows
Child windows are deleted from within the parent destructor. This includes any
children that are themselves frames or dialogs, so you may wish to close these
child frame or dialog windows explicitly from within the parent close handler.
@section overview_windowdeletion_windowkinds Other Kinds of Windows
So far we've been talking about 'managed' windows, i.e. frames and dialogs.
Windows with parents, such as controls, don't have delayed destruction and
don't usually have close event handlers, though you can implement them if you
wish. For consistency, continue to use the wxWindow::Destroy function instead
of the @c delete operator when deleting these kinds of windows explicitly.
*/

View File

@@ -0,0 +1,81 @@
/////////////////////////////////////////////////////////////////////////////
// Name: windowids.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_windowids Window IDs
@tableofcontents
When creating a new wxWindow-derived class or adding a menu item, its ID must
be specified. An ID is just a unique (at least locally, i.e. inside the same
top level window) integer allowing to find the window or menu item later and to
distinguish between events from different objects.
If applicable, stock IDs such as ::wxID_EXIT (for menu item) or ::wxID_OK (for
a button) should be used, see @ref page_stockitems for the full list of such
IDs.
If the value of an ID is not important, ::wxID_ANY should be used, telling
wxWidgets to allocate a unique ID automatically. All such
automatically-assigned IDs are negative and so won't conflict with any
user-defined IDs as long as they are positive.
If you do care about the ID value but don't want to specify it as a literal in
your code, you can use wxWindow::NewControlId() to create an ID that had never
been returned by this function before. Such IDs are also negative.
Finally, you can just define your own IDs. Typically this is done by using a
C++ enum to automatically ensure their uniqueness. If you do this, please note
that your custom IDs must be positive to avoid clashes with the automatically
assigned IDs discussed above and should @e not have values 0 or 1, that can
result in surprising behaviour under some platforms. Finally, you also need to
avoid defining IDs in the range from ::wxID_LOWEST to ::wxID_HIGHEST which is
reserved for wxWidgets-defined IDs, see ::wxStandardID for more details.
To avoid all these restrictions, it is best to avoid using hard-coded IDs at
all, they are not needed when using wxEvtHandler::Bind() for event handling
(unlike with the previously used event tables).
@see wxIdManager, wxWindow::NewControlId(), wxWindow::UnreserveControlId()
@section overview_windowids_type Data Types
A wxWindowID is just the integer type for a window ID. It should be used
almost everywhere. To help keep track of the count for the automatically
generated IDs, a new type, wxWindowIDRef exists, that can take the place of
wxWindowID where needed. When an ID is first created, it is marked as reserved.
When assigning it to a wxWindowIDRef, the usage count of the ID is increased,
or set to 1 if it is currently reserved. Assigning the same ID to several
wxWindowIDRefs will keep track of the count. As the wxWindowIDRef gets
destroyed or its value changes, it will decrease the count of the used ID. When
there are no more wxWindowIDRef types with the created ID, the ID is considered
free and can then be used again by wxWindow::NewControlId.
If a created ID is not assigned to a wxWindowIDRef, then it remains reserved
until it is unreserved manually with wxWindow::UnreserveControlId. However, if
it is assigned to a wxWindowIDRef, then it will be unreserved automatically and
will be considered free when the count is 0, and should NOT be manually
unreserved.
wxWindowIDRef can store both automatic IDs from wxWindow::NewControlId and
normal IDs. Reference counting is only done for the automatic IDs. Also,
wxWindowIDRef has conversion operators that allow it to be treated just like a
wxWindowID.
@section overview_windowids_using Using wxWindowIDRef
A wxWindowIDRef should be used in place of a wxWindowID where you want to make
sure the ID is not created again by wxWindow::NewControlId at least until the
wxWindowIDRef is destroyed, usually when the associated object is destroyed.
This is done already for windows, menu items, and tool bar items. It should
only be used in the main thread, as it is not thread safe.
*/

View File

@@ -0,0 +1,126 @@
/////////////////////////////////////////////////////////////////////////////
// Name: windowsizing.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_windowsizing Window Sizing Overview
@tableofcontents
It can sometimes be confusing to keep track of the various size-related
attributes of a wxWindow, how they relate to each other, and how they interact
with sizers. This document will attempt to clear the fog a little, and give
some simple explanations of things.
@section overview_windowsizing_glossary Glossary
@li @b "Size": this is the current size of the window and it can be explicitly
set or fetched with the wxWindow::SetSize() or wxWindow::GetSize() methods.
This size value is the size that the widget is currently using on screen and is
the way to change the size of something that is not being managed by a sizer.
@li @b "Client Size": the client size represents the widget's area inside of any
borders belonging to the widget and is the area that can be drawn upon in a
@c EVT_PAINT event. For wxFrame, the client size also excludes the frame
menu, tool and status bars, if any. If a window doesn't have any border
(and is not a wxFrame with some bars) then its client size is the same as
its size.
@li @b "Best Size": the best size of a widget depends on what kind of widget it is,
and usually also on the contents of the widget. For example a wxListBox's best
size will be calculated based on how many items it has, up to a certain limit,
or a wxButton's best size will be calculated based on its label size, but
normally won't be smaller than the platform default button size (unless a style
flag overrides that).
There is a special virtual method in the C++ window classes called
wxWindow::DoGetBestSize() that a class can override if it wants to calculate
its own best size based on its content, however notice that usually it is
more convenient to override DoGetBestClientSize(), see below.
@li @b "Best Client Size": this is simply the client size corresponding to the
best window size. When the fitting size for the given contents is computed,
it will usually be the client size and the size of the borders needs to be
added to obtain the full best size. For this reason, it's preferable to
override DoGetBestClientSize() and let DoGetBestSize() compute the full
best size.
@li @b "Minimal Size": the minimal size of a widget is a size that is normally explicitly
set by the programmer either with the wxWindow::SetMinSize() method or with the
wxWindow::SetSizeHints() method.
Most controls will also set the minimal size to the size given in the control's
constructor if a non-default value is passed.
Top-level windows such as wxFrame will not allow the user to resize the frame below
the minimal size.
@li @b "Maximum Size": just like for the minimal size, the maximum size is normally
explicitly set by the programmer with the wxWindow::SetMaxSize() method or
with wxWindow::SetSizeHints().
Top-level windows such as wxFrame will not allow the user to resize the frame above
the maximum size.
@li @b "Initial Size": the initial size of a widget is the size given to the
constructor of the widget, if any.
As mentioned above most controls will also set this size value as the control's
minimal size. If the size passed to the constructor is the default ::wxDefaultSize,
or if the size is not fully specified (such as wxSize(150,-1)) then most controls
will fill in the missing size components using the best size and will set the
initial size of the control to the resulting size.
@li @b "Virtual Size": the virtual size is the size of the potentially viewable
area of the widget.
The virtual size of a widget may be larger than its actual size and in this
case scrollbars will appear to the let the user 'explore' the full contents
of the widget.
See wxScrolled for more info.
@section overview_windowsizing_func Functions related to sizing
@li wxWindow::GetEffectiveMinSize(): returns a blending of the widget's minimal size
and best size, giving precedence to the minimal size.
For example, if a widget's min size is set to (150, -1) and the best size is
(80, 22) then the best fitting size is (150, 22). If the min size is (50, 20)
then the best fitting size is (50, 20). This method is what is called by the
sizers when determining what the requirements of each item in the sizer is,
and is used for calculating the overall minimum needs of the sizer.
@li wxWindow::SetInitialSize(): this is a little different from the typical size
setters. Rather than just setting an "initial size" attribute it actually sets
the minimal size to the value passed in, blends that value with the best size,
and then sets the size of the widget to be the result.
So you can consider this method to be a "Smart SetSize". This method is what is
called by the constructor of most controls to set the minimal size and the initial
size of the control.
@li wxWindow::Fit(): this method sets the size of a window to fit around its children.
If it has no children then nothing is done, if it does have children then the size
of the window is set to the window's best size.
@li wxSizer::Fit(): this sets the size of the window to be large enough to
accommodate the minimum size needed by the sizer, (along with a few other
constraints...). If the sizer is the one that is assigned to the window then
this should be equivalent to wxWindow::Fit().
@li wxSizer::Layout(): recalculates the minimum space needed by each item in the
sizer, and then lays out the items within the space currently allotted to the sizer.
@li wxWindow::Layout(): if the window has a sizer then it sets the space given to
the sizer to the current size of the window, which results in a call to
wxSizer::Layout(). If the window has layout constraints instead of a sizer then
the constraints algorithm is run. The @c Layout() method is what is called by
the default @c EVT_SIZE handler for container windows.
@li wxTopLevelWindow::Layout(): this overridden version does the same thing as
the base wxWindow::Layout() except, for convenience, it will also resize
the only child of the top-level window to cover its entire client area if
there is no sizer associated with the window. Note that this only happens
if there is exactly one child.
See also @ref overview_sizer
*/

View File

@@ -0,0 +1,30 @@
/////////////////////////////////////////////////////////////////////////////
// Name: windowstyles.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_windowstyles Window Styles
@tableofcontents
Window styles are used to specify alternative behaviour and appearances for
windows, when they are created. The symbols are defined in such a way that they
can be combined in a 'bit-list' using the C++ @e bitwise-or operator.
For example:
@code
wxCAPTION | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxRESIZE_BORDER
@endcode
For the window styles specific to each window class, please see the
documentation for the window.
Most windows can use the generic styles listed for wxWindow in addition to
their own styles.
*/

View File

@@ -0,0 +1,540 @@
/////////////////////////////////////////////////////////////////////////////
// Name: xrc.h
// Purpose: topic overview
// Author: wxWidgets team
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
/**
@page overview_xrc XML Based Resource System (XRC)
@tableofcontents
The XML-based resource system, known as XRC, allows user interface elements
such as dialogs, menu bars and toolbars, to be stored in text files and loaded
into the application at run-time. XRC files can also be compiled into binary
XRS files or C++ code (the former makes it possible to store all resources in a
single file and the latter is useful when you want to embed the resources into
the executable).
There are several advantages to using XRC resources:
@li Recompiling and linking an application is not necessary if the resources
change.
@li If you use a dialog designer that generates C++ code, it can be hard to
reintegrate this into existing C++ code. Separation of resources and code
is a more elegant solution.
@li You can choose between different alternative resource files at run time, if
necessary.
@li The XRC format uses sizers for flexibility, allowing dialogs to be
resizable and highly portable.
@li The XRC format is a wxWidgets standard, and can be generated or
postprocessed by any program that understands it. As it is based on the XML
standard, existing XML editors can be used for simple editing purposes.
XRC was written by Vaclav Slavik.
@see wxXmlResource, wxXmlResourceHandler, @ref overview_xrcformat
@section overview_xrc_gettingstarted Getting Started with XRC
<b> Creating an XRC file </b>
You will need to write an XRC file. Though this @e can be done by hand in a
text editor, for all but the smallest files it is advisable to use a
specialised tool. Examples of these include:
@e Non-free:
@li DialogBlocks <http://www.anthemion.co.uk/dialogblocks/>, a commercial
dialog editor.
@e Free:
@li XRCed <http://xrced.sourceforge.net/>, a wxPython-based dialog editor.
@li wxFormBuilder <http://wxformbuilder.org/>, a C++-based form designer that
can output C++, XRC or python.
@li wxCrafter (free version) <http://www.codelite.org/wxcrafter/>, a C++-based
form designer that can output C++ or XRC.
@li wxUiEditor <https://github.com/KeyWorksRW/wxUiEditor>, a C++-based
form designer that can output C++ or XRC.
There's a more complete list at <https://wiki.wxwidgets.org/Tools>
This small demonstration XRC file contains a simple dialog:
@code
<?xml version="1.0" ?>
<resource version="2.3.0.1">
<object class="wxDialog" name="SimpleDialog">
<title>Simple dialog</title>
<object class="wxBoxSizer">
<orient>wxVERTICAL</orient>
<object class="sizeritem">
<object class="wxTextCtrl" name="text"/>
<option>1</option>
<flag>wxALL|wxEXPAND</flag>
<border>10</border>
</object>
<object class="sizeritem">
<object class="wxBoxSizer">
<object class="sizeritem">
<object class="wxButton" name="clickme_btn">
<label>Click</label>
</object>
<flag>wxRIGHT</flag>
<border>10</border>
</object>
<object class="sizeritem">
<object class="wxButton" name="wxID_OK">
<label>OK</label>
</object>
<flag>wxLEFT</flag>
<border>10</border>
</object>
<orient>wxHORIZONTAL</orient>
</object>
<flag>wxALL|wxALIGN_CENTRE</flag>
<border>10</border>
</object>
</object>
</object>
</resource>
@endcode
You can keep all your XRC elements together in one file, or split them between
several.
<b> Loading XRC files </b>
Before you can use XRC in an app, it must first be loaded. This code fragment
shows how to load a single XRC file "resource.xrc" from the current working
directory, plus all the *.xrc files contained in the subdirectory "rc".
@code
#include "wx/xrc/xmlres.h"
bool MyApp::OnInit()
{
...
wxXmlResource::Get()->InitAllHandlers();
wxXmlResource::Get()->Load("resource.xrc");
wxXmlResource::Get()->LoadAllFiles("rc");
...
}
@endcode
It's normal to load any XRC files at the beginning of an app. Though it is
possible to unload a file later, it's seldom necessary.
<b> Using an XRC item </b>
The XRC file(s) are now loaded into the app's virtual filesystem. From there,
you must do another sort of load when you want to use an individual object.
Yes, it's confusingly named, but you first Load() the file, and later load each
top-level object when its needed.
This is how you would use the above simple dialog in your code.
@code
void MyClass::ShowDialog()
{
wxDialog dlg;
if (wxXmlResource::Get()->LoadDialog(&dlg, nullptr, "SimpleDialog"))
dlg.ShowModal();
}
@endcode
See how simple the code is. All the instantiation is done invisibly by the XRC
system.
Though you'll most often use wxXmlResource::LoadDialog, there are also
equivalents that load a frame, a menu etc; and the generic
wxXmlResource::LoadObject. See wxXmlResource for more details.
<b> Accessing XRC child controls </b>
The last section showed how to load top-level windows like dialogs, but what
about child windows like the wxTextCtrl named "text" that the dialog contains?
You can't 'load' an individual child control in the same way. Instead you use
the XRCCTRL macro to get a pointer to the child. To expand the previous code:
@code
void MyClass::ShowDialog()
{
wxDialog dlg;
if (!wxXmlResource::Get()->LoadDialog(&dlg, nullptr, "SimpleDialog"))
return;
wxTextCtrl* pText = XRCCTRL(dlg, "text", wxTextCtrl);
if (pText)
pText->ChangeValue("This is a simple dialog");
dlg.ShowModal();
}
@endcode
XRCCTRL takes a reference to the parent container and uses wxWindow::FindWindow
to search inside it for a wxWindow with the supplied name (here "text"). It
returns a pointer to that control, cast to the type in the third parameter; so
a similar effect could be obtained by writing:
@code
pText = (wxTextCtrl*)(dlg.FindWindowByName("text"));
@endcode
<b> XRC and IDs </b>
The ID of a control is often needed, e.g. for use in an event table
or with wxEvtHandler::Bind. It can easily be found by passing the name of the
control to the XRCID macro:
@code
void MyClass::ShowDialog()
{
wxDialog dlg;
if (!wxXmlResource::Get()->LoadDialog(&dlg, nullptr, "SimpleDialog"))
return;
XRCCTRL(dlg, "text", wxTextCtrl)->Bind(wxEVT_TEXT,
wxTextEventHandler(MyClass::OnTextEntered), this, XRCID("text"));
XRCCTRL(dlg, "clickme_btn", wxButton)->Bind(wxEVT_BUTTON,
wxCommandEventHandler(MyClass::OnClickme), this, XRCID("clickme_btn"));
dlg.ShowModal();
}
@endcode
A few points to note:
@li The value of the int returned by XRCID("foo") is guaranteed to be unique
within an app.
@li However that value isn't predictable, and you shouldn't rely on it being
consistent between runs. It certainly won't be the same in different apps.
@li @ref page_stockitems such as wxID_OK work correctly without requiring XRCID
(because, internally, XRCID("wxID_OK") is mapped to wxID_OK).
@li Both XRCID and XRCCTRL use the 'name' of the control (as in
wxWindow::GetName). This is different from the label that the user sees on
e.g. a wxButton.
<b> Subclassing in XRC </b>
You will often want to use subclassed wx controls in your code. There are three
ways to do this from XRC:
@li Very rarely you might need to
@ref overview_xrcformat_extending_custom "create your own wxXmlResourceHandler"
@li Occasionally wxXmlResource::AttachUnknownControl may be best. See
@ref overview_xrcformat_extending_unknown
@li Usually though, the simple 'subclass' keyword will suffice.
Suppose you wanted the wxTextCtrl named "text" to be created as your derived
class MyTextCtrl. The only change needed in the XRC file would be in this line:
@code
<object class="wxTextCtrl" name="text" subclass="MyTextCtrl"/>
@endcode
The only change in your code would be to use MyTextCtrl in XRCCTRL. However for
the subclass to be created successfully, it's important to ensure that it uses
wxWidget's RTTI mechanism: see @ref overview_xrcformat_extending_subclass for
the details.
@section overview_xrc_xrcsample The XRC sample
A major resource for learning how to use XRC is the @sample{xrc}. This
demonstrates all of the standard uses of XRC, and some of the less common ones.
It is strongly suggested that you run it, and look at the well-commented
source code to see how it works.
@section overview_xrc_binaryresourcefiles Binary Resource Files
To compile binary resource files, use the command-line @c wxrc utility. It
takes one or more file parameters (the input XRC files) and the following
switches and options:
@li -h (\--help): Show a help message.
@li -v (\--verbose): Show verbose logging information.
@li -c (\--cpp-code): Write C++ source rather than a XRS file.
@li -e (\--extra-cpp-code): If used together with -c, generates C++ header file
containing class definitions for the windows defined by the XRC file (see
special subsection).
@li -u (\--uncompressed): Do not compress XML files (C++ only).
@li -g (\--gettext): Output underscore-wrapped strings that poEdit or gettext
can scan. Outputs to stdout, or a file if -o is used.
@li -n (\--function) @<name@>: Specify C++ function name (use with -c).
@li -o (\--output) @<filename@>: Specify the output file, such as resource.xrs
or resource.cpp.
@li -l (\--list-of-handlers) @<filename@>: Output a list of necessary handlers
to this file.
For example:
@code
$ wxrc resource.xrc
$ wxrc resource.xrc -o resource.xrs
$ wxrc resource.xrc -v -c -o resource.cpp
@endcode
@note XRS file is essentially a renamed ZIP archive which means that you can
manipulate it with standard ZIP tools. Note that if you are using XRS files,
you have to initialize the wxFileSystem archive handler first! It is a simple
thing to do:
@code
#include <wx/filesys.h>
#include <wx/fs_arc.h>
...
wxFileSystem::AddHandler(new wxArchiveFSHandler);
@endcode
@section overview_xrc_embeddedresource Using Embedded Resources
It is sometimes useful to embed resources in the executable itself instead of
loading an external file (e.g. when your app is small and consists only of one
exe file). XRC provides means to convert resources into regular C++ file that
can be compiled and included in the executable.
Use the @c -c switch to @c wxrc utility to produce C++ file with embedded
resources. This file will contain a function called @c InitXmlResource (unless
you override this with a command line switch). Use it to load the resource:
@code
extern void InitXmlResource(); // defined in generated file
...
wxXmlResource::Get()->InitAllHandlers();
InitXmlResource();
...
@endcode
@section overview_xrc_cppheader C++ header file generation
Using the @c -e switch together with @c -c, a C++ header file is written
containing class definitions for the GUI windows defined in the XRC file. This
code generation can make it easier to use XRC and automate program development.
The classes can be used as basis for development, freeing the programmer from
dealing with most of the XRC specifics (e.g. @c XRCCTRL).
For each top level window defined in the XRC file a C++ class definition is
generated, containing as class members the named widgets of the window. A
default constructor for each class is also generated. Inside the constructor
all XRC loading is done and all class members representing widgets are
initialized.
A simple example will help understand how the scheme works. Suppose you have a
XRC file defining a top level window @c TestWnd_Base, which subclasses wxFrame
(any other class like @c wxDialog will do also), and has subwidgets wxTextCtrl A
and wxButton B.
The XRC file and corresponding class definition in the header file will be
something like:
@code
<?xml version="1.0"?>
<resource version="2.3.0.1">
<object class="wxFrame" name="TestWnd_Base">
<size>-1,-1</size>
<title>Test</title>
<object class="wxBoxSizer">
<orient>wxHORIZONTAL</orient>
<object class="sizeritem">
<object class="wxTextCtrl" name="A">
<label>Test label</label>
</object>
</object>
<object class="sizeritem">
<object class="wxButton" name="B">
<label>Test button</label>
</object>
</object>
</object>
</object>
</resource>
class TestWnd_Base : public wxFrame
{
protected:
wxTextCtrl* A;
wxButton* B;
private:
void InitWidgetsFromXRC()
{
wxXmlResource::Get()->LoadObject(this, nullptr, "TestWnd", "wxFrame");
A = XRCCTRL(*this, "A", wxTextCtrl);
B = XRCCTRL(*this, "B", wxButton);
}
public:
TestWnd::TestWnd()
{
InitWidgetsFromXRC();
}
};
@endcode
The generated window class can be used as basis for the full window class. The
class members which represent widgets may be accessed by name instead of using
@c XRCCTRL every time you wish to reference them (note that they are
@c protected class members), though you must still use @c XRCID to refer to
widget IDs in the event table.
Example:
@code
#include "resource.h"
class TestWnd : public TestWnd_Base
{
public:
TestWnd()
{
// A, B already initialised at this point
A->SetValue("Updated in TestWnd::TestWnd");
B->SetValue("Nice :)");
}
void OnBPressed(wxEvent& event)
{
Close();
}
wxDECLARE_EVENT_TABLE();
};
wxBEGIN_EVENT_TABLE(TestWnd,TestWnd_Base)
EVT_BUTTON(XRCID("B"), TestWnd::OnBPressed)
wxEND_EVENT_TABLE()
@endcode
It is also possible to access the wxSizerItem of a sizer that is part of a
resource. This can be done using @c XRCSIZERITEM as shown.
The resource file can have something like this for a sizer item.
@code
<object class="spacer" name="area">
<size>400, 300</size>
</object>
@endcode
The code can then access the sizer item by using @c XRCSIZERITEM and @c XRCID
together.
@code
wxSizerItem* item = XRCSIZERITEM(*this, "area");
@endcode
@section overview_xrc_newresourcehandlers Adding New Resource Handlers
Adding a new resource handler is pretty easy.
Typically, to add an handler for the @c MyControl class, you'll want to create
the @c xh_mycontrol.h and @c xh_mycontrol.cpp files.
The header needs to contains the @c MyControlXmlHandler class definition:
@code
class MyControlXmlHandler : public wxXmlResourceHandler
{
public:
// Constructor.
MyControlXmlHandler();
// Creates the control and returns a pointer to it.
virtual wxObject *DoCreateResource();
// Returns true if we know how to create a control for the given node.
virtual bool CanHandle(wxXmlNode *node);
// Register with wxWidgets' dynamic class subsystem.
wxDECLARE_DYNAMIC_CLASS(MyControlXmlHandler);
};
@endcode
The implementation of your custom XML handler will typically look as:
@code
// Register with wxWidgets' dynamic class subsystem.
wxIMPLEMENT_DYNAMIC_CLASS(MyControlXmlHandler, wxXmlResourceHandler);
MyControlXmlHandler::MyControlXmlHandler()
{
// this call adds support for all wxWidgets class styles
// (e.g. wxBORDER_SIMPLE, wxBORDER_SUNKEN, wxWS_EX_* etc etc)
AddWindowStyles();
// if MyControl class supports e.g. MYCONTROL_DEFAULT_STYLE
// you should use:
// XRC_ADD_STYLE(MYCONTROL_DEFAULT_STYLE);
}
wxObject *MyControlXmlHandler::DoCreateResource()
{
// the following macro will init a pointer named "control"
// with a new instance of the MyControl class, but will NOT
// Create() it!
XRC_MAKE_INSTANCE(control, MyControl)
// this is the point where you'll typically need to do the most
// important changes: here the control is created and initialized.
// You'll want to use the wxXmlResourceHandler's getters to
// do most of your work.
// If e.g. the MyControl::Create function looks like:
//
// bool MyControl::Create(wxWindow *parent, int id,
// const wxBitmap &first, const wxPoint &posFirst,
// const wxBitmap &second, const wxPoint &posSecond,
// const wxString &theTitle, const wxFont &titleFont,
// const wxPoint &pos, const wxSize &size,
// long style = MYCONTROL_DEFAULT_STYLE,
// const wxString &name = "MyControl");
//
// Then the XRC for your component should look like:
//
// <object class="MyControl" name="some_name">
// <first-bitmap>first.xpm</first-bitmap>
// <second-bitmap>text.xpm</second-bitmap>
// <first-pos>3,3</first-pos>
// <second-pos>4,4</second-pos>
// <the-title>a title</the-title>
// <title-font>
// <!-- Standard XRC tags for a font: <size>, <style>, <weight>, etc -->
// </title-font>
// <!-- XRC also accepts other usual tags for wxWindow-derived classes:
// like e.g. <name>, <style>, <size>, <position>, etc -->
// </object>
//
// And the code to read your custom tags from the XRC file is just:
control->Create(m_parentAsWindow, GetID(),
GetBitmap("first-bitmap"),
GetPosition("first-pos"),
GetBitmap("second-bitmap"),
GetPosition("second-pos"),
GetText("the-title"),
GetFont("title-font"),
GetPosition(), GetSize(), GetStyle(), GetName());
SetupWindow(control);
return control;
}
bool MyControlXmlHandler::CanHandle(wxXmlNode *node)
{
// this function tells XRC system that this handler can parse
// the <object class="MyControl"> tags
return IsOfClass(node, "MyControl");
}
@endcode
You may want to check the wxXmlResourceHandler documentation to see how many
built-in getters it contains. It's very easy to retrieve also complex
structures out of XRC files using them.
*/

File diff suppressed because it is too large Load Diff