1. wxMenu changes: wxMenuBase appears, several new functions for dynamic menu
handling as well 2. new sample: menu 3. small corrections to wxFileHistory made possible by wxMenu changes 4. ugly fix for panel loaded from resources and TABbing 5. wxDataObject &c doc updates git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4288 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1,16 +1,21 @@
|
|||||||
\section{\class{wxBitmapDataObject}}\label{wxbitmapdataobject}
|
\section{\class{wxBitmapDataObject}}\label{wxbitmapdataobject}
|
||||||
|
|
||||||
wxBitmapDataObject is a specialization of wxDataObject for bitmap data. It can be
|
wxBitmapDataObject is a specialization of wxDataObject for bitmap data. It can
|
||||||
used without change to paste data into the \helpref{wxClipboard}{wxclipboard}
|
be used without change to paste data into the
|
||||||
or a \helpref{wxDropSource}{wxdropsource}. A user may wish to derive a new class
|
\helpref{wxClipboard}{wxclipboard} or a \helpref{wxDropSource}{wxdropsource}. A
|
||||||
from this class for providing a bitmap on-demand in order to minimize memory consumption
|
user may wish to derive a new class from this class for providing a bitmap
|
||||||
when offering data in several formats, such as a bitmap and GIF.
|
on-demand in order to minimize memory consumption when offering data in several
|
||||||
|
formats, such as a bitmap and GIF.
|
||||||
|
|
||||||
In order to offer bitmap data on-demand \helpref{GetSize}{wxbitmapdataobjectgetsize}
|
\wxheading{Virtual functions to override}
|
||||||
and \helpref{WriteData}{wxbitmapdataobjectwritedata} will have to be overridden.
|
|
||||||
|
This class may be used as is, but
|
||||||
|
\helpref{GetBitmap}{wxbitmapdataobjectgetbitmap} may be overridden to increase
|
||||||
|
efficiency.
|
||||||
|
|
||||||
\wxheading{Derived from}
|
\wxheading{Derived from}
|
||||||
|
|
||||||
|
\helpref{wxDataObjectSimple}{wxdataobjectsimple}
|
||||||
\helpref{wxDataObject}{wxdataobject}
|
\helpref{wxDataObject}{wxdataobject}
|
||||||
|
|
||||||
\wxheading{Include files}
|
\wxheading{Include files}
|
||||||
@@ -19,64 +24,17 @@ and \helpref{WriteData}{wxbitmapdataobjectwritedata} will have to be overridden.
|
|||||||
|
|
||||||
\wxheading{See also}
|
\wxheading{See also}
|
||||||
|
|
||||||
|
\helpref{Clipboard and drag and drop overview}{wxclipboardonfigoverview},
|
||||||
|
\helpref{wxDataObject}{wxdataobject},
|
||||||
|
\helpref{wxDataObjectSimple}{wxdataobjectsimple},
|
||||||
|
\helpref{wxFileDataObject}{wxfiledataobject},
|
||||||
|
\helpref{wxTextDataObject}{wxtextdataobject},
|
||||||
\helpref{wxDataObject}{wxdataobject}
|
\helpref{wxDataObject}{wxdataobject}
|
||||||
|
|
||||||
\latexignore{\rtfignore{\wxheading{Members}}}
|
\func{}{wxBitmapDataObject}{\param{const wxBitmap\& }{bitmap = wxNullBitmap}}
|
||||||
|
|
||||||
\membersection{wxBitmapDataObject::wxBitmapDataObject}\label{wxbitmapdataobjectwxbitmapdataobject}
|
Constructor, optionally passing a bitmap (otherwise use
|
||||||
|
\helpref{SetBitmap}{wxbitmapdataobjectsetbitmap} later)
|
||||||
\func{}{wxBitmapDataObject}{\void}
|
|
||||||
|
|
||||||
Default constructor. Call \helpref{SetBitmap}{wxbitmapdataobjectsetbitmap} later
|
|
||||||
or override \helpref{WriteData}{wxbitmapdataobjectwritedata} and
|
|
||||||
\helpref{GetSize}{wxbitmapdataobjectgetsize} for providing data on-demand.
|
|
||||||
|
|
||||||
\func{}{wxBitmapDataObject}{\param{const wxBitmap\& }{bitmap}}
|
|
||||||
|
|
||||||
Constructor, passing a bitmap.
|
|
||||||
|
|
||||||
\membersection{wxBitmapDataObject::GetSize}\label{wxbitmapdataobjectgetsize}
|
|
||||||
|
|
||||||
\constfunc{virtual size\_t}{GetSize}{\void}
|
|
||||||
|
|
||||||
Returns the data size. By default, returns the size of the bitmap data
|
|
||||||
set in the constructor or using \helpref{SetBitmap}{wxbitmapdataobjectsetbitmap}.
|
|
||||||
This can be overridden to provide size data on-demand. Note that you'd
|
|
||||||
have to call the inherited GetSize method as this is the only way
|
|
||||||
to get to know the transfer size of the bitmap in a platform dependent
|
|
||||||
way - a bitmap has different size under GTK and Windows. In practice,
|
|
||||||
this would look like this:
|
|
||||||
|
|
||||||
\begin{verbatim}
|
|
||||||
size_t MyBitmapDataObject::GetSize()
|
|
||||||
{
|
|
||||||
// Get bitmap from global container. This container
|
|
||||||
// should be able to "produce" data in all formats
|
|
||||||
// offered by the application but store it only in
|
|
||||||
// one format to reduce memory consumption.
|
|
||||||
|
|
||||||
wxBitmap my_bitmap = my_global_container->GetBitmap();
|
|
||||||
|
|
||||||
// temporarily set bitmap
|
|
||||||
|
|
||||||
SetBitmap( my_bitmap );
|
|
||||||
|
|
||||||
size_t ret = wxBitmapDataObject::GetSize();
|
|
||||||
|
|
||||||
// unset bitmap again
|
|
||||||
|
|
||||||
SetBitmap( wxNullBitmap );
|
|
||||||
|
|
||||||
retrun ret;
|
|
||||||
}
|
|
||||||
\end{verbatim}
|
|
||||||
|
|
||||||
TODO: Offer a nicer way to do this. Maybe by providing a platform
|
|
||||||
dependent function in this class like
|
|
||||||
|
|
||||||
\begin{verbatim}
|
|
||||||
size_t GetBitmapSize( const wxBitmap &bitmap )
|
|
||||||
\end{verbatim}
|
|
||||||
|
|
||||||
\membersection{wxBitmapDataObject::GetBitmap}\label{wxbitmapdataobjectgettext}
|
\membersection{wxBitmapDataObject::GetBitmap}\label{wxbitmapdataobjectgettext}
|
||||||
|
|
||||||
@@ -91,26 +49,8 @@ the \helpref{wxClipboard}{wxclipboard}.
|
|||||||
|
|
||||||
\func{virtual void}{SetBitmap}{\param{const wxBitmap\& }{bitmap}}
|
\func{virtual void}{SetBitmap}{\param{const wxBitmap\& }{bitmap}}
|
||||||
|
|
||||||
Sets the bitmap associated with the data object. This method is called
|
Sets the bitmap associated with the data object. This method is called when the
|
||||||
internally when retrieving data from the \helpref{wxClipboard}{wxclipboard}
|
data object receives data. Usually there will be no reason to override this
|
||||||
and may be used to paste data to the clipboard directly (instead of
|
function.
|
||||||
on-demand).
|
|
||||||
|
|
||||||
\membersection{wxBitmapDataObject::WriteData}\label{wxbitmapdataobjectwritedata}
|
|
||||||
|
|
||||||
\constfunc{virtual void}{WriteData}{\param{void}{*dest} }
|
|
||||||
|
|
||||||
Write the data owned by this class to {\it dest}. By default, this
|
|
||||||
calls \helpref{WriteBitmap}{wxbitmapdataobjectwritebitmap} with the bitmap
|
|
||||||
set in the constructor or using \helpref{SetBitmap}{wxbitmapdataobjectsetbitmap}.
|
|
||||||
This can be overridden to provide bitmap data on-demand; in this case
|
|
||||||
\helpref{WriteBitmap}{wxbitmapdataobjectwritebitmap} must be called from
|
|
||||||
within th overriding WriteData() method.
|
|
||||||
|
|
||||||
\membersection{wxBitmapDataObject::WriteBitmap}\label{wxbitmapdataobjectwritebitmap}
|
|
||||||
|
|
||||||
\constfunc{void}{WriteBitmap}{\param{const wxBitmap\& }{bitmap}\param{void}{*dest} }
|
|
||||||
|
|
||||||
Writes the the bitmap {\it bitmap} to {\it dest}. This method must be called
|
|
||||||
from \helpref{WriteData}{wxbitmapdataobjectwritedata}.
|
|
||||||
|
|
||||||
|
@@ -40,6 +40,8 @@
|
|||||||
\input cursor.tex
|
\input cursor.tex
|
||||||
\input database.tex
|
\input database.tex
|
||||||
\input dataobj.tex
|
\input dataobj.tex
|
||||||
|
\input dobjcomp.tex
|
||||||
|
\input dobjsmpl.tex
|
||||||
\input datstrm.tex
|
\input datstrm.tex
|
||||||
\input date.tex
|
\input date.tex
|
||||||
\input dc.tex
|
\input dc.tex
|
||||||
|
@@ -1,38 +1,118 @@
|
|||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%% Name: dataobj.tex
|
||||||
|
%% Purpose: wxDataObject documentation
|
||||||
|
%% Author: Vadim Zeitlin
|
||||||
|
%% Modified by:
|
||||||
|
%% Created: 18.10.99
|
||||||
|
%% RCS-ID: $Id$
|
||||||
|
%% Copyright: (c) wxWindows team
|
||||||
|
%% Licence: wxWindows licence
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
\section{\class{wxDataObject}}\label{wxdataobject}
|
\section{\class{wxDataObject}}\label{wxdataobject}
|
||||||
|
|
||||||
A wxDataObject represents data that can be copied to or from the clipboard, or
|
A wxDataObject represents data that can be copied to or from the clipboard, or
|
||||||
dragged and dropped. There are two classes directly derived from wxDataObject:
|
dragged and dropped. The important thing about wxDataObject is that this is a
|
||||||
wxDataObjectSimple and wxDataObjectComposite. As you will guess, wxDataObjectSimple
|
"smart" piece of data unlike usual "dumb" data containers such as memory
|
||||||
holds data for a single format (such as HTML or text) and wxDataObjectComposite
|
buffers or files. Being "smart" here means that the data object itself should
|
||||||
can hold any number of wxDataObjectSimple classes. Please note that this is an
|
know what data formats it supports and how to render itself in each of
|
||||||
easy way to use Drag'n'Drop and the clipboard with multiple formats, but not the
|
supported formats.
|
||||||
most efficient one as each wxDataObjectSimple would contain the whole data in its
|
|
||||||
respective formars. Now imagine that you want to paste 200 pages of text in your
|
|
||||||
proprietary format, as well as Word, RTF, HTML, Unicode and plain text to the
|
|
||||||
clipboard and even today's computers are in trouble. For this case, you will have
|
|
||||||
to derive from wxDataObject directly and make it enumerate its formats and provide
|
|
||||||
the data in the requested format on demand.
|
|
||||||
|
|
||||||
Note that neither the GTK data transfer mechanisms for the clipboard and Drag'n'Drop
|
A supported format, incidentally, is exactly the format in which the data can
|
||||||
nor the OLE data transfer copies any data until another application actually
|
be requested from a data object or from which the data object may be set. In
|
||||||
requests the data. This is in contrast to the "feel" offered to the user of a
|
the general case, an object may support different formats on "input" and
|
||||||
program who would normally think that the data resides in the clipboard after
|
"output", i.e. it may be able to render itself in a given format but not be
|
||||||
having pressed "Copy" - in reality it is only declared to be available.
|
created from data on this format or vice versa. wxDataObject defines an
|
||||||
|
enumeration type
|
||||||
|
|
||||||
There are several predefined data object classes derived from wxDataObjectSimple:
|
\begin{verbatim}
|
||||||
\helpref{wxFileDataObject}{wxfiledataobject}, \helpref{wxTextDataObject}{wxtextdataobject}
|
enum Direction
|
||||||
and \helpref{wxBitmapDataObject}{wxbitmapdataobject} which can be used without change.
|
{
|
||||||
|
Get = 0x01, // format is supported by GetDataHere()
|
||||||
|
Set = 0x02 // format is supported by SetData()
|
||||||
|
};
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
You may also derive your own data object classes from \helpref{wxCustomDataObject}{wxprivatedataobject}
|
which allows to distinguish between them. See
|
||||||
for user-defined types. The format of user-defined data is given as mime-type string literal,
|
\helpref{wxDataFormat}{wxdataformat} documentation for more about formats.
|
||||||
such as "application/word" or "image/png". These strings are used as they are under Unix (so
|
|
||||||
far only GTK) to identify a format and are translated into their Windows equivalent under
|
Not surprizingly, being "smart" comes at a price of added complexity. This is
|
||||||
Win32 (using the OLE IDataObject for data exchange to and from the clipboard and for Drag'n'Drop).
|
reasonable for the situations when you really need to support multiple formats,
|
||||||
Note that the format string translation under Windows is not yet finnished.
|
but may be annoying if you only want to do something simple like cut and paste
|
||||||
|
text.
|
||||||
|
|
||||||
|
To provide a solution for both cases, wxWindows has two predefined classes
|
||||||
|
which derive from wxDataObject:
|
||||||
|
\helpref{wxDataObjectSimple}{wxdataobjectsimple} and
|
||||||
|
\helpref{wxDataObjectComposite}{wxdataobjectcomposite}.
|
||||||
|
\helpref{wxDataObjectSimple}{wxdataobjectsimple} is
|
||||||
|
the simplest wxDataObject possible and only holds data in a single format (such
|
||||||
|
as HTML or text) and \helpref{wxDataObjectComposite}{wxdataobjectcomposite} is
|
||||||
|
the simplest way to implement wxDataObject which does support multiple formats
|
||||||
|
because it achievs this by simply holding several wxDataObjectSimple objects.
|
||||||
|
|
||||||
|
So, you have several solutions when you need a wxDataObject class (and you need
|
||||||
|
one as soon as you want to transfer data via the clipboard or drag and drop):
|
||||||
|
|
||||||
|
\begin{twocollist}
|
||||||
|
\twocolitem{0. Use one of built-in classes}{You may use wxTextDataObject,
|
||||||
|
wxBitmapDataObject or wxFileDataObject in the simplest cases when you only need
|
||||||
|
to support one format and your data is either text, bitmap or list of files}
|
||||||
|
\twocolitem{1. Derive your class from wxDataObjectSimple}{This is the simplest
|
||||||
|
solution for custom data - you will only support one format and so probably
|
||||||
|
won't be able to communicate with other programs, but data transfer will work
|
||||||
|
in your program (or between different copies of it).}
|
||||||
|
\twocolitem{2. Use wxDataObjectComposite}{This is a quite simple, but rather
|
||||||
|
powerful solution which allows you to support any number of formats (either
|
||||||
|
standard or custom if you combine it with the previous solution).}
|
||||||
|
\twocolitem{3. Derive from wxDataObject directly}{This is the solution of
|
||||||
|
maximal flexibility and efficiency, but it also is the most difficult to
|
||||||
|
implement.}
|
||||||
|
\end{twocollist}
|
||||||
|
|
||||||
|
Please note that the easiest way to use Drag'n'Drop and the clipboard with
|
||||||
|
multiple formats is by using wxDataObjectComposite, but it is not the most
|
||||||
|
efficient one as each wxDataObjectSimple would contain the whole data in its
|
||||||
|
respective formars. Now imagine that you want to paste 200 pages of text in
|
||||||
|
your proprietary format, as well as Word, RTF, HTML, Unicode and plain text to
|
||||||
|
the clipboard and even today's computers are in trouble. For this case, you
|
||||||
|
will have to derive from wxDataObject directly and make it enumerate its
|
||||||
|
formats and provide the data in the requested format on demand.
|
||||||
|
|
||||||
|
Note that neither the GTK data transfer mechanisms for the clipboard and
|
||||||
|
Drag'n'Drop nor the OLE data transfer copies any data until another application
|
||||||
|
actually requests the data. This is in contrast to the "feel" offered to the
|
||||||
|
user of a program who would normally think that the data resides in the
|
||||||
|
clipboard after having pressed "Copy" - in reality it is only declared to be
|
||||||
|
available.
|
||||||
|
|
||||||
|
There are several predefined data object classes derived from
|
||||||
|
wxDataObjectSimple: \helpref{wxFileDataObject}{wxfiledataobject},
|
||||||
|
\helpref{wxTextDataObject}{wxtextdataobject} and
|
||||||
|
\helpref{wxBitmapDataObject}{wxbitmapdataobject} which can be used without
|
||||||
|
change.
|
||||||
|
|
||||||
|
You may also derive your own data object classes from
|
||||||
|
\helpref{wxCustomDataObject}{wxprivatedataobject} for user-defined types. The
|
||||||
|
format of user-defined data is given as mime-type string literal, such as
|
||||||
|
"application/word" or "image/png". These strings are used as they are under
|
||||||
|
Unix (so far only GTK) to identify a format and are translated into their
|
||||||
|
Windows equivalent under Win32 (using the OLE IDataObject for data exchange to
|
||||||
|
and from the clipboard and for Drag'n'Drop). Note that the format string
|
||||||
|
translation under Windows is not yet finnished.
|
||||||
|
|
||||||
|
\wxheading{Virtual functions to override}
|
||||||
|
|
||||||
|
Each class derived directly from wxDataObject must override and implement all
|
||||||
|
of its functions which are pure virtual in the base class.
|
||||||
|
|
||||||
|
The data objects which only render their data or only set it (i.e. work in
|
||||||
|
only one direction), should return 0 from
|
||||||
|
\helpref{GetFormatCount}{wxdataobjectgetformatcount}.
|
||||||
|
|
||||||
\wxheading{Derived from}
|
\wxheading{Derived from}
|
||||||
|
|
||||||
\helpref{wxObject}{wxobject}
|
None
|
||||||
|
|
||||||
\wxheading{Include files}
|
\wxheading{Include files}
|
||||||
|
|
||||||
@@ -40,13 +120,16 @@ Note that the format string translation under Windows is not yet finnished.
|
|||||||
|
|
||||||
\wxheading{See also}
|
\wxheading{See also}
|
||||||
|
|
||||||
|
\helpref{Clipboard and drag and drop overview}{wxclipboardonfigoverview},
|
||||||
|
\helpref{DnD sample}{samplednd},
|
||||||
\helpref{wxFileDataObject}{wxfiledataobject},
|
\helpref{wxFileDataObject}{wxfiledataobject},
|
||||||
\helpref{wxTextDataObject}{wxtextdataobject},
|
\helpref{wxTextDataObject}{wxtextdataobject},
|
||||||
\helpref{wxBitmapDataObject}{wxbitmapdataobject},
|
\helpref{wxBitmapDataObject}{wxbitmapdataobject},
|
||||||
\helpref{wxPrivateDataObject}{wxprivatedataobject},
|
\helpref{wxPrivateDataObject}{wxprivatedataobject},
|
||||||
\helpref{Drag and drop overview}{wxdndoverview}, \helpref{wxDropTarget}{wxdroptarget},
|
\helpref{wxDropTarget}{wxdroptarget},
|
||||||
\helpref{wxDropSource}{wxdropsource},
|
\helpref{wxDropSource}{wxdropsource},
|
||||||
\helpref{wxTextDropTarget}{wxtextdroptarget}, \helpref{wxFileDropTarget}{wxfiledroptarget}
|
\helpref{wxTextDropTarget}{wxtextdroptarget},
|
||||||
|
\helpref{wxFileDropTarget}{wxfiledroptarget}
|
||||||
|
|
||||||
\latexignore{\rtfignore{\wxheading{Members}}}
|
\latexignore{\rtfignore{\wxheading{Members}}}
|
||||||
|
|
||||||
@@ -62,17 +145,21 @@ Constructor.
|
|||||||
|
|
||||||
Destructor.
|
Destructor.
|
||||||
|
|
||||||
\membersection{wxDataObject::GetFormatCount}\label{wxdataobjectgetformatcount}
|
\membersection{wxDataObject::GetAllFormats}\label{wxdataobjectgetallformats}
|
||||||
|
|
||||||
\constfunc{virtual size_t}{GetFormatCount}{\void}
|
\constfunc{virtual void}{GetAllFormats}{
|
||||||
|
\param{wxDataFormat *}{formats},
|
||||||
|
\param{Direction}{ dir = Get}}
|
||||||
|
|
||||||
Return the number of available formats.
|
Copy all supported formats in the given direction to the array pointed to by
|
||||||
|
{\it formats} (there is enough place for GetFormatCount(dir) formats in it).
|
||||||
|
|
||||||
\membersection{wxDataObject::GetDataHere}\label{wxdataobjectgetdatahere}
|
\membersection{wxDataObject::GetDataHere}\label{wxdataobjectgetdatahere}
|
||||||
|
|
||||||
\constfunc{virtual bool}{GetDataHere}{\param{const wxDataFormat\&}{ format}, \param{void}{*buf} }
|
\constfunc{virtual bool}{GetDataHere}{\param{const wxDataFormat\&}{ format}, \param{void }{*buf} }
|
||||||
|
|
||||||
The method will write the data of the format {\it format} in the buffer {\it buf}.
|
The method will write the data of the format {\it format} in the buffer {\it
|
||||||
|
buf} and return TRUE on success, FALSE on failure.
|
||||||
|
|
||||||
\membersection{wxDataObject::GetDataSize}\label{wxdataobjectgetdatasize}
|
\membersection{wxDataObject::GetDataSize}\label{wxdataobjectgetdatasize}
|
||||||
|
|
||||||
@@ -80,16 +167,30 @@ The method will write the data of the format {\it format} in the buffer {\it buf
|
|||||||
|
|
||||||
Returns the data size of the given format {\it format}.
|
Returns the data size of the given format {\it format}.
|
||||||
|
|
||||||
|
\membersection{wxDataObject::GetFormatCount}\label{wxdataobjectgetformatcount}
|
||||||
|
|
||||||
|
\constfunc{virtual size\_t}{GetFormatCount}{\param{Direction}{ dir = Get}}
|
||||||
|
|
||||||
|
Return the number of available formats for rendering or setting the data.
|
||||||
|
|
||||||
\membersection{wxDataObject::GetPreferredFormat}\label{wxdataobjectgetpreferredformat}
|
\membersection{wxDataObject::GetPreferredFormat}\label{wxdataobjectgetpreferredformat}
|
||||||
|
|
||||||
\constfunc{virtual wxDataFormat}{GetPreferredFormat}{\void}
|
\constfunc{virtual wxDataFormat}{GetPreferredFormat}{\param{Direction}{ dir = Get}}
|
||||||
|
|
||||||
Returns the preferred format. Usually the first format in the list of available formats.
|
Returns the preferred format for either rendering the data (if {\it dir} is
|
||||||
|
{\tt Get}, its default value) or for setting it. Usually this will be the
|
||||||
|
native format of the wxDataObject.
|
||||||
|
|
||||||
\membersection{wxDataObject::SetData}\label{wxdataobjectsetdata}
|
\membersection{wxDataObject::SetData}\label{wxdataobjectsetdata}
|
||||||
|
|
||||||
\func{virtual bool}{SetData}{\param{const wxDataFormat\&}{ format}, \param{size_t}{ len}, \param{const void}{*buf} }
|
\func{virtual bool}{SetData}{
|
||||||
|
\param{const wxDataFormat\&}{ format},
|
||||||
|
\param{size\_t}{ len},
|
||||||
|
\param{const void }{*buf} }
|
||||||
|
|
||||||
Set the data of the format {\it format} and the size {\it len} provided in the buffer {\it buf}.
|
Set the data in the format {\it format} of the length {\it len} provided in the
|
||||||
|
buffer {\it buf}.
|
||||||
|
|
||||||
|
Returns TRUE on sucess, FALSE on failure.
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,9 +1,18 @@
|
|||||||
\section{\class{wxFileDataObject}}\label{wxfiledataobject}
|
\section{\class{wxFileDataObject}}\label{wxfiledataobject}
|
||||||
|
|
||||||
wxFileDataObject is a specialization of wxDataObject for file names.
|
wxFileDataObject is a specialization of \helpref{wxDataObject}{wxdataobject}
|
||||||
|
for file names. Unlike other predefined wxDataObject derivations, it only works
|
||||||
|
in one direction - the one of setting the data, i.e. the program can only
|
||||||
|
receive files dropped on it using it and there is no way (currently) to
|
||||||
|
initiate a drag and drop file operation.
|
||||||
|
|
||||||
|
\wxheading{Virtual functions to override}
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
\wxheading{Derived from}
|
\wxheading{Derived from}
|
||||||
|
|
||||||
|
\helpref{wxDataObjectSimple}{wxdataobjectsimple}
|
||||||
\helpref{wxDataObject}{wxdataobject}
|
\helpref{wxDataObject}{wxdataobject}
|
||||||
|
|
||||||
\wxheading{Include files}
|
\wxheading{Include files}
|
||||||
@@ -12,31 +21,23 @@ wxFileDataObject is a specialization of wxDataObject for file names.
|
|||||||
|
|
||||||
\wxheading{See also}
|
\wxheading{See also}
|
||||||
|
|
||||||
|
\helpref{wxDataObject}{wxdataobject},
|
||||||
|
\helpref{wxDataObjectSimple}{wxdataobjectsimple},
|
||||||
|
\helpref{wxTextDataObject}{wxtextdataobject},
|
||||||
|
\helpref{wxBitmapDataObject}{wxbitmapdataobject}
|
||||||
\helpref{wxDataObject}{wxdataobject}
|
\helpref{wxDataObject}{wxdataobject}
|
||||||
|
|
||||||
\latexignore{\rtfignore{\wxheading{Members}}}
|
\latexignore{\rtfignore{\wxheading{Members}}}
|
||||||
|
|
||||||
\membersection{wxFileDataObject::wxFileDataObject}\label{wxfiledataobjectwxfiledataobject}
|
\membersection{wxFileDataObject}\label{wxfiledataobjectwxfiledataobject}
|
||||||
|
|
||||||
\func{}{wxFileDataObject}{\void}
|
\func{}{wxFileDataObject}{\void}
|
||||||
|
|
||||||
Constructor.
|
Constructor.
|
||||||
|
|
||||||
\membersection{wxFileDataObject::GetFormat}\label{wxfiledataobjectgetformat}
|
\membersection{wxFileDataObject::GetFilenames}\label{wxfiledataobjectgetfilenames}
|
||||||
|
|
||||||
\constfunc{virtual wxDataFormat}{GetFormat}{\void}
|
\constfunc{const wxArrayString\& }{GetFilenames}{\void}
|
||||||
|
|
||||||
Returns wxDF\_FILENAME.
|
Returns the \helpref{array}{wxarraystring} of file names.
|
||||||
|
|
||||||
\membersection{wxFileDataObject::AddFile}\label{wxfiledataobjectaddfile}
|
|
||||||
|
|
||||||
\func{virtual void}{AddFile}{\param{const wxString\& }{file}}
|
|
||||||
|
|
||||||
Adds a filename to the data object.
|
|
||||||
|
|
||||||
\membersection{wxFileDataObject::GetFiles}\label{wxfiledataobjectgetfiles}
|
|
||||||
|
|
||||||
\constfunc{virtual wxString}{GetFiles}{\void}
|
|
||||||
|
|
||||||
Returns files as a zero-separated list.
|
|
||||||
|
|
||||||
|
@@ -15,7 +15,18 @@ A static text control displays one or more lines of read-only text.
|
|||||||
|
|
||||||
\wxheading{Window styles}
|
\wxheading{Window styles}
|
||||||
|
|
||||||
There are no special styles for this control.
|
\twocolwidtha{5cm}
|
||||||
|
\begin{twocollist}\itemsep=0pt
|
||||||
|
\twocolitem{\windowstyle{wxALIGN\_LEFT}}{Align the text to the left}
|
||||||
|
\twocolitem{\windowstyle{wxALIGN\_RIGHT}}{Align the text to the right}
|
||||||
|
\twocolitem{\windowstyle{wxALIGN\_CENTRE}}{Center the text (horisontally)}
|
||||||
|
\twocolitem{\windowstyle{wxST\_NO\_AUTORESIZE}}{By default, the control will
|
||||||
|
adjust its size to exactly fit to the size of the text when
|
||||||
|
\helpref{SetLabel}{wxstatictextsetlabel} is called. If this style flag is
|
||||||
|
given, the control will not change its size (this style is especially useful
|
||||||
|
with controls which also have wxALIGN\_RIGHT or CENTER style because otherwise
|
||||||
|
they won't make sense any longer after a call to SetLabel)}
|
||||||
|
\end{twocollist}
|
||||||
|
|
||||||
See also \helpref{window styles overview}{windowstyles}.
|
See also \helpref{window styles overview}{windowstyles}.
|
||||||
|
|
||||||
@@ -75,7 +86,8 @@ Returns the contents of the control.
|
|||||||
|
|
||||||
\func{virtual void}{SetLabel}{\param{const wxString\& }{ label}}
|
\func{virtual void}{SetLabel}{\param{const wxString\& }{ label}}
|
||||||
|
|
||||||
Sets the static text label.
|
Sets the static text label and updates the controls size to exactly fit the
|
||||||
|
label unless the control has wxST\_NO\_AUTORESIZE flag.
|
||||||
|
|
||||||
\wxheading{Parameters}
|
\wxheading{Parameters}
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
%% Name: tclipbrd.tex
|
%% Name: tclipbrd.tex
|
||||||
%% Purpose: Data transfer (clipboard and drag and drop) overview
|
%% Purpose: Data transfer (clipboard and drag and drop) overview
|
||||||
%% Author: Vadim Zeitlin
|
%% Author: Vadim Zeitlin
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
%% RCS-ID: $Id$
|
%% RCS-ID: $Id$
|
||||||
%% Copyright: (c) Vadim Zeitlin
|
%% Copyright: (c) Vadim Zeitlin
|
||||||
%% Licence: wxWindows licence
|
%% Licence: wxWindows licence
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
\section{Clipboard and drag and drop overview}\label{wxclipboardonfigoverview}
|
\section{Clipboard and drag and drop overview}\label{wxclipboardonfigoverview}
|
||||||
|
|
||||||
@@ -17,23 +17,24 @@ Classes: \helpref{wxDataObject}{wxdataobject},
|
|||||||
\helpref{wxDropSource}{wxdropsource},
|
\helpref{wxDropSource}{wxdropsource},
|
||||||
\helpref{wxDropTarget}{wxdroptarget}
|
\helpref{wxDropTarget}{wxdroptarget}
|
||||||
|
|
||||||
|
See also: \helpref{DnD sample}{samplednd}
|
||||||
|
|
||||||
This overview discusses data transfer through clipboard or drag and drop. In
|
This overview discusses data transfer through clipboard or drag and drop. In
|
||||||
wxWindows, these two ways to transfer data (either between different
|
wxWindows, these two ways to transfer data (either between different
|
||||||
applications or inside one and the same) are very similar which allows to
|
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
|
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
|
words, if you implement drag and drop support for your application, you get
|
||||||
clipboard support for free and vice versa.
|
clipboard support for free and vice versa.
|
||||||
|
|
||||||
In the heart of both clipboard and drag and drop operations lies the
|
In the heart of both clipboard and drag and drop operations lies the
|
||||||
\helpref{wxDataObject}{wxdataobject} class. The objects of this class (or, to be
|
\helpref{wxDataObject}{wxdataobject} class. The objects of this class (or, to
|
||||||
precise, classes derived from it) represent the data which is being carried by
|
be precise, classes derived from it) represent the data which is being carried
|
||||||
the mouse during drag and drop operation or copied to or pasted from the
|
by the mouse during drag and drop operation or copied to or pasted from the
|
||||||
clipboard. wxDataObject is a "smart" piece of data
|
clipboard. wxDataObject is a "smart" piece of data because it knows which
|
||||||
because it knows which formats it supports (see
|
formats it supports (see GetFormatCount and GetAllFormats) and knows how to
|
||||||
GetFormatCount and GetAllFormats) and knows how to render
|
render itself in any of them (see GetDataHere). It can also receive its value
|
||||||
itself in any of them (see GetDataHere).
|
from the outside in a format it supports if it implements the SetData method.
|
||||||
It can also receive its value from the outside in a format it supports if it
|
Please see the documentation of this class for more details.
|
||||||
implements the SetData method.
|
|
||||||
|
|
||||||
Both clipboard and drag and drop operations have two sides: the source and
|
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
|
target, the data provider and the data receiver. These which may be in the same
|
||||||
@@ -44,10 +45,10 @@ should do.
|
|||||||
\subsection{The data provider (source) duties}{wxdataobjectsource}
|
\subsection{The data provider (source) duties}{wxdataobjectsource}
|
||||||
|
|
||||||
The data provider is responsible for creating a
|
The data provider is responsible for creating a
|
||||||
\helpref{wxDataObject}{wxdataobjectwxdataobject} containing the data to be
|
\helpref{wxDataObject}{wxdataobject} containing the data to be
|
||||||
transfered. Then it should either pass it to the clipboard using
|
transfered. Then it should either pass it to the clipboard using
|
||||||
\helpref{AddData}{wxclipboardadddata} or \helpref{SetData}{wxclipboardsetdata}
|
\helpref{SetData}{wxclipboardsetdata} function or to
|
||||||
functions or to \helpref{wxDropSource}{wxdropsource} and call
|
\helpref{wxDropSource}{wxdropsource} and call
|
||||||
\helpref{DoDragDrop}{wxdropsourcedodragdrop} function.
|
\helpref{DoDragDrop}{wxdropsourcedodragdrop} function.
|
||||||
|
|
||||||
The only (but important) difference is that the object for the clipboard
|
The only (but important) difference is that the object for the clipboard
|
||||||
@@ -74,9 +75,10 @@ data formats you need and pass it as argument to
|
|||||||
no data in (any of) the supported format(s) is available. If it returns {\tt
|
no data in (any of) the supported format(s) is available. If it returns {\tt
|
||||||
TRUE}, the data has been successfully transfered to wxDataObject.
|
TRUE}, the data has been successfully transfered to wxDataObject.
|
||||||
|
|
||||||
{\bf TODO} document drag and drop side when the API is finalised
|
For drag and drop case, the \helpref{wxDropTarget::OnData}{wxdroptargetondata}
|
||||||
|
virtual function will be called when a data object is dropped, from which the
|
||||||
|
data itself may be requested by calling
|
||||||
|
\helpref{wxDropTarget::GetData}{wxdroptargetwxdroptarget} method which fills
|
||||||
|
the data object.
|
||||||
|
|
||||||
|
|
||||||
% !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
||||||
% Vadim, please remember the new line at the end of each file. Please
|
|
||||||
% also remember to compile the .hlp file to check for bad references etc.,
|
|
||||||
% before checking in. I have removed references that were unresolved. - JACS
|
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
This chapter contains a selection of topic overviews.
|
This chapter contains a selection of topic overviews.
|
||||||
|
|
||||||
|
\input tsamples.tex
|
||||||
\input tapp.tex
|
\input tapp.tex
|
||||||
\input tstring.tex
|
\input tstring.tex
|
||||||
\input tcontain.tex
|
\input tcontain.tex
|
||||||
@@ -38,7 +39,6 @@ This chapter contains a selection of topic overviews.
|
|||||||
\input tvalidat.tex
|
\input tvalidat.tex
|
||||||
\input texpr.tex
|
\input texpr.tex
|
||||||
\input tgrid.tex
|
\input tgrid.tex
|
||||||
\input tdnd.tex
|
|
||||||
\input tthreads.tex
|
\input tthreads.tex
|
||||||
\input tfile.tex
|
\input tfile.tex
|
||||||
\input ti18n.tex
|
\input ti18n.tex
|
||||||
@@ -46,3 +46,6 @@ This chapter contains a selection of topic overviews.
|
|||||||
\input tusage.tex
|
\input tusage.tex
|
||||||
\input ttips.tex
|
\input ttips.tex
|
||||||
\input fs.tex
|
\input fs.tex
|
||||||
|
|
||||||
|
% \input tdnd.tex
|
||||||
|
|
||||||
|
@@ -2,15 +2,27 @@
|
|||||||
|
|
||||||
wxTextDataObject is a specialization of wxDataObject for text data. It can be
|
wxTextDataObject is a specialization of wxDataObject for text data. It can be
|
||||||
used without change to paste data into the \helpref{wxClipboard}{wxclipboard}
|
used without change to paste data into the \helpref{wxClipboard}{wxclipboard}
|
||||||
or a \helpref{wxDropSource}{wxdropsource}. A user may wish to derive a new class
|
or a \helpref{wxDropSource}{wxdropsource}. A user may wish to derive a new
|
||||||
from this class for providing text on-demand in order to minimize memory consumption
|
class from this class for providing text on-demand in order to minimize memory
|
||||||
when offering data in several formats, such as plain text and RTF.
|
consumption when offering data in several formats, such as plain text and RTF
|
||||||
|
because by default the text is stored in a string in this class, but it might
|
||||||
|
as well be generated when requested. For this,
|
||||||
|
\helpref{GetTextLength}{wxtextdataobjectgettextlength} and
|
||||||
|
\helpref{GetText}{wxtextdataobjectgettext} will have to be overridden.
|
||||||
|
|
||||||
In order to offer text data on-demand \helpref{GetSize}{wxtextdataobjectgetsize}
|
Note that if you already have the text inside a string, you will not achieve
|
||||||
and \helpref{WriteData}{wxtextdataobjectwritedata} will have to be overridden.
|
any efficiency gain by overriding these functions because copying wxStrings is
|
||||||
|
already a very efficient operation (data is not actualyl copied because
|
||||||
|
wxStrings are reference counted).
|
||||||
|
|
||||||
|
\wxheading{Virtual functions to override}
|
||||||
|
|
||||||
|
This class may be used as is, but all of data transfer functions may be
|
||||||
|
overridden to increase efficiency.
|
||||||
|
|
||||||
\wxheading{Derived from}
|
\wxheading{Derived from}
|
||||||
|
|
||||||
|
\helpref{wxDataObjectSimple}{wxdataobjectsimple}
|
||||||
\helpref{wxDataObject}{wxdataobject}
|
\helpref{wxDataObject}{wxdataobject}
|
||||||
|
|
||||||
\wxheading{Include files}
|
\wxheading{Include files}
|
||||||
@@ -19,25 +31,24 @@ and \helpref{WriteData}{wxtextdataobjectwritedata} will have to be overridden.
|
|||||||
|
|
||||||
\wxheading{See also}
|
\wxheading{See also}
|
||||||
|
|
||||||
\helpref{wxDataObject}{wxdataobject}
|
\helpref{Clipboard and drag and drop overview}{wxclipboardonfigoverview},
|
||||||
|
\helpref{wxDataObject}{wxdataobject},
|
||||||
|
\helpref{wxDataObjectSimple}{wxdataobjectsimple},
|
||||||
|
\helpref{wxFileDataObject}{wxfiledataobject},
|
||||||
|
\helpref{wxBitmapDataObject}{wxbitmapdataobject}
|
||||||
|
|
||||||
\latexignore{\rtfignore{\wxheading{Members}}}
|
\latexignore{\rtfignore{\wxheading{Members}}}
|
||||||
|
|
||||||
\membersection{wxTextDataObject::wxTextDataObject}\label{wxtextdataobjectwxtextdataobject}
|
\membersection{wxTextDataObject::wxTextDataObject}\label{wxtextdataobjectwxtextdataobject}
|
||||||
|
|
||||||
\func{}{wxTextDataObject}{\void}
|
\func{}{wxTextDataObject}{\param{const wxString\& }{text = wxEmptyString}}
|
||||||
|
|
||||||
Default constructor. Call \helpref{SetText}{wxtextdataobjectsettext} later
|
Constructor, may be used to initialise the text (otherwise
|
||||||
or override \helpref{WriteData}{wxtextdataobjectwritedata} and
|
\helpref{SetText}{wxtextdataobjectsettext} should be used later)
|
||||||
\helpref{GetSize}{wxtextdataobjectgetsize} for providing data on-demand.
|
|
||||||
|
|
||||||
\func{}{wxTextDataObject}{\param{const wxString\& }{strText}}
|
\membersection{wxTextDataObject::GetTextLength}\label{wxtextdataobjectgettextlength}
|
||||||
|
|
||||||
Constructor, passing text.
|
\constfunc{virtual size\_t}{GetTextLength}{\void}
|
||||||
|
|
||||||
\membersection{wxTextDataObject::GetSize}\label{wxtextdataobjectgetsize}
|
|
||||||
|
|
||||||
\constfunc{virtual size\_t}{GetSize}{\void}
|
|
||||||
|
|
||||||
Returns the data size. By default, returns the size of the text data
|
Returns the data size. By default, returns the size of the text data
|
||||||
set in the constructor or using \helpref{SetText}{wxtextdataobjectsettext}.
|
set in the constructor or using \helpref{SetText}{wxtextdataobjectsettext}.
|
||||||
@@ -59,25 +70,8 @@ the \helpref{wxClipboard}{wxclipboard}.
|
|||||||
\func{virtual void}{SetText}{\param{const wxString\& }{strText}}
|
\func{virtual void}{SetText}{\param{const wxString\& }{strText}}
|
||||||
|
|
||||||
Sets the text associated with the data object. This method is called
|
Sets the text associated with the data object. This method is called
|
||||||
internally when retrieving data from the \helpref{wxClipboard}{wxclipboard}
|
when the data object receives the data and, by default, copies the text into
|
||||||
and may be used to paste data to the clipboard directly (instead of
|
the member variable. If you want to process the text on the fly you may wish to
|
||||||
on-demand).
|
override this function.
|
||||||
|
|
||||||
\membersection{wxTextDataObject::WriteData}\label{wxtextdataobjectwritedata}
|
|
||||||
|
|
||||||
\constfunc{virtual void}{WriteData}{\param{void}{*dest} }
|
|
||||||
|
|
||||||
Write the data owned by this class to {\it dest}. By default, this
|
|
||||||
calls \helpref{WriteString}{wxtextdataobjectwritestring} with the string
|
|
||||||
set in the constructor or using \helpref{SetText}{wxtextdataobjectsettext}.
|
|
||||||
This can be overridden to provide text data on-demand; in this case
|
|
||||||
\helpref{WriteString}{wxtextdataobjectwritestring} must be called from
|
|
||||||
within the overriding WriteData() method.
|
|
||||||
|
|
||||||
\membersection{wxTextDataObject::WriteString}\label{wxtextdataobjectwritestring}
|
|
||||||
|
|
||||||
\constfunc{void}{WriteString}{\param{const wxString\& }{str}\param{void}{*dest} }
|
|
||||||
|
|
||||||
Writes the the string {\it str} to {\it dest}. This method must be called
|
|
||||||
from \helpref{WriteData}{wxtextdataobjectwritedata}.
|
|
||||||
|
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
[OPTIONS]
|
[OPTIONS]
|
||||||
BMROOT=d:\wx2\wxWindows\docs\latex\wx ; Assume that bitmaps are where the source is
|
BMROOT=L:\wxWindows\docs\latex\wx ; Assume that bitmaps are where the source is
|
||||||
TITLE=wxWindows Manual
|
TITLE=wxWindows Manual
|
||||||
CONTENTS=Contents
|
CONTENTS=Contents
|
||||||
COMPRESS=HIGH
|
COMPRESS=HIGH
|
||||||
|
|
||||||
[FILES]
|
[FILES]
|
||||||
wx.rtf
|
Wx.rtf
|
||||||
|
|
||||||
[CONFIG]
|
[CONFIG]
|
||||||
CreateButton("Up", "&Up", "JumpId(`wx.hlp', `Contents')")
|
CreateButton("Up", "&Up", "JumpId(`Wx.hlp', `Contents')")
|
||||||
BrowseButtons()
|
BrowseButtons()
|
||||||
|
|
||||||
[MAP]
|
[MAP]
|
||||||
|
@@ -51,10 +51,6 @@ public:
|
|||||||
long m_style;
|
long m_style;
|
||||||
wxWindow *m_invokingWindow;
|
wxWindow *m_invokingWindow;
|
||||||
|
|
||||||
#if 0 // seems to be unused (VZ)
|
|
||||||
wxMenuList& GetMenus() { return m_menus; }
|
|
||||||
#endif // 0
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_DYNAMIC_CLASS(wxMenuBar)
|
DECLARE_DYNAMIC_CLASS(wxMenuBar)
|
||||||
};
|
};
|
||||||
@@ -63,92 +59,34 @@ private:
|
|||||||
// wxMenu
|
// wxMenu
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
class wxMenu : public wxEvtHandler
|
class wxMenu : public wxMenuBase
|
||||||
{
|
{
|
||||||
DECLARE_DYNAMIC_CLASS(wxMenu)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
wxMenu( const wxString& title, const wxFunction func)
|
// ctors & dtor
|
||||||
{
|
wxMenu(const wxString& title, long style = 0)
|
||||||
Init(title, 0, func);
|
: wxMenuBase(title, style) { Init(); }
|
||||||
}
|
|
||||||
wxMenu( long style )
|
|
||||||
{
|
|
||||||
Init( wxEmptyString, style );
|
|
||||||
}
|
|
||||||
wxMenu( const wxString& title = wxEmptyString, long style = 0 )
|
|
||||||
{
|
|
||||||
Init(title, style);
|
|
||||||
}
|
|
||||||
|
|
||||||
~wxMenu();
|
wxMenu(long style = 0) : wxMenuBase(style) { Init(); }
|
||||||
|
|
||||||
// title
|
virtual ~wxMenu();
|
||||||
void SetTitle(const wxString& label);
|
|
||||||
const wxString GetTitle() const;
|
|
||||||
|
|
||||||
// menu creation
|
// implement base class virtuals
|
||||||
void AppendSeparator();
|
virtual bool DoAppend(wxMenuItem *item);
|
||||||
void Append(int id, const wxString &item,
|
virtual bool DoInsert(size_t pos, wxMenuItem *item);
|
||||||
const wxString &helpStr = "", bool checkable = FALSE);
|
virtual wxMenuItem *DoRemove(wxMenuItem *item);
|
||||||
void Append(int id, const wxString &item,
|
|
||||||
wxMenu *subMenu, const wxString &helpStr = "" );
|
|
||||||
void Append(wxMenuItem *pItem);
|
|
||||||
void Break() { }
|
|
||||||
|
|
||||||
// delete item. don't delete the wxMenu if it's a submenu
|
// TODO: virtual void SetTitle(const wxString& title);
|
||||||
void Delete( int id );
|
|
||||||
|
|
||||||
// find item by name/id
|
|
||||||
int FindItem( const wxString itemString ) const;
|
|
||||||
wxMenuItem *FindItem( int id ) const;
|
|
||||||
|
|
||||||
// get/set item's state
|
|
||||||
void Enable( int id, bool enable );
|
|
||||||
bool IsEnabled( int id ) const;
|
|
||||||
void Check( int id, bool check );
|
|
||||||
bool IsChecked( int id ) const;
|
|
||||||
|
|
||||||
void SetLabel( int id, const wxString &label );
|
|
||||||
wxString GetLabel( int id ) const;
|
|
||||||
|
|
||||||
// helpstring
|
|
||||||
virtual void SetHelpString(int id, const wxString& helpString);
|
|
||||||
virtual wxString GetHelpString(int id) const ;
|
|
||||||
|
|
||||||
// accessors
|
|
||||||
wxList& GetItems() { return m_items; }
|
|
||||||
|
|
||||||
void SetEventHandler(wxEvtHandler *handler) { m_eventHandler = handler; }
|
|
||||||
wxEvtHandler *GetEventHandler() { return m_eventHandler; }
|
|
||||||
|
|
||||||
void SetClientData( void* clientData ) { m_clientData = clientData; }
|
|
||||||
void* GetClientData() const { return m_clientData; }
|
|
||||||
|
|
||||||
// Updates the UI for a menu and all submenus recursively.
|
|
||||||
// source is the object that has the update event handlers
|
|
||||||
// defined for it. If NULL, the menu or associated window
|
|
||||||
// will be used.
|
|
||||||
void UpdateUI(wxEvtHandler* source = (wxEvtHandler*) NULL);
|
|
||||||
|
|
||||||
wxMenuItem *FindItemForId( int id ) const { return FindItem( id ); }
|
|
||||||
|
|
||||||
wxFunction GetCallback() const { return m_callback; }
|
|
||||||
void Callback(const wxFunction func) { m_callback = func; }
|
|
||||||
wxFunction m_callback;
|
|
||||||
|
|
||||||
#ifdef WXWIN_COMPATIBILITY
|
#ifdef WXWIN_COMPATIBILITY
|
||||||
|
wxMenu(const wxString& title, const wxFunction func)
|
||||||
// compatibility: these functions are deprecated
|
: wxMenuBase(title)
|
||||||
bool Enabled(int id) const { return IsEnabled(id); }
|
{
|
||||||
bool Checked(int id) const { return IsChecked(id); }
|
Callback(func);
|
||||||
|
}
|
||||||
#endif // WXWIN_COMPATIBILITY
|
#endif // WXWIN_COMPATIBILITY
|
||||||
|
|
||||||
// implementation
|
// implementation
|
||||||
int FindMenuIdByMenuItem( GtkWidget *menuItem ) const;
|
int FindMenuIdByMenuItem( GtkWidget *menuItem ) const;
|
||||||
void SetInvokingWindow( wxWindow *win );
|
|
||||||
wxWindow *GetInvokingWindow();
|
|
||||||
|
|
||||||
// implementation GTK only
|
// implementation GTK only
|
||||||
GtkWidget *m_menu; // GtkMenu
|
GtkWidget *m_menu; // GtkMenu
|
||||||
@@ -156,21 +94,11 @@ public:
|
|||||||
GtkAccelGroup *m_accel;
|
GtkAccelGroup *m_accel;
|
||||||
GtkItemFactory *m_factory;
|
GtkItemFactory *m_factory;
|
||||||
|
|
||||||
// used by wxMenuBar
|
|
||||||
long GetStyle(void) const { return m_style; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// common code for both constructors:
|
// common code for all constructors:
|
||||||
void Init( const wxString& title,
|
void Init();
|
||||||
long style,
|
|
||||||
const wxFunction func = (wxFunction) NULL );
|
|
||||||
|
|
||||||
wxString m_title;
|
DECLARE_DYNAMIC_CLASS(wxMenu)
|
||||||
wxList m_items;
|
|
||||||
wxWindow *m_invokingWindow;
|
|
||||||
wxEvtHandler *m_eventHandler;
|
|
||||||
void *m_clientData;
|
|
||||||
long m_style;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __GTKMENUH__
|
#endif // __GTKMENUH__
|
||||||
|
@@ -31,10 +31,15 @@ public:
|
|||||||
|
|
||||||
// implement base class virtuals
|
// implement base class virtuals
|
||||||
virtual void SetText( const wxString& str );
|
virtual void SetText( const wxString& str );
|
||||||
|
virtual wxString GetLabel() const;
|
||||||
virtual void Enable( bool enable = TRUE );
|
virtual void Enable( bool enable = TRUE );
|
||||||
virtual void Check( bool check = TRUE );
|
virtual void Check( bool check = TRUE );
|
||||||
virtual bool IsChecked() const;
|
virtual bool IsChecked() const;
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
virtual wxAcceleratorEntry *GetAccel() const;
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
// implementation
|
// implementation
|
||||||
void SetMenuItem(GtkWidget *menuItem) { m_menuItem = menuItem; }
|
void SetMenuItem(GtkWidget *menuItem) { m_menuItem = menuItem; }
|
||||||
GtkWidget *GetMenuItem() const { return m_menuItem; }
|
GtkWidget *GetMenuItem() const { return m_menuItem; }
|
||||||
|
@@ -51,10 +51,6 @@ public:
|
|||||||
long m_style;
|
long m_style;
|
||||||
wxWindow *m_invokingWindow;
|
wxWindow *m_invokingWindow;
|
||||||
|
|
||||||
#if 0 // seems to be unused (VZ)
|
|
||||||
wxMenuList& GetMenus() { return m_menus; }
|
|
||||||
#endif // 0
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_DYNAMIC_CLASS(wxMenuBar)
|
DECLARE_DYNAMIC_CLASS(wxMenuBar)
|
||||||
};
|
};
|
||||||
@@ -63,92 +59,34 @@ private:
|
|||||||
// wxMenu
|
// wxMenu
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
class wxMenu : public wxEvtHandler
|
class wxMenu : public wxMenuBase
|
||||||
{
|
{
|
||||||
DECLARE_DYNAMIC_CLASS(wxMenu)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
wxMenu( const wxString& title, const wxFunction func)
|
// ctors & dtor
|
||||||
{
|
wxMenu(const wxString& title, long style = 0)
|
||||||
Init(title, 0, func);
|
: wxMenuBase(title, style) { Init(); }
|
||||||
}
|
|
||||||
wxMenu( long style )
|
|
||||||
{
|
|
||||||
Init( wxEmptyString, style );
|
|
||||||
}
|
|
||||||
wxMenu( const wxString& title = wxEmptyString, long style = 0 )
|
|
||||||
{
|
|
||||||
Init(title, style);
|
|
||||||
}
|
|
||||||
|
|
||||||
~wxMenu();
|
wxMenu(long style = 0) : wxMenuBase(style) { Init(); }
|
||||||
|
|
||||||
// title
|
virtual ~wxMenu();
|
||||||
void SetTitle(const wxString& label);
|
|
||||||
const wxString GetTitle() const;
|
|
||||||
|
|
||||||
// menu creation
|
// implement base class virtuals
|
||||||
void AppendSeparator();
|
virtual bool DoAppend(wxMenuItem *item);
|
||||||
void Append(int id, const wxString &item,
|
virtual bool DoInsert(size_t pos, wxMenuItem *item);
|
||||||
const wxString &helpStr = "", bool checkable = FALSE);
|
virtual wxMenuItem *DoRemove(wxMenuItem *item);
|
||||||
void Append(int id, const wxString &item,
|
|
||||||
wxMenu *subMenu, const wxString &helpStr = "" );
|
|
||||||
void Append(wxMenuItem *pItem);
|
|
||||||
void Break() { }
|
|
||||||
|
|
||||||
// delete item. don't delete the wxMenu if it's a submenu
|
// TODO: virtual void SetTitle(const wxString& title);
|
||||||
void Delete( int id );
|
|
||||||
|
|
||||||
// find item by name/id
|
|
||||||
int FindItem( const wxString itemString ) const;
|
|
||||||
wxMenuItem *FindItem( int id ) const;
|
|
||||||
|
|
||||||
// get/set item's state
|
|
||||||
void Enable( int id, bool enable );
|
|
||||||
bool IsEnabled( int id ) const;
|
|
||||||
void Check( int id, bool check );
|
|
||||||
bool IsChecked( int id ) const;
|
|
||||||
|
|
||||||
void SetLabel( int id, const wxString &label );
|
|
||||||
wxString GetLabel( int id ) const;
|
|
||||||
|
|
||||||
// helpstring
|
|
||||||
virtual void SetHelpString(int id, const wxString& helpString);
|
|
||||||
virtual wxString GetHelpString(int id) const ;
|
|
||||||
|
|
||||||
// accessors
|
|
||||||
wxList& GetItems() { return m_items; }
|
|
||||||
|
|
||||||
void SetEventHandler(wxEvtHandler *handler) { m_eventHandler = handler; }
|
|
||||||
wxEvtHandler *GetEventHandler() { return m_eventHandler; }
|
|
||||||
|
|
||||||
void SetClientData( void* clientData ) { m_clientData = clientData; }
|
|
||||||
void* GetClientData() const { return m_clientData; }
|
|
||||||
|
|
||||||
// Updates the UI for a menu and all submenus recursively.
|
|
||||||
// source is the object that has the update event handlers
|
|
||||||
// defined for it. If NULL, the menu or associated window
|
|
||||||
// will be used.
|
|
||||||
void UpdateUI(wxEvtHandler* source = (wxEvtHandler*) NULL);
|
|
||||||
|
|
||||||
wxMenuItem *FindItemForId( int id ) const { return FindItem( id ); }
|
|
||||||
|
|
||||||
wxFunction GetCallback() const { return m_callback; }
|
|
||||||
void Callback(const wxFunction func) { m_callback = func; }
|
|
||||||
wxFunction m_callback;
|
|
||||||
|
|
||||||
#ifdef WXWIN_COMPATIBILITY
|
#ifdef WXWIN_COMPATIBILITY
|
||||||
|
wxMenu(const wxString& title, const wxFunction func)
|
||||||
// compatibility: these functions are deprecated
|
: wxMenuBase(title)
|
||||||
bool Enabled(int id) const { return IsEnabled(id); }
|
{
|
||||||
bool Checked(int id) const { return IsChecked(id); }
|
Callback(func);
|
||||||
|
}
|
||||||
#endif // WXWIN_COMPATIBILITY
|
#endif // WXWIN_COMPATIBILITY
|
||||||
|
|
||||||
// implementation
|
// implementation
|
||||||
int FindMenuIdByMenuItem( GtkWidget *menuItem ) const;
|
int FindMenuIdByMenuItem( GtkWidget *menuItem ) const;
|
||||||
void SetInvokingWindow( wxWindow *win );
|
|
||||||
wxWindow *GetInvokingWindow();
|
|
||||||
|
|
||||||
// implementation GTK only
|
// implementation GTK only
|
||||||
GtkWidget *m_menu; // GtkMenu
|
GtkWidget *m_menu; // GtkMenu
|
||||||
@@ -156,21 +94,11 @@ public:
|
|||||||
GtkAccelGroup *m_accel;
|
GtkAccelGroup *m_accel;
|
||||||
GtkItemFactory *m_factory;
|
GtkItemFactory *m_factory;
|
||||||
|
|
||||||
// used by wxMenuBar
|
|
||||||
long GetStyle(void) const { return m_style; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// common code for both constructors:
|
// common code for all constructors:
|
||||||
void Init( const wxString& title,
|
void Init();
|
||||||
long style,
|
|
||||||
const wxFunction func = (wxFunction) NULL );
|
|
||||||
|
|
||||||
wxString m_title;
|
DECLARE_DYNAMIC_CLASS(wxMenu)
|
||||||
wxList m_items;
|
|
||||||
wxWindow *m_invokingWindow;
|
|
||||||
wxEvtHandler *m_eventHandler;
|
|
||||||
void *m_clientData;
|
|
||||||
long m_style;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __GTKMENUH__
|
#endif // __GTKMENUH__
|
||||||
|
@@ -31,10 +31,15 @@ public:
|
|||||||
|
|
||||||
// implement base class virtuals
|
// implement base class virtuals
|
||||||
virtual void SetText( const wxString& str );
|
virtual void SetText( const wxString& str );
|
||||||
|
virtual wxString GetLabel() const;
|
||||||
virtual void Enable( bool enable = TRUE );
|
virtual void Enable( bool enable = TRUE );
|
||||||
virtual void Check( bool check = TRUE );
|
virtual void Check( bool check = TRUE );
|
||||||
virtual bool IsChecked() const;
|
virtual bool IsChecked() const;
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
virtual wxAcceleratorEntry *GetAccel() const;
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
// implementation
|
// implementation
|
||||||
void SetMenuItem(GtkWidget *menuItem) { m_menuItem = menuItem; }
|
void SetMenuItem(GtkWidget *menuItem) { m_menuItem = menuItem; }
|
||||||
GtkWidget *GetMenuItem() const { return m_menuItem; }
|
GtkWidget *GetMenuItem() const { return m_menuItem; }
|
||||||
|
@@ -20,20 +20,204 @@
|
|||||||
// headers
|
// headers
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "wx/list.h" // for wxMenuList
|
#include "wx/list.h" // for "template" list classes
|
||||||
#include "wx/window.h" // base class for wxMenuBar
|
#include "wx/window.h" // base class for wxMenuBar
|
||||||
|
|
||||||
|
// also include this one to ensure compatibility with old code which only
|
||||||
|
// included wx/menu.h
|
||||||
|
#include "wx/menuitem.h"
|
||||||
|
|
||||||
class WXDLLEXPORT wxMenu;
|
class WXDLLEXPORT wxMenu;
|
||||||
class WXDLLEXPORT wxMenuBar;
|
class WXDLLEXPORT wxMenuBar;
|
||||||
class WXDLLEXPORT wxMenuItem;
|
class WXDLLEXPORT wxMenuItem;
|
||||||
|
|
||||||
|
// pseudo template list classes
|
||||||
|
WX_DECLARE_LIST(wxMenu, wxMenuList);
|
||||||
|
WX_DECLARE_LIST(wxMenuItem, wxMenuItemList);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxMenu
|
// wxMenu
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// for now, it's in platform-specific file
|
class WXDLLEXPORT wxMenuBase : public wxEvtHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// create a menu
|
||||||
|
static wxMenu *New(const wxString& title = wxEmptyString, long style = 0);
|
||||||
|
|
||||||
WX_DECLARE_LIST(wxMenu, wxMenuList);
|
// ctors
|
||||||
|
wxMenuBase(const wxString& title, long style = 0) : m_title(title)
|
||||||
|
{ Init(style); }
|
||||||
|
wxMenuBase(long style = 0)
|
||||||
|
{ Init(style); }
|
||||||
|
|
||||||
|
// dtor deletes all the menu items we own
|
||||||
|
virtual ~wxMenuBase();
|
||||||
|
|
||||||
|
// menu construction
|
||||||
|
// -----------------
|
||||||
|
|
||||||
|
// append a separator to the menu
|
||||||
|
void AppendSeparator() { Append(wxID_SEPARATOR, wxEmptyString); }
|
||||||
|
|
||||||
|
// append a normal item to the menu
|
||||||
|
void Append(int id,
|
||||||
|
const wxString& text,
|
||||||
|
const wxString& help = wxEmptyString,
|
||||||
|
bool isCheckable = FALSE)
|
||||||
|
{
|
||||||
|
DoAppend(wxMenuItem::New((wxMenu *)this, id, text, help, isCheckable));
|
||||||
|
}
|
||||||
|
|
||||||
|
// append a submenu
|
||||||
|
void Append(int id,
|
||||||
|
const wxString& text,
|
||||||
|
wxMenu *submenu,
|
||||||
|
const wxString& help = wxEmptyString)
|
||||||
|
{
|
||||||
|
DoAppend(wxMenuItem::New((wxMenu *)this, id, text, help, FALSE, submenu));
|
||||||
|
}
|
||||||
|
|
||||||
|
// the most generic form of Append() - append anything
|
||||||
|
void Append(wxMenuItem *item) { DoAppend(item); }
|
||||||
|
|
||||||
|
// insert a break in the menu (only works when appending the items, not
|
||||||
|
// inserting them)
|
||||||
|
virtual void Break() { }
|
||||||
|
|
||||||
|
// insert an item before given position
|
||||||
|
bool Insert(size_t pos, wxMenuItem *item);
|
||||||
|
|
||||||
|
// detach an item from the menu, but don't delete it so that it can be
|
||||||
|
// added back later (but if it's not, the caller is responsible for
|
||||||
|
// deleting it!)
|
||||||
|
wxMenuItem *Remove(int id) { return Remove(FindChildItem(id)); }
|
||||||
|
wxMenuItem *Remove(wxMenuItem *item);
|
||||||
|
|
||||||
|
// delete an item from the menu (submenus are not destroyed by this
|
||||||
|
// function, see Destroy)
|
||||||
|
bool Delete(int id) { return Delete(FindChildItem(id)); }
|
||||||
|
bool Delete(wxMenuItem *item);
|
||||||
|
|
||||||
|
// delete the item from menu and destroy it (if it's a submenu)
|
||||||
|
bool Destroy(int id) { return Destroy(FindChildItem(id)); }
|
||||||
|
bool Destroy(wxMenuItem *item);
|
||||||
|
|
||||||
|
// menu items access
|
||||||
|
// -----------------
|
||||||
|
|
||||||
|
// get the items
|
||||||
|
size_t GetMenuItemCount() const { return m_items.GetCount(); }
|
||||||
|
|
||||||
|
const wxMenuItemList& GetMenuItems() const { return m_items; }
|
||||||
|
wxMenuItemList& GetMenuItems() { return m_items; }
|
||||||
|
|
||||||
|
// search
|
||||||
|
virtual int FindItem(const wxString& itemString) const;
|
||||||
|
wxMenuItem* FindItem(int id, wxMenu **menu = NULL) const;
|
||||||
|
|
||||||
|
// get/set items attributes
|
||||||
|
void Enable(int id, bool enable);
|
||||||
|
bool IsEnabled(int id) const;
|
||||||
|
|
||||||
|
void Check(int id, bool check);
|
||||||
|
bool IsChecked(int id) const;
|
||||||
|
|
||||||
|
void SetLabel(int id, const wxString& label);
|
||||||
|
wxString GetLabel(int id) const;
|
||||||
|
|
||||||
|
virtual void SetHelpString(int id, const wxString& helpString);
|
||||||
|
virtual wxString GetHelpString(int id) const;
|
||||||
|
|
||||||
|
// misc accessors
|
||||||
|
// --------------
|
||||||
|
|
||||||
|
// the title
|
||||||
|
virtual void SetTitle(const wxString& title) { m_title = title; }
|
||||||
|
const wxString GetTitle() const { return m_title; }
|
||||||
|
|
||||||
|
// client data
|
||||||
|
void SetClientData(void* clientData) { m_clientData = clientData; }
|
||||||
|
void* GetClientData() const { return m_clientData; }
|
||||||
|
|
||||||
|
// event handler
|
||||||
|
void SetEventHandler(wxEvtHandler *handler) { m_eventHandler = handler; }
|
||||||
|
wxEvtHandler *GetEventHandler() const { return m_eventHandler; }
|
||||||
|
|
||||||
|
// invoking window
|
||||||
|
void SetInvokingWindow(wxWindow *win) { m_invokingWindow = win; }
|
||||||
|
wxWindow *GetInvokingWindow() const { return m_invokingWindow; }
|
||||||
|
|
||||||
|
// style
|
||||||
|
long GetStyle() const { return m_style; }
|
||||||
|
|
||||||
|
// implementation helpers
|
||||||
|
// ----------------------
|
||||||
|
|
||||||
|
// Updates the UI for a menu and all submenus recursively. source is the
|
||||||
|
// object that has the update event handlers defined for it. If NULL, the
|
||||||
|
// menu or associated window will be used.
|
||||||
|
void UpdateUI(wxEvtHandler* source = (wxEvtHandler*)NULL);
|
||||||
|
|
||||||
|
// is the menu attached to a menu bar (or is it a popup one)?
|
||||||
|
bool IsAttached() const { return m_menuBar != NULL; }
|
||||||
|
|
||||||
|
// set/get the parent of this menu
|
||||||
|
void SetParent(wxMenu *parent) { m_menuParent = parent; }
|
||||||
|
wxMenu *GetParent() const { return m_menuParent; }
|
||||||
|
|
||||||
|
#if WXWIN_COMPATIBILITY
|
||||||
|
// compatibility: these functions are deprecated, use the new ones instead
|
||||||
|
bool Enabled(int id) const { return IsEnabled(id); }
|
||||||
|
bool Checked(int id) const { return IsChecked(id); }
|
||||||
|
|
||||||
|
wxMenuItem* FindItemForId(int itemId, wxMenu **itemMenu) const
|
||||||
|
{ return FindItem(itemId, itemMenu); }
|
||||||
|
|
||||||
|
wxList& GetItems() const { return (wxList &)m_items; }
|
||||||
|
|
||||||
|
// wxWin 1.6x compatible menu event handling
|
||||||
|
wxFunction GetCallback() const { return m_callback; }
|
||||||
|
void Callback(const wxFunction func) { m_callback = func; }
|
||||||
|
wxFunction m_callback;
|
||||||
|
#endif // WXWIN_COMPATIBILITY
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// virtuals to override in derived classes
|
||||||
|
// ---------------------------------------
|
||||||
|
|
||||||
|
virtual bool DoAppend(wxMenuItem *item);
|
||||||
|
virtual bool DoInsert(size_t pos, wxMenuItem *item);
|
||||||
|
|
||||||
|
virtual wxMenuItem *DoRemove(wxMenuItem *item);
|
||||||
|
virtual bool DoDelete(wxMenuItem *item);
|
||||||
|
virtual bool DoDestroy(wxMenuItem *item);
|
||||||
|
|
||||||
|
// helpers
|
||||||
|
// -------
|
||||||
|
|
||||||
|
// common part of all ctors
|
||||||
|
void Init(long style);
|
||||||
|
|
||||||
|
// unlike FindItem(), this function doesn't recurse but only looks through
|
||||||
|
// our direct children and also may return the index of the found child if
|
||||||
|
// pos != NULL
|
||||||
|
wxMenuItem *FindChildItem(int id, size_t *pos = NULL) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxMenuBar *m_menuBar; // menubar we belong to or NULL
|
||||||
|
wxMenu *m_menuParent; // parent menu or NULL
|
||||||
|
|
||||||
|
wxString m_title; // the menu title or label
|
||||||
|
wxMenuItemList m_items; // the list of menu items
|
||||||
|
|
||||||
|
wxWindow *m_invokingWindow; // for popup menus
|
||||||
|
void *m_clientData; // associated with the menu
|
||||||
|
|
||||||
|
long m_style; // combination of wxMENU_XXX flags
|
||||||
|
|
||||||
|
wxEvtHandler *m_eventHandler; // a pluggable in event handler
|
||||||
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxMenuBar
|
// wxMenuBar
|
||||||
@@ -122,7 +306,7 @@ public:
|
|||||||
|
|
||||||
// compatibility only: these functions are deprecated, use the new ones
|
// compatibility only: these functions are deprecated, use the new ones
|
||||||
// instead
|
// instead
|
||||||
#ifdef WXWIN_COMPATIBILITY
|
#if WXWIN_COMPATIBILITY
|
||||||
bool Enabled(int id) const { return IsEnabled(id); }
|
bool Enabled(int id) const { return IsEnabled(id); }
|
||||||
bool Checked(int id) const { return IsChecked(id); }
|
bool Checked(int id) const { return IsChecked(id); }
|
||||||
|
|
||||||
@@ -161,9 +345,5 @@ protected:
|
|||||||
#endif
|
#endif
|
||||||
#endif // wxUSE_BASE_CLASSES_ONLY/!wxUSE_BASE_CLASSES_ONLY
|
#endif // wxUSE_BASE_CLASSES_ONLY/!wxUSE_BASE_CLASSES_ONLY
|
||||||
|
|
||||||
// also include this one to ensure compatibility with old code which only
|
|
||||||
// included wx/menu.h
|
|
||||||
#include "wx/menuitem.h"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// _WX_MENU_H_BASE_
|
// _WX_MENU_H_BASE_
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
// forward declarations
|
// forward declarations
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class WXDLLEXPORT wxAcceleratorEntry;
|
||||||
class WXDLLEXPORT wxMenuItem;
|
class WXDLLEXPORT wxMenuItem;
|
||||||
class WXDLLEXPORT wxMenu;
|
class WXDLLEXPORT wxMenu;
|
||||||
|
|
||||||
@@ -52,6 +53,9 @@ public:
|
|||||||
bool isCheckable = FALSE,
|
bool isCheckable = FALSE,
|
||||||
wxMenu *subMenu = (wxMenu *)NULL);
|
wxMenu *subMenu = (wxMenu *)NULL);
|
||||||
|
|
||||||
|
// destruction: wxMenuItem will delete its submenu
|
||||||
|
virtual ~wxMenuItemBase();
|
||||||
|
|
||||||
// the menu we're in
|
// the menu we're in
|
||||||
wxMenu *GetMenu() const { return m_parentMenu; }
|
wxMenu *GetMenu() const { return m_parentMenu; }
|
||||||
|
|
||||||
@@ -60,8 +64,14 @@ public:
|
|||||||
int GetId() const { return m_id; }
|
int GetId() const { return m_id; }
|
||||||
bool IsSeparator() const { return m_id == wxID_SEPARATOR; }
|
bool IsSeparator() const { return m_id == wxID_SEPARATOR; }
|
||||||
|
|
||||||
// the item's text (or name, or label...)
|
// the item's text (or name)
|
||||||
|
//
|
||||||
|
// NB: the item's text includes the accelerators and mnemonics info (if
|
||||||
|
// any), i.e. it may contain '&' or '_' or "\t..." and thus is
|
||||||
|
// different from the item's label which only contains the text shown
|
||||||
|
// in the menu
|
||||||
virtual void SetText(const wxString& str) { m_text = str; }
|
virtual void SetText(const wxString& str) { m_text = str; }
|
||||||
|
virtual wxString GetLabel() const { return m_text; }
|
||||||
const wxString& GetText() const { return m_text; }
|
const wxString& GetText() const { return m_text; }
|
||||||
|
|
||||||
// what kind of menu item we are
|
// what kind of menu item we are
|
||||||
@@ -75,13 +85,24 @@ public:
|
|||||||
// state
|
// state
|
||||||
virtual void Enable(bool enable = TRUE) { m_isEnabled = enable; }
|
virtual void Enable(bool enable = TRUE) { m_isEnabled = enable; }
|
||||||
virtual bool IsEnabled() const { return m_isEnabled; }
|
virtual bool IsEnabled() const { return m_isEnabled; }
|
||||||
|
|
||||||
virtual void Check(bool check = TRUE) { m_isChecked = check; }
|
virtual void Check(bool check = TRUE) { m_isChecked = check; }
|
||||||
virtual bool IsChecked() const { return m_isChecked; }
|
virtual bool IsChecked() const { return m_isChecked; }
|
||||||
|
void Toggle() { Check(!m_isChecked); }
|
||||||
|
|
||||||
// help string (displayed in the status bar by default)
|
// help string (displayed in the status bar by default)
|
||||||
void SetHelp(const wxString& str) { m_help = str; }
|
void SetHelp(const wxString& str) { m_help = str; }
|
||||||
const wxString& GetHelp() const { return m_help; }
|
const wxString& GetHelp() const { return m_help; }
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
// get our accelerator or NULL (caller must delete the pointer)
|
||||||
|
virtual wxAcceleratorEntry *GetAccel() const { return NULL; }
|
||||||
|
|
||||||
|
// set the accel for this item - this may also be done indirectly with
|
||||||
|
// SetText()
|
||||||
|
virtual void SetAccel(wxAcceleratorEntry *accel);
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
// compatibility only, use new functions in the new code
|
// compatibility only, use new functions in the new code
|
||||||
void SetName(const wxString& str) { SetText(str); }
|
void SetName(const wxString& str) { SetText(str); }
|
||||||
const wxString& GetName() const { return GetText(); }
|
const wxString& GetName() const { return GetText(); }
|
||||||
|
@@ -16,179 +16,97 @@
|
|||||||
#pragma interface "menu.h"
|
#pragma interface "menu.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/defs.h"
|
|
||||||
#include "wx/event.h"
|
|
||||||
#include "wx/dynarray.h"
|
|
||||||
#include "wx/string.h"
|
|
||||||
|
|
||||||
#if wxUSE_ACCEL
|
#if wxUSE_ACCEL
|
||||||
#include "wx/accel.h"
|
#include "wx/accel.h"
|
||||||
|
#include "wx/dynarray.h"
|
||||||
|
|
||||||
|
WX_DEFINE_EXPORTED_ARRAY(wxAcceleratorEntry *, wxAcceleratorArray);
|
||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
class WXDLLEXPORT wxMenuItem;
|
|
||||||
class WXDLLEXPORT wxMenuBar;
|
|
||||||
class WXDLLEXPORT wxMenu;
|
|
||||||
class WXDLLEXPORT wxFrame;
|
class WXDLLEXPORT wxFrame;
|
||||||
|
|
||||||
WXDLLEXPORT_DATA(extern const wxChar*) wxEmptyString;
|
|
||||||
|
|
||||||
WX_DEFINE_EXPORTED_ARRAY(wxAcceleratorEntry *, wxAcceleratorArray);
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Menu
|
// Menu
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
class WXDLLEXPORT wxMenu : public wxEvtHandler
|
class WXDLLEXPORT wxMenu : public wxMenuBase
|
||||||
{
|
{
|
||||||
DECLARE_DYNAMIC_CLASS(wxMenu)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// ctors & dtor
|
// ctors & dtor
|
||||||
wxMenu(const wxString& title,
|
wxMenu(const wxString& title, long style = 0)
|
||||||
const wxFunction func)
|
: wxMenuBase(title, style) { Init(); }
|
||||||
{
|
|
||||||
Init(title, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxMenu( long WXUNUSED(style) )
|
wxMenu(long style = 0) : wxMenuBase(style) { Init(); }
|
||||||
{
|
|
||||||
Init( wxEmptyString );
|
|
||||||
}
|
|
||||||
|
|
||||||
wxMenu(const wxString& title = wxEmptyString, long WXUNUSED(style) = 0)
|
|
||||||
{
|
|
||||||
Init(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~wxMenu();
|
virtual ~wxMenu();
|
||||||
|
|
||||||
// construct menu
|
// implement base class virtuals
|
||||||
// append a separator to the menu
|
virtual bool DoAppend(wxMenuItem *item);
|
||||||
void AppendSeparator();
|
virtual bool DoInsert(size_t pos, wxMenuItem *item);
|
||||||
// append a normal item to the menu
|
virtual wxMenuItem *DoRemove(wxMenuItem *item);
|
||||||
void Append(int id, const wxString& label,
|
|
||||||
const wxString& helpString = wxEmptyString,
|
|
||||||
bool checkable = FALSE);
|
|
||||||
// append a submenu
|
|
||||||
void Append(int id, const wxString& label,
|
|
||||||
wxMenu *submenu,
|
|
||||||
const wxString& helpString = wxEmptyString);
|
|
||||||
// append anything (create wxMenuItem first)
|
|
||||||
void Append(wxMenuItem *pItem);
|
|
||||||
|
|
||||||
// insert a break in the menu
|
virtual void Break();
|
||||||
void Break();
|
|
||||||
|
|
||||||
// delete an item
|
virtual void SetTitle(const wxString& title);
|
||||||
// If it's a submenu, menu is not destroyed.
|
|
||||||
// VZ: why? shouldn't it return "wxMenu *" then?
|
|
||||||
void Delete(int id);
|
|
||||||
|
|
||||||
// client data
|
|
||||||
void SetClientData(void* clientData) { m_clientData = clientData; }
|
|
||||||
void* GetClientData() const { return m_clientData; }
|
|
||||||
|
|
||||||
// menu item control
|
|
||||||
// enable/disable item
|
|
||||||
void Enable(int id, bool enable);
|
|
||||||
// TRUE if enabled
|
|
||||||
bool IsEnabled(int id) const;
|
|
||||||
|
|
||||||
// check/uncheck item - only for checkable items, of course
|
|
||||||
void Check(int id, bool check);
|
|
||||||
// TRUE if checked
|
|
||||||
bool IsChecked(int id) const;
|
|
||||||
|
|
||||||
// other properties
|
|
||||||
// the menu title
|
|
||||||
void SetTitle(const wxString& label);
|
|
||||||
const wxString GetTitle() const;
|
|
||||||
// the item label
|
|
||||||
void SetLabel(int id, const wxString& label);
|
|
||||||
wxString GetLabel(int id) const;
|
|
||||||
// help string
|
|
||||||
virtual void SetHelpString(int id, const wxString& helpString);
|
|
||||||
virtual wxString GetHelpString(int id) const;
|
|
||||||
|
|
||||||
// get the list of items
|
|
||||||
wxList& GetItems() const { return (wxList &)m_menuItems; }
|
|
||||||
|
|
||||||
// find item
|
|
||||||
// returns id of the item matching the given string or wxNOT_FOUND
|
|
||||||
virtual int FindItem(const wxString& itemString) const;
|
|
||||||
// returns NULL if not found
|
|
||||||
wxMenuItem* FindItem(int id) const { return FindItemForId(id); }
|
|
||||||
// find wxMenuItem by ID, and item's menu too if itemMenu is !NULL
|
|
||||||
wxMenuItem *FindItemForId(int itemId, wxMenu **itemMenu = NULL) const;
|
|
||||||
|
|
||||||
// Updates the UI for a menu and all submenus recursively. source is the
|
|
||||||
// object that has the update event handlers defined for it. If NULL, the
|
|
||||||
// menu or associated window will be used.
|
|
||||||
void UpdateUI(wxEvtHandler* source = (wxEvtHandler*)NULL);
|
|
||||||
|
|
||||||
|
// MSW-specific
|
||||||
bool ProcessCommand(wxCommandEvent& event);
|
bool ProcessCommand(wxCommandEvent& event);
|
||||||
|
|
||||||
void SetEventHandler(wxEvtHandler *handler) { m_eventHandler = handler; }
|
#ifdef WXWIN_COMPATIBILITY
|
||||||
wxEvtHandler *GetEventHandler() const { return m_eventHandler; }
|
wxMenu(const wxString& title, const wxFunction func)
|
||||||
|
: wxMenuBase(title)
|
||||||
|
{
|
||||||
|
Callback(func);
|
||||||
|
}
|
||||||
|
#endif // WXWIN_COMPATIBILITY
|
||||||
|
|
||||||
|
// implementation only from now on
|
||||||
|
// -------------------------------
|
||||||
|
|
||||||
// IMPLEMENTATION
|
|
||||||
bool MSWCommand(WXUINT param, WXWORD id);
|
bool MSWCommand(WXUINT param, WXWORD id);
|
||||||
|
|
||||||
void SetInvokingWindow(wxWindow *pWin) { m_pInvokingWindow = pWin; }
|
|
||||||
wxWindow *GetInvokingWindow() const { return m_pInvokingWindow; }
|
|
||||||
|
|
||||||
// semi-private accessors
|
// semi-private accessors
|
||||||
// get the window which contains this menu
|
// get the window which contains this menu
|
||||||
wxWindow *GetWindow() const;
|
wxWindow *GetWindow() const;
|
||||||
// get the menu handle
|
// get the menu handle
|
||||||
WXHMENU GetHMenu() const;
|
WXHMENU GetHMenu() const { return m_hMenu; }
|
||||||
|
|
||||||
// only for wxMenuBar
|
// attach/detach menu to/from wxMenuBar
|
||||||
void Attach(wxMenuBar *menubar);
|
void Attach(wxMenuBar *menubar);
|
||||||
void Detach();
|
void Detach();
|
||||||
|
|
||||||
#if wxUSE_ACCEL
|
#if wxUSE_ACCEL
|
||||||
|
// called by wxMenuBar to build its accel table from the accels of all menus
|
||||||
|
bool HasAccels() const { return !m_accels.IsEmpty(); }
|
||||||
size_t GetAccelCount() const { return m_accels.GetCount(); }
|
size_t GetAccelCount() const { return m_accels.GetCount(); }
|
||||||
size_t CopyAccels(wxAcceleratorEntry *accels) const;
|
size_t CopyAccels(wxAcceleratorEntry *accels) const;
|
||||||
|
|
||||||
|
// called by wxMenuItem when its accels changes
|
||||||
|
void UpdateAccel(wxMenuItem *item);
|
||||||
|
|
||||||
|
// helper used by wxMenu itself (returns the index in m_accels)
|
||||||
|
int FindAccel(int id) const;
|
||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
wxFunction GetCallback() const { return m_callback; }
|
|
||||||
void Callback(const wxFunction func) { m_callback = func; }
|
|
||||||
wxFunction m_callback;
|
|
||||||
|
|
||||||
#ifdef WXWIN_COMPATIBILITY
|
|
||||||
// compatibility: these functions are deprecated
|
|
||||||
bool Enabled(int id) const { return IsEnabled(id); }
|
|
||||||
bool Checked(int id) const { return IsChecked(id); }
|
|
||||||
|
|
||||||
#endif // WXWIN_COMPATIBILITY
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// common part of all ctors
|
// common part of all ctors
|
||||||
void Init(const wxString& title, const wxFunction func = NULL );
|
void Init();
|
||||||
|
|
||||||
|
// common part of Append/Insert (behaves as Append is pos == (size_t)-1)
|
||||||
|
bool DoInsertOrAppend(wxMenuItem *item, size_t pos = (size_t)-1);
|
||||||
|
|
||||||
|
// if TRUE, insert a breal before appending the next item
|
||||||
bool m_doBreak;
|
bool m_doBreak;
|
||||||
|
|
||||||
// This is used when m_hMenu is NULL because we don't want to
|
// the menu handle of this menu
|
||||||
// delete it in ~wxMenu (it's been added to a parent menu).
|
|
||||||
// But we'll still need the handle for other purposes.
|
|
||||||
// Might be better to have a flag saying whether it's deleteable or not.
|
|
||||||
WXHMENU m_savehMenu ; // Used for Enable() on popup
|
|
||||||
WXHMENU m_hMenu;
|
WXHMENU m_hMenu;
|
||||||
|
|
||||||
int m_noItems;
|
|
||||||
wxString m_title;
|
|
||||||
wxMenu * m_topLevelMenu;
|
|
||||||
wxMenuBar * m_menuBar;
|
|
||||||
wxList m_menuItems;
|
|
||||||
wxEvtHandler * m_eventHandler;
|
|
||||||
wxWindow *m_pInvokingWindow;
|
|
||||||
void* m_clientData;
|
|
||||||
|
|
||||||
#if wxUSE_ACCEL
|
#if wxUSE_ACCEL
|
||||||
// the accelerators for our menu items
|
// the accelerators for our menu items
|
||||||
wxAcceleratorArray m_accels;
|
wxAcceleratorArray m_accels;
|
||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_CLASS(wxMenu)
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -243,8 +161,11 @@ public:
|
|||||||
void Attach(wxFrame *frame);
|
void Attach(wxFrame *frame);
|
||||||
|
|
||||||
#if wxUSE_ACCEL
|
#if wxUSE_ACCEL
|
||||||
// get the accel table for the menus
|
// get the accel table for all the menus
|
||||||
const wxAcceleratorTable& GetAccelTable() const { return m_accelTable; }
|
const wxAcceleratorTable& GetAccelTable() const { return m_accelTable; }
|
||||||
|
|
||||||
|
// update the accel table (must be called after adding/deletign a menu)
|
||||||
|
void RebuildAccelTable();
|
||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
// get the menu handle
|
// get the menu handle
|
||||||
|
@@ -45,12 +45,17 @@ public:
|
|||||||
|
|
||||||
// override base class virtuals
|
// override base class virtuals
|
||||||
virtual void SetText(const wxString& strName);
|
virtual void SetText(const wxString& strName);
|
||||||
|
virtual wxString GetLabel() const;
|
||||||
virtual void SetCheckable(bool checkable);
|
virtual void SetCheckable(bool checkable);
|
||||||
|
|
||||||
virtual void Enable(bool bDoEnable = TRUE);
|
virtual void Enable(bool bDoEnable = TRUE);
|
||||||
virtual void Check(bool bDoCheck = TRUE);
|
virtual void Check(bool bDoCheck = TRUE);
|
||||||
virtual bool IsChecked() const;
|
virtual bool IsChecked() const;
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
virtual wxAcceleratorEntry *GetAccel() const;
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
// unfortunately needed to resolve ambiguity between
|
// unfortunately needed to resolve ambiguity between
|
||||||
// wxMenuItemBase::IsCheckable() and wxOwnerDrawn::IsCheckable()
|
// wxMenuItemBase::IsCheckable() and wxOwnerDrawn::IsCheckable()
|
||||||
bool IsCheckable() const { return wxMenuItemBase::IsCheckable(); }
|
bool IsCheckable() const { return wxMenuItemBase::IsCheckable(); }
|
||||||
@@ -60,9 +65,6 @@ public:
|
|||||||
// menu handle depending on what we're
|
// menu handle depending on what we're
|
||||||
int GetRealId() const;
|
int GetRealId() const;
|
||||||
|
|
||||||
// delete the submenu
|
|
||||||
void DeleteSubMenu();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_DYNAMIC_CLASS(wxMenuItem)
|
DECLARE_DYNAMIC_CLASS(wxMenuItem)
|
||||||
};
|
};
|
||||||
|
@@ -400,6 +400,8 @@ void MyFrame::OnSize(wxSizeEvent& event)
|
|||||||
wxSize size = event.GetSize();
|
wxSize size = event.GetSize();
|
||||||
|
|
||||||
Resize(size);
|
Resize(size);
|
||||||
|
|
||||||
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyFrame::Resize(const wxSize& size, const wxFont& font)
|
void MyFrame::Resize(const wxSize& size, const wxFont& font)
|
||||||
|
482
samples/menu/menu.cpp
Normal file
482
samples/menu/menu.cpp
Normal file
@@ -0,0 +1,482 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: samples/menu.cpp
|
||||||
|
// Purpose: wxMenu/wxMenuBar sample
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Modified by:
|
||||||
|
// Created: 01.11.99
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) 1999 Vadim Zeitlin
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// declarations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// headers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// For compilers that support precompilation, includes "wx/wx.h".
|
||||||
|
#include <wx/wxprec.h>
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
#include <wx/wx.h>
|
||||||
|
|
||||||
|
#include <wx/log.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// classes
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Define a new application
|
||||||
|
class MyApp: public wxApp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool OnInit();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Define a new frame
|
||||||
|
class MyFrame: public wxFrame
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MyFrame();
|
||||||
|
|
||||||
|
virtual ~MyFrame() { delete m_menu; }
|
||||||
|
|
||||||
|
void OnQuit(wxCommandEvent& event);
|
||||||
|
void OnAbout(wxCommandEvent& event);
|
||||||
|
|
||||||
|
void OnDummy(wxCommandEvent& event);
|
||||||
|
|
||||||
|
void OnAppendMenuItem(wxCommandEvent& event);
|
||||||
|
void OnAppendSubMenu(wxCommandEvent& event);
|
||||||
|
void OnDeleteMenuItem(wxCommandEvent& event);
|
||||||
|
void OnInsertMenuItem(wxCommandEvent& event);
|
||||||
|
void OnCheckMenuItem(wxCommandEvent& event);
|
||||||
|
void OnEnableMenuItem(wxCommandEvent& event);
|
||||||
|
void OnGetLabelMenuItem(wxCommandEvent& event);
|
||||||
|
void OnSetLabelMenuItem(wxCommandEvent& event);
|
||||||
|
|
||||||
|
void OnAppendMenu(wxCommandEvent& event);
|
||||||
|
void OnDeleteMenu(wxCommandEvent& event);
|
||||||
|
void OnToggleMenu(wxCommandEvent& event);
|
||||||
|
void OnEnableMenu(wxCommandEvent& event);
|
||||||
|
void OnGetLabelMenu(wxCommandEvent& event);
|
||||||
|
void OnSetLabelMenu(wxCommandEvent& event);
|
||||||
|
|
||||||
|
void OnRightDown(wxMouseEvent& event);
|
||||||
|
|
||||||
|
void OnUpdateCheckMenuItemUI(wxUpdateUIEvent& event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxMenu *CreateDummyMenu();
|
||||||
|
|
||||||
|
wxMenuItem *GetLastMenuItem() const;
|
||||||
|
|
||||||
|
wxMenu *m_menu;
|
||||||
|
|
||||||
|
DECLARE_EVENT_TABLE()
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// constants
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Menu_File_Quit = 100,
|
||||||
|
|
||||||
|
Menu_MenuBar_Toggle = 200,
|
||||||
|
Menu_MenuBar_Append,
|
||||||
|
Menu_MenuBar_Delete,
|
||||||
|
Menu_MenuBar_Enable,
|
||||||
|
Menu_MenuBar_GetLabel,
|
||||||
|
Menu_MenuBar_SetLabel,
|
||||||
|
|
||||||
|
Menu_Menu_Append = 300,
|
||||||
|
Menu_Menu_AppendSub,
|
||||||
|
Menu_Menu_Insert,
|
||||||
|
Menu_Menu_Delete,
|
||||||
|
Menu_Menu_Enable,
|
||||||
|
Menu_Menu_Check,
|
||||||
|
Menu_Menu_GetLabel,
|
||||||
|
Menu_Menu_SetLabel,
|
||||||
|
|
||||||
|
Menu_Dummy_First = 400,
|
||||||
|
Menu_Dummy_Second,
|
||||||
|
Menu_Dummy_Third,
|
||||||
|
Menu_Dummy_Fourth,
|
||||||
|
Menu_Dummy_Last,
|
||||||
|
|
||||||
|
Menu_Help_About = 1000,
|
||||||
|
|
||||||
|
Menu_Popup_ToBeDeleted = 2000,
|
||||||
|
Menu_Popup_ToBeGreyed,
|
||||||
|
Menu_Popup_ToBeChecked,
|
||||||
|
Menu_Popup_Submenu,
|
||||||
|
|
||||||
|
Menu_Max
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// event tables
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||||
|
EVT_MENU(Menu_File_Quit, MyFrame::OnQuit)
|
||||||
|
|
||||||
|
EVT_MENU(Menu_Help_About, MyFrame::OnAbout)
|
||||||
|
|
||||||
|
EVT_MENU(Menu_MenuBar_Toggle, MyFrame::OnToggleMenu)
|
||||||
|
EVT_MENU(Menu_MenuBar_Append, MyFrame::OnAppendMenu)
|
||||||
|
EVT_MENU(Menu_MenuBar_Delete, MyFrame::OnDeleteMenu)
|
||||||
|
EVT_MENU(Menu_MenuBar_Enable, MyFrame::OnEnableMenu)
|
||||||
|
EVT_MENU(Menu_MenuBar_GetLabel, MyFrame::OnGetLabelMenu)
|
||||||
|
EVT_MENU(Menu_MenuBar_SetLabel, MyFrame::OnSetLabelMenu)
|
||||||
|
|
||||||
|
EVT_MENU(Menu_Menu_Append, MyFrame::OnAppendMenuItem)
|
||||||
|
EVT_MENU(Menu_Menu_AppendSub, MyFrame::OnAppendSubMenu)
|
||||||
|
EVT_MENU(Menu_Menu_Insert, MyFrame::OnInsertMenuItem)
|
||||||
|
EVT_MENU(Menu_Menu_Delete, MyFrame::OnDeleteMenuItem)
|
||||||
|
EVT_MENU(Menu_Menu_Enable, MyFrame::OnEnableMenuItem)
|
||||||
|
EVT_MENU(Menu_Menu_Check, MyFrame::OnCheckMenuItem)
|
||||||
|
EVT_MENU(Menu_Menu_GetLabel, MyFrame::OnGetLabelMenuItem)
|
||||||
|
EVT_MENU(Menu_Menu_SetLabel, MyFrame::OnSetLabelMenuItem)
|
||||||
|
|
||||||
|
EVT_MENU_RANGE(Menu_Dummy_First, Menu_Dummy_Last, MyFrame::OnDummy)
|
||||||
|
|
||||||
|
EVT_UPDATE_UI(Menu_Menu_Check, MyFrame::OnUpdateCheckMenuItemUI)
|
||||||
|
|
||||||
|
EVT_RIGHT_DOWN(MyFrame::OnRightDown)
|
||||||
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// implementation
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// MyApp
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
IMPLEMENT_APP(MyApp)
|
||||||
|
|
||||||
|
// The `main program' equivalent, creating the windows and returning the
|
||||||
|
// main frame
|
||||||
|
bool MyApp::OnInit()
|
||||||
|
{
|
||||||
|
// Create the main frame window
|
||||||
|
MyFrame* frame = new MyFrame;
|
||||||
|
|
||||||
|
frame->Show(TRUE);
|
||||||
|
|
||||||
|
frame->SetStatusText("Hello, wxWindows");
|
||||||
|
|
||||||
|
SetTopWindow(frame);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// MyFrame
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Define my frame constructor
|
||||||
|
MyFrame::MyFrame()
|
||||||
|
: wxFrame((wxFrame *)NULL, -1, "wxWindows menu sample",
|
||||||
|
wxDefaultPosition, wxSize(300, 200))
|
||||||
|
{
|
||||||
|
m_menu = NULL;
|
||||||
|
|
||||||
|
CreateStatusBar();
|
||||||
|
|
||||||
|
// create the menubar
|
||||||
|
wxMenu *fileMenu = new wxMenu;
|
||||||
|
fileMenu->Append(Menu_File_Quit, "E&xit\tAlt-X", "Quit toolbar sample" );
|
||||||
|
|
||||||
|
wxMenu *menubarMenu = new wxMenu;
|
||||||
|
menubarMenu->Append(Menu_MenuBar_Append, "&Append menu\tCtrl-A",
|
||||||
|
"Append a menu to the menubar");
|
||||||
|
menubarMenu->Append(Menu_MenuBar_Delete, "&Delete menu\tCtrl-D",
|
||||||
|
"Delete the last menu from the menubar");
|
||||||
|
menubarMenu->Append(Menu_MenuBar_Toggle, "&Toggle menu\tCtrl-T",
|
||||||
|
"Toggle the first menu in the menubar", TRUE);
|
||||||
|
menubarMenu->AppendSeparator();
|
||||||
|
menubarMenu->Append(Menu_MenuBar_Enable, "&Enable menu\tCtrl-E",
|
||||||
|
"Enable or disable the last menu", TRUE);
|
||||||
|
menubarMenu->AppendSeparator();
|
||||||
|
menubarMenu->Append(Menu_MenuBar_GetLabel, "&Get menu label\tCtrl-G",
|
||||||
|
"Get the label of the last menu");
|
||||||
|
menubarMenu->Append(Menu_MenuBar_SetLabel, "&Set menu label\tCtrl-S",
|
||||||
|
"Change the label of the last menu");
|
||||||
|
|
||||||
|
wxMenu *menuMenu = new wxMenu;
|
||||||
|
menuMenu->Append(Menu_Menu_Append, "&Append menu item\tAlt-A",
|
||||||
|
"Append a menu item to the last menu");
|
||||||
|
menuMenu->Append(Menu_Menu_AppendSub, "&Append sub menu\tAlt-S",
|
||||||
|
"Append a sub menu to the last menu");
|
||||||
|
menuMenu->Append(Menu_Menu_Insert, "&Insert menu item\tAlt-I",
|
||||||
|
"Insert a menu item in head of the last menu");
|
||||||
|
menuMenu->Append(Menu_Menu_Delete, "&Delete menu item\tAlt-D",
|
||||||
|
"Delete the last menu item from the last menu");
|
||||||
|
menuMenu->AppendSeparator();
|
||||||
|
menuMenu->Append(Menu_Menu_Enable, "&Enable menu item\tAlt-E",
|
||||||
|
"Enable or disable the last menu item", TRUE);
|
||||||
|
menuMenu->Append(Menu_Menu_Check, "&Check menu item\tAlt-C",
|
||||||
|
"Check or uncheck the last menu item", TRUE);
|
||||||
|
menuMenu->AppendSeparator();
|
||||||
|
menuMenu->Append(Menu_Menu_GetLabel, "&Get menu item label\tAlt-G",
|
||||||
|
"Get the label of the last menu item");
|
||||||
|
menuMenu->Append(Menu_Menu_SetLabel, "&Set menu item label\tAlt-S",
|
||||||
|
"Change the label of the last menu item");
|
||||||
|
|
||||||
|
wxMenu *helpMenu = new wxMenu;
|
||||||
|
helpMenu->Append(Menu_Help_About, "&About\tF1", "About menu sample");
|
||||||
|
|
||||||
|
wxMenuBar* menuBar = new wxMenuBar( wxMB_DOCKABLE );
|
||||||
|
|
||||||
|
menuBar->Append(fileMenu, "&File");
|
||||||
|
menuBar->Append(menubarMenu, "Menu&bar");
|
||||||
|
menuBar->Append(menuMenu, "&Menu");
|
||||||
|
menuBar->Append(helpMenu, "&Help");
|
||||||
|
|
||||||
|
// these items should be initially checked
|
||||||
|
menuBar->Check(Menu_MenuBar_Toggle, TRUE);
|
||||||
|
menuBar->Check(Menu_MenuBar_Enable, TRUE);
|
||||||
|
menuBar->Check(Menu_Menu_Enable, TRUE);
|
||||||
|
menuBar->Check(Menu_Menu_Check, FALSE);
|
||||||
|
|
||||||
|
// associate the menu bar with the frame
|
||||||
|
SetMenuBar(menuBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMenu *MyFrame::CreateDummyMenu()
|
||||||
|
{
|
||||||
|
wxMenu *menu = new wxMenu;
|
||||||
|
menu->Append(Menu_Dummy_First, "First item\tCtrl-F1");
|
||||||
|
menu->AppendSeparator();
|
||||||
|
menu->Append(Menu_Dummy_Second, "Second item\tCtrl-F2", "", TRUE);
|
||||||
|
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMenuItem *MyFrame::GetLastMenuItem() const
|
||||||
|
{
|
||||||
|
wxMenuBar *menubar = GetMenuBar();
|
||||||
|
wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
|
||||||
|
|
||||||
|
wxMenuItemList::Node *node = menu->GetMenuItems().GetLast();
|
||||||
|
if ( !node )
|
||||||
|
{
|
||||||
|
wxLogWarning("No last item in the last menu!");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return node->GetData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
Close(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
(void)wxMessageBox("wxWindows toolbar sample",
|
||||||
|
"About wxWindows menu sample",
|
||||||
|
wxICON_INFORMATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnDeleteMenu(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuBar *mbar = GetMenuBar();
|
||||||
|
|
||||||
|
size_t count = mbar->GetMenuCount();
|
||||||
|
if ( count == 2 )
|
||||||
|
{
|
||||||
|
// don't let delete the first 2 menus
|
||||||
|
wxLogError("Can't delete any more menus");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete mbar->Remove(count - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnAppendMenu(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
static s_count = 0;
|
||||||
|
|
||||||
|
wxString title;
|
||||||
|
title.Printf("Dummy menu &%d", ++s_count);
|
||||||
|
|
||||||
|
GetMenuBar()->Append(CreateDummyMenu(), title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnToggleMenu(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuBar *mbar = GetMenuBar();
|
||||||
|
if ( !m_menu )
|
||||||
|
{
|
||||||
|
// hide the menu
|
||||||
|
m_menu = mbar->Remove(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// restore it
|
||||||
|
mbar->Insert(0, m_menu, "&File");
|
||||||
|
m_menu = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnEnableMenu(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuBar *mbar = GetMenuBar();
|
||||||
|
size_t count = mbar->GetMenuCount();
|
||||||
|
|
||||||
|
static bool s_enabled = TRUE;
|
||||||
|
|
||||||
|
s_enabled = !s_enabled;
|
||||||
|
mbar->EnableTop(count - 1, s_enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnGetLabelMenu(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuBar *mbar = GetMenuBar();
|
||||||
|
size_t count = mbar->GetMenuCount();
|
||||||
|
|
||||||
|
wxLogMessage("The label of the last menu item is '%s'",
|
||||||
|
mbar->GetLabelTop(count - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnSetLabelMenu(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuBar *mbar = GetMenuBar();
|
||||||
|
size_t count = mbar->GetMenuCount();
|
||||||
|
|
||||||
|
mbar->SetLabelTop(count - 1, "Dummy label &0");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnDummy(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
wxString s;
|
||||||
|
s.Printf("Dummy item #%d", event.GetId() - Menu_Dummy_First + 1);
|
||||||
|
wxMessageBox(s, "Menu sample", wxICON_INFORMATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnAppendMenuItem(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuBar *menubar = GetMenuBar();
|
||||||
|
wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
|
||||||
|
|
||||||
|
menu->AppendSeparator();
|
||||||
|
menu->Append(Menu_Dummy_Third, "Third dummy item\tCtrl-F3",
|
||||||
|
"Checkable item", TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnAppendSubMenu(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuBar *menubar = GetMenuBar();
|
||||||
|
wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
|
||||||
|
|
||||||
|
menu->Append(Menu_Dummy_Last, "Dummy sub menu\tCtrl-F12",
|
||||||
|
CreateDummyMenu());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnDeleteMenuItem(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuBar *menubar = GetMenuBar();
|
||||||
|
wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
|
||||||
|
|
||||||
|
size_t count = menu->GetMenuItemCount();
|
||||||
|
if ( !count )
|
||||||
|
{
|
||||||
|
wxLogWarning("No items to delete!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
menu->Destroy(menu->GetMenuItems().Item(count - 1)->GetData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnInsertMenuItem(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuBar *menubar = GetMenuBar();
|
||||||
|
wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
|
||||||
|
|
||||||
|
menu->Insert(0, wxMenuItem::New(menu, Menu_Dummy_Fourth,
|
||||||
|
"Fourth dummy item\tCtrl-F4"));
|
||||||
|
menu->Insert(1, wxMenuItem::New(menu, wxID_SEPARATOR, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnEnableMenuItem(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuItem *item = GetLastMenuItem();
|
||||||
|
|
||||||
|
if ( item )
|
||||||
|
{
|
||||||
|
item->Enable(!item->IsEnabled());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnCheckMenuItem(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuItem *item = GetLastMenuItem();
|
||||||
|
|
||||||
|
item->Toggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnUpdateCheckMenuItemUI(wxUpdateUIEvent& event)
|
||||||
|
{
|
||||||
|
wxMenuItem *item = GetLastMenuItem();
|
||||||
|
|
||||||
|
event.Enable(item && item->IsCheckable());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnGetLabelMenuItem(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuItem *item = GetLastMenuItem();
|
||||||
|
|
||||||
|
if ( item )
|
||||||
|
{
|
||||||
|
wxLogMessage("The label of the last menu item is '%s'",
|
||||||
|
item->GetLabel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnSetLabelMenuItem(wxCommandEvent& WXUNUSED(event))
|
||||||
|
{
|
||||||
|
wxMenuItem *item = GetLastMenuItem();
|
||||||
|
|
||||||
|
if ( item )
|
||||||
|
{
|
||||||
|
item->SetText("Dummy menu item text");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyFrame::OnRightDown(wxMouseEvent &event )
|
||||||
|
{
|
||||||
|
wxMenu menu("Test popup");
|
||||||
|
|
||||||
|
menu.Append(Menu_Help_About, "&About");
|
||||||
|
menu.Append(Menu_Popup_Submenu, "Submenu", CreateDummyMenu());
|
||||||
|
menu.Append(Menu_Popup_ToBeDeleted, "To be deleted");
|
||||||
|
menu.Append(Menu_Popup_ToBeChecked, "To be checked", "", TRUE);
|
||||||
|
menu.Append(Menu_Popup_ToBeGreyed, "To be greyed");
|
||||||
|
menu.AppendSeparator();
|
||||||
|
menu.Append(Menu_File_Quit, "E&xit");
|
||||||
|
|
||||||
|
menu.Delete(Menu_Popup_ToBeDeleted);
|
||||||
|
menu.Check(Menu_Popup_ToBeChecked, TRUE);
|
||||||
|
menu.Enable(Menu_Popup_ToBeGreyed, FALSE);
|
||||||
|
|
||||||
|
PopupMenu( &menu, event.GetX(), event.GetY() );
|
||||||
|
}
|
@@ -71,8 +71,6 @@ public:
|
|||||||
const wxSize& size = wxDefaultSize,
|
const wxSize& size = wxDefaultSize,
|
||||||
long style = wxDEFAULT_FRAME_STYLE);
|
long style = wxDEFAULT_FRAME_STYLE);
|
||||||
|
|
||||||
virtual ~MyFrame() { delete m_menu; }
|
|
||||||
|
|
||||||
void OnQuit(wxCommandEvent& event);
|
void OnQuit(wxCommandEvent& event);
|
||||||
void OnAbout(wxCommandEvent& event);
|
void OnAbout(wxCommandEvent& event);
|
||||||
|
|
||||||
@@ -94,8 +92,6 @@ private:
|
|||||||
bool m_smallToolbar;
|
bool m_smallToolbar;
|
||||||
wxTextCtrl* m_textWindow;
|
wxTextCtrl* m_textWindow;
|
||||||
|
|
||||||
wxMenu *m_menu;
|
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -109,10 +105,7 @@ enum
|
|||||||
{
|
{
|
||||||
IDM_TOOLBAR_TOGGLETOOLBAR = 200,
|
IDM_TOOLBAR_TOGGLETOOLBAR = 200,
|
||||||
IDM_TOOLBAR_ENABLEPRINT,
|
IDM_TOOLBAR_ENABLEPRINT,
|
||||||
IDM_TOOLBAR_TOGGLEHELP,
|
IDM_TOOLBAR_TOGGLEHELP
|
||||||
IDM_MENU_TOGGLE,
|
|
||||||
IDM_MENU_APPEND,
|
|
||||||
IDM_MENU_DELETE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -130,10 +123,6 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
|||||||
EVT_MENU(IDM_TOOLBAR_ENABLEPRINT, MyFrame::OnEnablePrint)
|
EVT_MENU(IDM_TOOLBAR_ENABLEPRINT, MyFrame::OnEnablePrint)
|
||||||
EVT_MENU(IDM_TOOLBAR_TOGGLEHELP, MyFrame::OnToggleHelp)
|
EVT_MENU(IDM_TOOLBAR_TOGGLEHELP, MyFrame::OnToggleHelp)
|
||||||
|
|
||||||
EVT_MENU(IDM_MENU_TOGGLE, MyFrame::OnToggleMenu)
|
|
||||||
EVT_MENU(IDM_MENU_APPEND, MyFrame::OnAppendMenu)
|
|
||||||
EVT_MENU(IDM_MENU_DELETE, MyFrame::OnDeleteMenu)
|
|
||||||
|
|
||||||
EVT_MENU(-1, MyFrame::OnToolLeftClick)
|
EVT_MENU(-1, MyFrame::OnToolLeftClick)
|
||||||
|
|
||||||
EVT_TOOL_ENTER(ID_TOOLBAR, MyFrame::OnToolEnter)
|
EVT_TOOL_ENTER(ID_TOOLBAR, MyFrame::OnToolEnter)
|
||||||
@@ -261,7 +250,6 @@ MyFrame::MyFrame(wxFrame* parent,
|
|||||||
long style)
|
long style)
|
||||||
: wxFrame(parent, id, title, pos, size, style)
|
: wxFrame(parent, id, title, pos, size, style)
|
||||||
{
|
{
|
||||||
m_menu = NULL;
|
|
||||||
m_textWindow = new wxTextCtrl(this, -1, "", wxPoint(0, 0), wxSize(-1, -1), wxTE_MULTILINE);
|
m_textWindow = new wxTextCtrl(this, -1, "", wxPoint(0, 0), wxSize(-1, -1), wxTE_MULTILINE);
|
||||||
m_smallToolbar = FALSE;
|
m_smallToolbar = FALSE;
|
||||||
|
|
||||||
@@ -280,11 +268,6 @@ MyFrame::MyFrame(wxFrame* parent,
|
|||||||
wxMenu *fileMenu = new wxMenu;
|
wxMenu *fileMenu = new wxMenu;
|
||||||
fileMenu->Append(wxID_EXIT, "E&xit", "Quit toolbar sample" );
|
fileMenu->Append(wxID_EXIT, "E&xit", "Quit toolbar sample" );
|
||||||
|
|
||||||
wxMenu *menuMenu = new wxMenu;
|
|
||||||
menuMenu->Append(IDM_MENU_APPEND, "&Append menu");
|
|
||||||
menuMenu->Append(IDM_MENU_DELETE, "&Delete menu");
|
|
||||||
menuMenu->Append(IDM_MENU_TOGGLE, "&Toggle menu", "", TRUE);
|
|
||||||
|
|
||||||
wxMenu *helpMenu = new wxMenu;
|
wxMenu *helpMenu = new wxMenu;
|
||||||
helpMenu->Append(wxID_HELP, "&About", "About toolbar sample");
|
helpMenu->Append(wxID_HELP, "&About", "About toolbar sample");
|
||||||
|
|
||||||
@@ -292,7 +275,6 @@ MyFrame::MyFrame(wxFrame* parent,
|
|||||||
|
|
||||||
menuBar->Append(fileMenu, "&File");
|
menuBar->Append(fileMenu, "&File");
|
||||||
menuBar->Append(tbarMenu, "&Toolbar");
|
menuBar->Append(tbarMenu, "&Toolbar");
|
||||||
menuBar->Append(menuMenu, "&Menubar");
|
|
||||||
menuBar->Append(helpMenu, "&Help");
|
menuBar->Append(helpMenu, "&Help");
|
||||||
|
|
||||||
// Associate the menu bar with the frame
|
// Associate the menu bar with the frame
|
||||||
@@ -333,53 +315,6 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
|||||||
(void)wxMessageBox("wxWindows toolbar sample", "About wxToolBar");
|
(void)wxMessageBox("wxWindows toolbar sample", "About wxToolBar");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyFrame::OnDeleteMenu(wxCommandEvent& WXUNUSED(event))
|
|
||||||
{
|
|
||||||
wxMenuBar *mbar = GetMenuBar();
|
|
||||||
|
|
||||||
size_t count = mbar->GetMenuCount();
|
|
||||||
if ( count == 3 )
|
|
||||||
{
|
|
||||||
// don't let delete the first 3 menus
|
|
||||||
wxLogError("Can't delete any more menus");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete mbar->Remove(count - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyFrame::OnAppendMenu(wxCommandEvent& WXUNUSED(event))
|
|
||||||
{
|
|
||||||
static s_count = 0;
|
|
||||||
|
|
||||||
wxMenu *menu = new wxMenu;
|
|
||||||
menu->Append(0, "First item");
|
|
||||||
menu->AppendSeparator();
|
|
||||||
menu->Append(0, "Second item");
|
|
||||||
|
|
||||||
wxString title;
|
|
||||||
title.Printf("Dummy menu &%d", ++s_count);
|
|
||||||
|
|
||||||
GetMenuBar()->Append(menu, title);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyFrame::OnToggleMenu(wxCommandEvent& WXUNUSED(event))
|
|
||||||
{
|
|
||||||
wxMenuBar *mbar = GetMenuBar();
|
|
||||||
if ( !m_menu )
|
|
||||||
{
|
|
||||||
// hide the menu
|
|
||||||
m_menu = mbar->Remove(1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// restore it
|
|
||||||
mbar->Insert(1, m_menu, "&Toolbar");
|
|
||||||
m_menu = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyFrame::OnToolLeftClick(wxCommandEvent& event)
|
void MyFrame::OnToolLeftClick(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
wxString str;
|
wxString str;
|
||||||
|
@@ -1931,11 +1931,21 @@ void wxFileHistory::RemoveFileFromHistory(int i)
|
|||||||
// delete the last menu item which is unused now
|
// delete the last menu item which is unused now
|
||||||
menu->Delete(wxID_FILE1 + m_fileHistoryN - 1);
|
menu->Delete(wxID_FILE1 + m_fileHistoryN - 1);
|
||||||
|
|
||||||
// unfortunately, we can't delete separator (there is no function to
|
// delete the last separator too if no more files are left
|
||||||
// delete item by position, only by id - and what if there are several
|
if ( m_fileHistoryN == 1 )
|
||||||
// separators in this menu?) - so we will be always left with at least
|
{
|
||||||
// one and, even worse, we will add another one if this was the last
|
wxMenuItemList::Node *node = menu->GetMenuItems().GetLast();
|
||||||
// file... (FIXME)
|
if ( node )
|
||||||
|
{
|
||||||
|
wxMenuItem *menuItem = node->GetData();
|
||||||
|
if ( menuItem->IsSeparator() )
|
||||||
|
{
|
||||||
|
menu->Delete(menuItem);
|
||||||
|
}
|
||||||
|
//else: should we search backwards for the last separator?
|
||||||
|
}
|
||||||
|
//else: menu is empty somehow
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fileHistoryN--;
|
m_fileHistoryN--;
|
||||||
|
@@ -37,14 +37,410 @@
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "wx/listimpl.cpp"
|
#include "wx/listimpl.cpp"
|
||||||
|
|
||||||
WX_DEFINE_LIST(wxMenuList);
|
WX_DEFINE_LIST(wxMenuList);
|
||||||
|
WX_DEFINE_LIST(wxMenuItemList);
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// ctor and dtor
|
// wxMenuItem
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
wxMenuItemBase::~wxMenuItemBase()
|
||||||
|
{
|
||||||
|
delete m_subMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
|
||||||
|
void wxMenuItemBase::SetAccel(wxAcceleratorEntry *accel)
|
||||||
|
{
|
||||||
|
wxString text = m_text.BeforeFirst(wxT('\t'));
|
||||||
|
if ( accel )
|
||||||
|
{
|
||||||
|
text += wxT('\t');
|
||||||
|
|
||||||
|
int flags = accel->GetFlags();
|
||||||
|
if ( flags & wxACCEL_ALT )
|
||||||
|
text += wxT("Alt-");
|
||||||
|
if ( flags & wxACCEL_CTRL )
|
||||||
|
text += wxT("Ctrl-");
|
||||||
|
if ( flags & wxACCEL_SHIFT )
|
||||||
|
text += wxT("Shift-");
|
||||||
|
|
||||||
|
int code = accel->GetKeyCode();
|
||||||
|
switch ( code )
|
||||||
|
{
|
||||||
|
case WXK_F1:
|
||||||
|
case WXK_F2:
|
||||||
|
case WXK_F3:
|
||||||
|
case WXK_F4:
|
||||||
|
case WXK_F5:
|
||||||
|
case WXK_F6:
|
||||||
|
case WXK_F7:
|
||||||
|
case WXK_F8:
|
||||||
|
case WXK_F9:
|
||||||
|
case WXK_F10:
|
||||||
|
case WXK_F11:
|
||||||
|
case WXK_F12:
|
||||||
|
text << wxT('F') << code - WXK_F1 + 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// if there are any other keys wxGetAccelFromString() may return,
|
||||||
|
// we should process them here
|
||||||
|
|
||||||
|
default:
|
||||||
|
if ( wxIsalnum(code) )
|
||||||
|
{
|
||||||
|
text << (wxChar)code;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFAIL_MSG( wxT("unknown keyboard accel") );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxMenu ctor and dtor
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxMenuBase::Init(long style)
|
||||||
|
{
|
||||||
|
m_items.DeleteContents(TRUE);
|
||||||
|
|
||||||
|
m_menuBar = (wxMenuBar *)NULL;
|
||||||
|
m_menuParent = (wxMenu *)NULL;
|
||||||
|
|
||||||
|
m_invokingWindow = (wxWindow *)NULL;
|
||||||
|
m_style = style;
|
||||||
|
m_clientData = (void *)NULL;
|
||||||
|
m_eventHandler = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMenuBase::~wxMenuBase()
|
||||||
|
{
|
||||||
|
// nothing to do, wxMenuItemList dtor will delete the menu items
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxMenu item adding/removing
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxMenuBase::DoAppend(wxMenuItem *item)
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( item, FALSE, wxT("invalid item in wxMenu::Append()") );
|
||||||
|
|
||||||
|
m_items.Append(item);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxMenuBase::Insert(size_t pos, wxMenuItem *item)
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( item, FALSE, wxT("invalid item in wxMenu::Insert") );
|
||||||
|
wxCHECK_MSG( pos < GetMenuItemCount(), FALSE,
|
||||||
|
wxT("invalid index in wxMenu::Insert") );
|
||||||
|
|
||||||
|
return DoInsert(pos, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxMenuBase::DoInsert(size_t pos, wxMenuItem *item)
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( item, FALSE, wxT("invalid item in wxMenu::Insert()") );
|
||||||
|
|
||||||
|
wxMenuItemList::Node *node = m_items.Item(pos);
|
||||||
|
wxCHECK_MSG( node, FALSE, wxT("invalid index in wxMenu::Insert()") );
|
||||||
|
|
||||||
|
m_items.Insert(node, item);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMenuItem *wxMenuBase::Remove(wxMenuItem *item)
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Remove") );
|
||||||
|
|
||||||
|
return DoRemove(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMenuItem *wxMenuBase::DoRemove(wxMenuItem *item)
|
||||||
|
{
|
||||||
|
wxMenuItemList::Node *node = m_items.Find(item);
|
||||||
|
|
||||||
|
// if we get here, the item is valid or one of Remove() functions is broken
|
||||||
|
wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
|
||||||
|
|
||||||
|
// we detach the item, but we do delete the list node (i.e. don't call
|
||||||
|
// DetachNode() here!)
|
||||||
|
node->SetData((wxMenuItem *)NULL); // to prevent it from deleting the item
|
||||||
|
m_items.DeleteNode(node);
|
||||||
|
|
||||||
|
// item isn't attached to anything any more
|
||||||
|
wxMenu *submenu = item->GetSubMenu();
|
||||||
|
if ( submenu )
|
||||||
|
{
|
||||||
|
submenu->SetParent((wxMenu *)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxMenuBase::Delete(wxMenuItem *item)
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Delete") );
|
||||||
|
|
||||||
|
return DoDelete(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxMenuBase::DoDelete(wxMenuItem *item)
|
||||||
|
{
|
||||||
|
wxMenuItem *item2 = DoRemove(item);
|
||||||
|
wxCHECK_MSG( item2, FALSE, wxT("failed to delete menu item") );
|
||||||
|
|
||||||
|
// don't delete the submenu
|
||||||
|
item2->SetSubMenu((wxMenu *)NULL);
|
||||||
|
|
||||||
|
delete item2;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxMenuBase::Destroy(wxMenuItem *item)
|
||||||
|
{
|
||||||
|
wxCHECK_MSG( item, NULL, wxT("invalid item in wxMenu::Destroy") );
|
||||||
|
|
||||||
|
return DoDestroy(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxMenuBase::DoDestroy(wxMenuItem *item)
|
||||||
|
{
|
||||||
|
wxMenuItem *item2 = DoRemove(item);
|
||||||
|
wxCHECK_MSG( item2, FALSE, wxT("failed to delete menu item") );
|
||||||
|
|
||||||
|
delete item2;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxMenu searching for items
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Finds the item id matching the given string, -1 if not found.
|
||||||
|
int wxMenuBase::FindItem(const wxString& text) const
|
||||||
|
{
|
||||||
|
wxString label = wxMenuItem(NULL, wxID_SEPARATOR, text).GetLabel();
|
||||||
|
for ( wxMenuItemList::Node *node = m_items.GetFirst();
|
||||||
|
node;
|
||||||
|
node = node->GetNext() )
|
||||||
|
{
|
||||||
|
wxMenuItem *item = node->GetData();
|
||||||
|
if ( item->IsSubMenu() )
|
||||||
|
{
|
||||||
|
int rc = item->GetSubMenu()->FindItem(label);
|
||||||
|
if ( rc != wxNOT_FOUND )
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
else if ( !item->IsSeparator() )
|
||||||
|
{
|
||||||
|
if ( item->GetLabel() == label )
|
||||||
|
return item->GetId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxNOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// recursive search for item by id
|
||||||
|
wxMenuItem *wxMenuBase::FindItem(int itemId, wxMenu **itemMenu) const
|
||||||
|
{
|
||||||
|
if ( itemMenu )
|
||||||
|
*itemMenu = NULL;
|
||||||
|
|
||||||
|
wxMenuItem *item = NULL;
|
||||||
|
for ( wxMenuItemList::Node *node = m_items.GetFirst();
|
||||||
|
node && !item;
|
||||||
|
node = node->GetNext() )
|
||||||
|
{
|
||||||
|
item = node->GetData();
|
||||||
|
|
||||||
|
if ( item->GetId() == itemId )
|
||||||
|
{
|
||||||
|
if ( itemMenu )
|
||||||
|
*itemMenu = (wxMenu *)this;
|
||||||
|
}
|
||||||
|
else if ( item->IsSubMenu() )
|
||||||
|
{
|
||||||
|
item = item->GetSubMenu()->FindItem(itemId, itemMenu);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// don't exit the loop
|
||||||
|
item = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// non recursive search
|
||||||
|
wxMenuItem *wxMenuBase::FindChildItem(int id, size_t *ppos) const
|
||||||
|
{
|
||||||
|
wxMenuItem *item = (wxMenuItem *)NULL;
|
||||||
|
wxMenuItemList::Node *node = GetMenuItems().GetFirst();
|
||||||
|
|
||||||
|
size_t pos;
|
||||||
|
for ( pos = 0; node; pos++ )
|
||||||
|
{
|
||||||
|
item = node->GetData();
|
||||||
|
if ( item->GetId() == id )
|
||||||
|
break;
|
||||||
|
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ppos )
|
||||||
|
{
|
||||||
|
*ppos = item ? pos : wxNOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxMenu helpers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Update a menu and all submenus recursively. source is the object that has
|
||||||
|
// the update event handlers defined for it. If NULL, the menu or associated
|
||||||
|
// window will be used.
|
||||||
|
void wxMenuBase::UpdateUI(wxEvtHandler* source)
|
||||||
|
{
|
||||||
|
if ( !source && GetInvokingWindow() )
|
||||||
|
source = GetInvokingWindow()->GetEventHandler();
|
||||||
|
if ( !source )
|
||||||
|
source = GetEventHandler();
|
||||||
|
if ( !source )
|
||||||
|
source = this;
|
||||||
|
|
||||||
|
wxMenuItemList::Node* node = GetMenuItems().GetFirst();
|
||||||
|
while ( node )
|
||||||
|
{
|
||||||
|
wxMenuItem* item = node->GetData();
|
||||||
|
if ( !item->IsSeparator() )
|
||||||
|
{
|
||||||
|
wxWindowID id = item->GetId();
|
||||||
|
wxUpdateUIEvent event(id);
|
||||||
|
event.SetEventObject( source );
|
||||||
|
|
||||||
|
if ( source->ProcessEvent(event) )
|
||||||
|
{
|
||||||
|
// if anything changed, update the chanegd attribute
|
||||||
|
if (event.GetSetText())
|
||||||
|
SetLabel(id, event.GetText());
|
||||||
|
if (event.GetSetChecked())
|
||||||
|
Check(id, event.GetChecked());
|
||||||
|
if (event.GetSetEnabled())
|
||||||
|
Enable(id, event.GetEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
// recurse to the submenus
|
||||||
|
if ( item->GetSubMenu() )
|
||||||
|
item->GetSubMenu()->UpdateUI(source);
|
||||||
|
}
|
||||||
|
//else: item is a separator (which don't process update UI events)
|
||||||
|
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxMenu functions forwarded to wxMenuItem
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void wxMenuBase::Enable( int id, bool enable )
|
||||||
|
{
|
||||||
|
wxMenuItem *item = FindItem(id);
|
||||||
|
|
||||||
|
wxCHECK_RET( item, wxT("wxMenu::Enable: no such item") );
|
||||||
|
|
||||||
|
item->Enable(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxMenuBase::IsEnabled( int id ) const
|
||||||
|
{
|
||||||
|
wxMenuItem *item = FindItem(id);
|
||||||
|
|
||||||
|
wxCHECK_MSG( item, FALSE, wxT("wxMenu::IsEnabled: no such item") );
|
||||||
|
|
||||||
|
return item->IsEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxMenuBase::Check( int id, bool enable )
|
||||||
|
{
|
||||||
|
wxMenuItem *item = FindItem(id);
|
||||||
|
|
||||||
|
wxCHECK_RET( item, wxT("wxMenu::Check: no such item") );
|
||||||
|
|
||||||
|
item->Check(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxMenuBase::IsChecked( int id ) const
|
||||||
|
{
|
||||||
|
wxMenuItem *item = FindItem(id);
|
||||||
|
|
||||||
|
wxCHECK_MSG( item, FALSE, wxT("wxMenu::IsChecked: no such item") );
|
||||||
|
|
||||||
|
return item->IsChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxMenuBase::SetLabel( int id, const wxString &label )
|
||||||
|
{
|
||||||
|
wxMenuItem *item = FindItem(id);
|
||||||
|
|
||||||
|
wxCHECK_RET( item, wxT("wxMenu::SetLabel: no such item") );
|
||||||
|
|
||||||
|
item->SetText(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString wxMenuBase::GetLabel( int id ) const
|
||||||
|
{
|
||||||
|
wxMenuItem *item = FindItem(id);
|
||||||
|
|
||||||
|
wxCHECK_MSG( item, wxT(""), wxT("wxMenu::GetLabel: no such item") );
|
||||||
|
|
||||||
|
return item->GetText();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxMenuBase::SetHelpString( int id, const wxString& helpString )
|
||||||
|
{
|
||||||
|
wxMenuItem *item = FindItem(id);
|
||||||
|
|
||||||
|
wxCHECK_RET( item, wxT("wxMenu::SetHelpString: no such item") );
|
||||||
|
|
||||||
|
item->SetHelp( helpString );
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString wxMenuBase::GetHelpString( int id ) const
|
||||||
|
{
|
||||||
|
wxMenuItem *item = FindItem(id);
|
||||||
|
|
||||||
|
wxCHECK_MSG( item, wxT(""), wxT("wxMenu::GetHelpString: no such item") );
|
||||||
|
|
||||||
|
return item->GetHelp();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxMenuBarBase ctor and dtor
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxMenuBarBase::wxMenuBarBase()
|
wxMenuBarBase::wxMenuBarBase()
|
||||||
|
@@ -2890,7 +2890,7 @@ bool wxWindowBase::LoadFromResource(wxWindow *parent, const wxString& resourceNa
|
|||||||
else if (IsKindOf(CLASSINFO(wxPanel)))
|
else if (IsKindOf(CLASSINFO(wxPanel)))
|
||||||
{
|
{
|
||||||
wxPanel* panel = (wxPanel *)this;
|
wxPanel* panel = (wxPanel *)this;
|
||||||
if (!panel->Create(parent, -1, wxPoint(x, y), wxSize(width, height), theWindowStyle, name))
|
if (!panel->Create(parent, -1, wxPoint(x, y), wxSize(width, height), theWindowStyle | wxTAB_TRAVERSAL, name))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
654
src/gtk/menu.cpp
654
src/gtk/menu.cpp
@@ -31,6 +31,10 @@
|
|||||||
extern void wxapp_install_idle_handler();
|
extern void wxapp_install_idle_handler();
|
||||||
extern bool g_isIdle;
|
extern bool g_isIdle;
|
||||||
|
|
||||||
|
#if (GTK_MINOR_VERSION > 0) && wxUSE_ACCEL
|
||||||
|
static wxString GetHotKey( const wxMenuItem& item );
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// wxMenuBar
|
// wxMenuBar
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -355,7 +359,7 @@ int wxMenuBar::FindMenuItem( const wxString &menuString, const wxString &itemStr
|
|||||||
// Find a wxMenuItem using its id. Recurses down into sub-menus
|
// Find a wxMenuItem using its id. Recurses down into sub-menus
|
||||||
static wxMenuItem* FindMenuItemByIdRecursive(const wxMenu* menu, int id)
|
static wxMenuItem* FindMenuItemByIdRecursive(const wxMenu* menu, int id)
|
||||||
{
|
{
|
||||||
wxMenuItem* result = menu->FindItem(id);
|
wxMenuItem* result = menu->FindChildItem(id);
|
||||||
|
|
||||||
wxNode *node = ((wxMenu *)menu)->GetItems().First(); // const_cast
|
wxNode *node = ((wxMenu *)menu)->GetItems().First(); // const_cast
|
||||||
while ( node && result == NULL )
|
while ( node && result == NULL )
|
||||||
@@ -440,7 +444,7 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
|
|||||||
if (!menu->IsEnabled(id))
|
if (!menu->IsEnabled(id))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxMenuItem* item = menu->FindItem( id );
|
wxMenuItem* item = menu->FindChildItem( id );
|
||||||
wxCHECK_RET( item, wxT("error in menu item callback") );
|
wxCHECK_RET( item, wxT("error in menu item callback") );
|
||||||
|
|
||||||
if (item->IsCheckable())
|
if (item->IsCheckable())
|
||||||
@@ -569,6 +573,28 @@ wxMenuItem::~wxMenuItem()
|
|||||||
// don't delete menu items, the menus take care of that
|
// don't delete menu items, the menus take care of that
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return the menu item text without any menu accels
|
||||||
|
wxString wxMenuItem::GetLabel() const
|
||||||
|
{
|
||||||
|
wxString label;
|
||||||
|
#if (GTK_MINOR_VERSION > 0)
|
||||||
|
for ( const wxChar *pc = m_text.c_str(); *pc; pc++ )
|
||||||
|
{
|
||||||
|
if ( *pc == wxT('_') )
|
||||||
|
{
|
||||||
|
// this is the escape character for GTK+ - skip it
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
label += *pc;
|
||||||
|
}
|
||||||
|
#else // GTK+ 1.0
|
||||||
|
label = m_text;
|
||||||
|
#endif // GTK+ 1.2/1.0
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
void wxMenuItem::SetText( const wxString& str )
|
void wxMenuItem::SetText( const wxString& str )
|
||||||
{
|
{
|
||||||
DoSetText(str);
|
DoSetText(str);
|
||||||
@@ -623,6 +649,25 @@ void wxMenuItem::DoSetText( const wxString& str )
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
|
||||||
|
wxAcceleratorEntry *wxMenuItem::GetAccel() const
|
||||||
|
{
|
||||||
|
if ( !item.GetHotKey() )
|
||||||
|
{
|
||||||
|
// nothing
|
||||||
|
return (wxAcceleratorEntry *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// as wxGetAccelFromString() looks for TAB, insert a dummy one here
|
||||||
|
wxString label;
|
||||||
|
label << wxT('\t') << item.GetHotKey();
|
||||||
|
|
||||||
|
return wxGetAccelFromString(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
void wxMenuItem::Check( bool check )
|
void wxMenuItem::Check( bool check )
|
||||||
{
|
{
|
||||||
wxCHECK_RET( m_menuItem, wxT("invalid menu item") );
|
wxCHECK_RET( m_menuItem, wxT("invalid menu item") );
|
||||||
@@ -658,11 +703,7 @@ wxString wxMenuItem::GetFactoryPath() const
|
|||||||
{
|
{
|
||||||
/* in order to get the pointer to the item we need the item text _without_ underscores */
|
/* in order to get the pointer to the item we need the item text _without_ underscores */
|
||||||
wxString path( wxT("<main>/") );
|
wxString path( wxT("<main>/") );
|
||||||
for ( const wxChar *pc = m_text; *pc != wxT('\0'); pc++ )
|
path += GetLabel();
|
||||||
{
|
|
||||||
while (*pc == wxT('_')) pc++; /* skip it */
|
|
||||||
path << *pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@@ -673,17 +714,8 @@ wxString wxMenuItem::GetFactoryPath() const
|
|||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler)
|
IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler)
|
||||||
|
|
||||||
void
|
void wxMenu::Init()
|
||||||
wxMenu::Init( const wxString& title,
|
|
||||||
long style,
|
|
||||||
const wxFunction func
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
m_title = title;
|
|
||||||
m_items.DeleteContents( TRUE );
|
|
||||||
m_invokingWindow = (wxWindow *) NULL;
|
|
||||||
m_style = style;
|
|
||||||
|
|
||||||
#if (GTK_MINOR_VERSION > 0)
|
#if (GTK_MINOR_VERSION > 0)
|
||||||
m_accel = gtk_accel_group_new();
|
m_accel = gtk_accel_group_new();
|
||||||
m_factory = gtk_item_factory_new( GTK_TYPE_MENU, "<main>", m_accel );
|
m_factory = gtk_item_factory_new( GTK_TYPE_MENU, "<main>", m_accel );
|
||||||
@@ -692,18 +724,6 @@ wxMenu::Init( const wxString& title,
|
|||||||
m_menu = gtk_menu_new(); // Do not show!
|
m_menu = gtk_menu_new(); // Do not show!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_callback = func;
|
|
||||||
|
|
||||||
m_eventHandler = this;
|
|
||||||
m_clientData = (void*) NULL;
|
|
||||||
|
|
||||||
if (m_title.IsNull()) m_title = wxT("");
|
|
||||||
if (m_title != wxT(""))
|
|
||||||
{
|
|
||||||
Append(-2, m_title);
|
|
||||||
AppendSeparator();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_owner = (GtkWidget*) NULL;
|
m_owner = (GtkWidget*) NULL;
|
||||||
|
|
||||||
#if (GTK_MINOR_VERSION > 0)
|
#if (GTK_MINOR_VERSION > 0)
|
||||||
@@ -722,40 +742,30 @@ wxMenu::Init( const wxString& title,
|
|||||||
//GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, "<main>/tearoff" );
|
//GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, "<main>/tearoff" );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// append the title as the very first entry if we have it
|
||||||
|
if ( !!m_title )
|
||||||
|
{
|
||||||
|
Append(-2, m_title);
|
||||||
|
AppendSeparator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxMenu::~wxMenu()
|
wxMenu::~wxMenu()
|
||||||
{
|
{
|
||||||
wxNode *node = m_items.First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
|
||||||
wxMenu *submenu = item->GetSubMenu();
|
|
||||||
if (submenu)
|
|
||||||
delete submenu;
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_destroy( m_menu );
|
gtk_widget_destroy( m_menu );
|
||||||
|
|
||||||
gtk_object_unref( GTK_OBJECT(m_factory) );
|
gtk_object_unref( GTK_OBJECT(m_factory) );
|
||||||
|
|
||||||
|
// the menu items are deleted by the base class dtor
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenu::SetTitle( const wxString& title )
|
virtual bool wxMenu::DoAppend(wxMenuItem *mitem)
|
||||||
{
|
{
|
||||||
// TODO Waiting for something better
|
GtkWidget *menuItem;
|
||||||
m_title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString wxMenu::GetTitle() const
|
|
||||||
{
|
|
||||||
return m_title;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::AppendSeparator()
|
|
||||||
{
|
|
||||||
wxMenuItem *mitem = new wxMenuItem(this, wxID_SEPARATOR);
|
|
||||||
|
|
||||||
|
if ( mitem->IsSeparator() )
|
||||||
|
{
|
||||||
#if (GTK_MINOR_VERSION > 0)
|
#if (GTK_MINOR_VERSION > 0)
|
||||||
GtkItemFactoryEntry entry;
|
GtkItemFactoryEntry entry;
|
||||||
entry.path = "/sep";
|
entry.path = "/sep";
|
||||||
@@ -767,30 +777,191 @@ void wxMenu::AppendSeparator()
|
|||||||
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
||||||
|
|
||||||
/* this will be wrong for more than one separator. do we care? */
|
/* this will be wrong for more than one separator. do we care? */
|
||||||
GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, "<main>/sep" );
|
menuItem = gtk_item_factory_get_widget( m_factory, "<main>/sep" );
|
||||||
#else
|
#else // GTK+ 1.0
|
||||||
GtkWidget *menuItem = gtk_menu_item_new();
|
menuItem = gtk_menu_item_new();
|
||||||
|
#endif // GTK 1.2/1.0
|
||||||
|
}
|
||||||
|
else if ( mitem->IsSubMenu() )
|
||||||
|
{
|
||||||
|
#if (GTK_MINOR_VERSION > 0)
|
||||||
|
/* text has "_" instead of "&" after mitem->SetText() */
|
||||||
|
wxString text( mitem->GetText() );
|
||||||
|
|
||||||
|
/* local buffer in multibyte form */
|
||||||
|
char buf[200];
|
||||||
|
strcpy( buf, "/" );
|
||||||
|
strcat( buf, text.mb_str() );
|
||||||
|
|
||||||
|
GtkItemFactoryEntry entry;
|
||||||
|
entry.path = buf;
|
||||||
|
entry.callback = (GtkItemFactoryCallback) 0;
|
||||||
|
entry.callback_action = 0;
|
||||||
|
entry.item_type = "<Branch>";
|
||||||
|
|
||||||
|
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
||||||
|
|
||||||
|
wxString path( mitem->GetFactoryPath() );
|
||||||
|
GtkWidget *menuItem = gtk_item_factory_get_item( m_factory, path.mb_str() );
|
||||||
|
#else // GTK+ 1.0
|
||||||
|
GtkWidget *menuItem = gtk_menu_item_new_with_label(mitem->GetText().mbc_str());
|
||||||
|
#endif // GTK 1.2/1.0
|
||||||
|
|
||||||
|
gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), subMenu->m_menu );
|
||||||
|
}
|
||||||
|
else // a normal item
|
||||||
|
{
|
||||||
|
#if (GTK_MINOR_VERSION > 0)
|
||||||
|
/* text has "_" instead of "&" after mitem->SetText() */
|
||||||
|
wxString text( mitem->GetText() );
|
||||||
|
|
||||||
|
/* local buffer in multibyte form */
|
||||||
|
char buf[200];
|
||||||
|
strcpy( buf, "/" );
|
||||||
|
strcat( buf, text.mb_str() );
|
||||||
|
|
||||||
|
GtkItemFactoryEntry entry;
|
||||||
|
entry.path = buf;
|
||||||
|
entry.callback = (GtkItemFactoryCallback) gtk_menu_clicked_callback;
|
||||||
|
entry.callback_action = 0;
|
||||||
|
if (checkable)
|
||||||
|
entry.item_type = "<CheckItem>";
|
||||||
|
else
|
||||||
|
entry.item_type = "<Item>";
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
// due to an apparent bug in GTK+, we have to use a static buffer here -
|
||||||
|
// otherwise GTK+ 1.2.2 manages to override the memory we pass to it
|
||||||
|
// somehow! (VZ)
|
||||||
|
static char s_accel[32]; // must be big enough for <control><alt><shift>F12
|
||||||
|
strncpy(s_accel, GetHotKey(*mitem).mb_str(), WXSIZEOF(s_accel));
|
||||||
|
entry.accelerator = s_accel;
|
||||||
|
#else // !wxUSE_ACCEL
|
||||||
|
entry.accelerator = (char*) NULL;
|
||||||
|
#endif // wxUSE_ACCEL/!wxUSE_ACCEL
|
||||||
|
|
||||||
|
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
||||||
|
|
||||||
|
wxString path( mitem->GetFactoryPath() );
|
||||||
|
GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, path.mb_str() );
|
||||||
|
#else // GTK+ 1.0
|
||||||
|
GtkWidget *menuItem = checkable ? gtk_check_menu_item_new_with_label( mitem->GetText().mb_str() )
|
||||||
|
: gtk_menu_item_new_with_label( mitem->GetText().mb_str() );
|
||||||
|
|
||||||
|
gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
|
||||||
|
GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
|
||||||
|
(gpointer)this );
|
||||||
|
#endif // GTK+ 1.2/1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !mitem->IsSeparator() )
|
||||||
|
{
|
||||||
|
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
||||||
|
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
||||||
|
(gpointer)this );
|
||||||
|
|
||||||
|
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
||||||
|
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
||||||
|
(gpointer)this );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GTK_MINOR_VERSION == 0
|
||||||
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
||||||
gtk_widget_show( menuItem );
|
gtk_widget_show( menuItem );
|
||||||
#endif
|
#endif // GTK+ 1.0
|
||||||
|
|
||||||
mitem->SetMenuItem(menuItem);
|
mitem->SetMenuItem(menuItem);
|
||||||
m_items.Append( mitem );
|
|
||||||
|
return wxMenuBase::DoAppend(mitem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VZ: this seems to be GTK+ 1.0 only code, I don't understand why there were
|
||||||
|
// both specialized versions of Append() and this one before my changes,
|
||||||
|
// but it seems that the others are better...
|
||||||
|
#if 0
|
||||||
|
void wxMenu::Append( wxMenuItem *item )
|
||||||
|
{
|
||||||
|
GtkWidget *menuItem = (GtkWidget*) NULL;
|
||||||
|
|
||||||
|
if (item->IsSeparator())
|
||||||
|
menuItem = gtk_menu_item_new();
|
||||||
|
else if (item->IsSubMenu())
|
||||||
|
menuItem = gtk_menu_item_new_with_label(item->GetText().mbc_str());
|
||||||
|
else
|
||||||
|
menuItem = item->IsCheckable() ? gtk_check_menu_item_new_with_label(item->GetText().mbc_str())
|
||||||
|
: gtk_menu_item_new_with_label(item->GetText().mbc_str());
|
||||||
|
|
||||||
|
if (!item->IsSeparator())
|
||||||
|
{
|
||||||
|
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
||||||
|
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
||||||
|
(gpointer*)this );
|
||||||
|
|
||||||
|
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
||||||
|
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
||||||
|
(gpointer*)this );
|
||||||
|
|
||||||
|
if (!item->IsSubMenu())
|
||||||
|
{
|
||||||
|
gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
|
||||||
|
GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
|
||||||
|
(gpointer*)this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
||||||
|
gtk_widget_show( menuItem );
|
||||||
|
|
||||||
|
item->SetMenuItem(menuItem);
|
||||||
|
}
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
bool wxMenu::DoInsert(size_t pos, wxMenuItem *item)
|
||||||
|
{
|
||||||
|
if ( !wxMenuBase::DoInsert(pos, item) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
wxFAIL_MSG(wxT("not implemented"));
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
|
||||||
|
{
|
||||||
|
if ( !wxMenuBase::DoRemove(item) )
|
||||||
|
return (wxMenuItem *)NULL;
|
||||||
|
|
||||||
|
// TODO: this code doesn't delete the item factory item and this seems
|
||||||
|
// impossible as of GTK 1.2.6.
|
||||||
|
gtk_widget_destroy( item->GetMenuItem() );
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wxMenu::FindMenuIdByMenuItem( GtkWidget *menuItem ) const
|
||||||
|
{
|
||||||
|
wxNode *node = m_items.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxMenuItem *item = (wxMenuItem*)node->Data();
|
||||||
|
if (item->GetMenuItem() == menuItem)
|
||||||
|
return item->GetId();
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxNOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// helpers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if (GTK_MINOR_VERSION > 0) && wxUSE_ACCEL
|
#if (GTK_MINOR_VERSION > 0) && wxUSE_ACCEL
|
||||||
static wxString GetHotKey( const wxMenuItem& item )
|
static wxString GetHotKey( const wxMenuItem& item )
|
||||||
{
|
{
|
||||||
wxString hotkey;
|
wxString hotkey;
|
||||||
|
|
||||||
// as wxGetAccelFromString() looks for TAB, insert a dummy one here
|
wxAcceleratorEntry *accel = item.GetAccel();
|
||||||
wxString label;
|
|
||||||
label << wxT('\t') << item.GetHotKey();
|
|
||||||
|
|
||||||
// but if the hotkey is empty don't do anything
|
|
||||||
if ( label.length() > 1 )
|
|
||||||
{
|
|
||||||
wxAcceleratorEntry *accel = wxGetAccelFromString(label);
|
|
||||||
if ( accel )
|
if ( accel )
|
||||||
{
|
{
|
||||||
int flags = accel->GetFlags();
|
int flags = accel->GetFlags();
|
||||||
@@ -835,361 +1006,8 @@ static wxString GetHotKey( const wxMenuItem& item )
|
|||||||
|
|
||||||
delete accel;
|
delete accel;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return hotkey;
|
return hotkey;
|
||||||
}
|
}
|
||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool checkable )
|
|
||||||
{
|
|
||||||
wxMenuItem *mitem = new wxMenuItem(this, id, item, helpStr, checkable);
|
|
||||||
|
|
||||||
#if (GTK_MINOR_VERSION > 0)
|
|
||||||
/* text has "_" instead of "&" after mitem->SetText() */
|
|
||||||
wxString text( mitem->GetText() );
|
|
||||||
|
|
||||||
/* local buffer in multibyte form */
|
|
||||||
char buf[200];
|
|
||||||
strcpy( buf, "/" );
|
|
||||||
strcat( buf, text.mb_str() );
|
|
||||||
|
|
||||||
GtkItemFactoryEntry entry;
|
|
||||||
entry.path = buf;
|
|
||||||
entry.callback = (GtkItemFactoryCallback) gtk_menu_clicked_callback;
|
|
||||||
entry.callback_action = 0;
|
|
||||||
if (checkable)
|
|
||||||
entry.item_type = "<CheckItem>";
|
|
||||||
else
|
|
||||||
entry.item_type = "<Item>";
|
|
||||||
|
|
||||||
#if wxUSE_ACCEL
|
|
||||||
// due to an apparent bug in GTK+, we have to use a static buffer here -
|
|
||||||
// otherwise GTK+ 1.2.2 manages to override the memory we pass to it
|
|
||||||
// somehow! (VZ)
|
|
||||||
static char s_accel[32]; // must be big enough for <control><alt><shift>F12
|
|
||||||
strncpy(s_accel, GetHotKey(*mitem).mb_str(), WXSIZEOF(s_accel));
|
|
||||||
entry.accelerator = s_accel;
|
|
||||||
#else
|
|
||||||
entry.accelerator = (char*) NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
|
||||||
|
|
||||||
wxString path( mitem->GetFactoryPath() );
|
|
||||||
GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, path.mb_str() );
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
GtkWidget *menuItem = checkable ? gtk_check_menu_item_new_with_label( mitem->GetText().mb_str() )
|
|
||||||
: gtk_menu_item_new_with_label( mitem->GetText().mb_str() );
|
|
||||||
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
|
|
||||||
(gpointer)this );
|
|
||||||
|
|
||||||
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
|
||||||
gtk_widget_show( menuItem );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
|
||||||
(gpointer)this );
|
|
||||||
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
|
||||||
(gpointer)this );
|
|
||||||
|
|
||||||
mitem->SetMenuItem(menuItem);
|
|
||||||
|
|
||||||
m_items.Append( mitem );
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::Append( int id, const wxString &item, wxMenu *subMenu, const wxString &helpStr )
|
|
||||||
{
|
|
||||||
wxMenuItem *mitem = new wxMenuItem(this, id, item, helpStr, FALSE, subMenu);
|
|
||||||
|
|
||||||
#if (GTK_MINOR_VERSION > 0)
|
|
||||||
/* text has "_" instead of "&" after mitem->SetText() */
|
|
||||||
wxString text( mitem->GetText() );
|
|
||||||
|
|
||||||
/* local buffer in multibyte form */
|
|
||||||
char buf[200];
|
|
||||||
strcpy( buf, "/" );
|
|
||||||
strcat( buf, text.mb_str() );
|
|
||||||
|
|
||||||
GtkItemFactoryEntry entry;
|
|
||||||
entry.path = buf;
|
|
||||||
entry.callback = (GtkItemFactoryCallback) 0;
|
|
||||||
entry.callback_action = 0;
|
|
||||||
entry.item_type = "<Branch>";
|
|
||||||
|
|
||||||
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
|
||||||
|
|
||||||
wxString path( mitem->GetFactoryPath() );
|
|
||||||
GtkWidget *menuItem = gtk_item_factory_get_item( m_factory, path.mb_str() );
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
GtkWidget *menuItem = gtk_menu_item_new_with_label(mitem->GetText().mbc_str());
|
|
||||||
|
|
||||||
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
|
||||||
gtk_widget_show( menuItem );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
|
||||||
(gpointer*)this );
|
|
||||||
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
|
||||||
(gpointer*)this );
|
|
||||||
|
|
||||||
gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), subMenu->m_menu );
|
|
||||||
|
|
||||||
mitem->SetMenuItem(menuItem);
|
|
||||||
|
|
||||||
m_items.Append( mitem );
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::Append( wxMenuItem *item )
|
|
||||||
{
|
|
||||||
m_items.Append( item );
|
|
||||||
|
|
||||||
GtkWidget *menuItem = (GtkWidget*) NULL;
|
|
||||||
|
|
||||||
if (item->IsSeparator())
|
|
||||||
menuItem = gtk_menu_item_new();
|
|
||||||
else if (item->IsSubMenu())
|
|
||||||
menuItem = gtk_menu_item_new_with_label(item->GetText().mbc_str());
|
|
||||||
else
|
|
||||||
menuItem = item->IsCheckable() ? gtk_check_menu_item_new_with_label(item->GetText().mbc_str())
|
|
||||||
: gtk_menu_item_new_with_label(item->GetText().mbc_str());
|
|
||||||
|
|
||||||
if (!item->IsSeparator())
|
|
||||||
{
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
|
||||||
(gpointer*)this );
|
|
||||||
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
|
||||||
(gpointer*)this );
|
|
||||||
|
|
||||||
if (!item->IsSubMenu())
|
|
||||||
{
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
|
|
||||||
(gpointer*)this );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
|
||||||
gtk_widget_show( menuItem );
|
|
||||||
item->SetMenuItem(menuItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::Delete( int id )
|
|
||||||
{
|
|
||||||
wxNode *node = m_items.First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
|
||||||
if (item->GetId() == id)
|
|
||||||
{
|
|
||||||
/* TODO: this code doesn't delete the item factory item and
|
|
||||||
this seems impossible as of GTK 1.2.6. */
|
|
||||||
gtk_widget_destroy( item->GetMenuItem() );
|
|
||||||
m_items.DeleteNode( node );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxMenu::FindItem( const wxString itemString ) const
|
|
||||||
{
|
|
||||||
wxString s = wxT("");
|
|
||||||
for ( const wxChar *pc = itemString; *pc != wxT('\0'); pc++ )
|
|
||||||
{
|
|
||||||
if (*pc == wxT('&'))
|
|
||||||
{
|
|
||||||
pc++; /* skip it */
|
|
||||||
#if (GTK_MINOR_VERSION > 0)
|
|
||||||
s << wxT('_');
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
s << *pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxNode *node = m_items.First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
|
||||||
if (item->GetText() == s)
|
|
||||||
{
|
|
||||||
return item->GetId();
|
|
||||||
}
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxNOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::Enable( int id, bool enable )
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_RET( item, wxT("wxMenu::Enable: no such item") );
|
|
||||||
|
|
||||||
item->Enable(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxMenu::IsEnabled( int id ) const
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_MSG( item, FALSE, wxT("wxMenu::IsEnabled: no such item") );
|
|
||||||
|
|
||||||
return item->IsEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::Check( int id, bool enable )
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_RET( item, wxT("wxMenu::Check: no such item") );
|
|
||||||
|
|
||||||
item->Check(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxMenu::IsChecked( int id ) const
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_MSG( item, FALSE, wxT("wxMenu::IsChecked: no such item") );
|
|
||||||
|
|
||||||
return item->IsChecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::SetLabel( int id, const wxString &label )
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_RET( item, wxT("wxMenu::SetLabel: no such item") );
|
|
||||||
|
|
||||||
item->SetText(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxMenu::GetLabel( int id ) const
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_MSG( item, wxT(""), wxT("wxMenu::GetLabel: no such item") );
|
|
||||||
|
|
||||||
return item->GetText();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::SetHelpString( int id, const wxString& helpString )
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_RET( item, wxT("wxMenu::SetHelpString: no such item") );
|
|
||||||
|
|
||||||
item->SetHelp( helpString );
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxMenu::GetHelpString( int id ) const
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_MSG( item, wxT(""), wxT("wxMenu::GetHelpString: no such item") );
|
|
||||||
|
|
||||||
return item->GetHelp();
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxMenu::FindMenuIdByMenuItem( GtkWidget *menuItem ) const
|
|
||||||
{
|
|
||||||
wxNode *node = m_items.First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
|
||||||
if (item->GetMenuItem() == menuItem)
|
|
||||||
return item->GetId();
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxNOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxMenuItem *wxMenu::FindItem(int id) const
|
|
||||||
{
|
|
||||||
wxNode *node = m_items.First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
|
||||||
if (item->GetId() == id)
|
|
||||||
{
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Not finding anything here can be correct
|
|
||||||
* when search the entire menu system for
|
|
||||||
* an entry -> no error message. */
|
|
||||||
|
|
||||||
return (wxMenuItem *) NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::SetInvokingWindow( wxWindow *win )
|
|
||||||
{
|
|
||||||
m_invokingWindow = win;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxWindow *wxMenu::GetInvokingWindow()
|
|
||||||
{
|
|
||||||
return m_invokingWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update a menu and all submenus recursively. source is the object that has
|
|
||||||
// the update event handlers defined for it. If NULL, the menu or associated
|
|
||||||
// window will be used.
|
|
||||||
void wxMenu::UpdateUI(wxEvtHandler* source)
|
|
||||||
{
|
|
||||||
if (!source && GetInvokingWindow())
|
|
||||||
source = GetInvokingWindow()->GetEventHandler();
|
|
||||||
if (!source)
|
|
||||||
source = GetEventHandler();
|
|
||||||
if (!source)
|
|
||||||
source = this;
|
|
||||||
|
|
||||||
wxNode* node = GetItems().First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem* item = (wxMenuItem*) node->Data();
|
|
||||||
if ( !item->IsSeparator() )
|
|
||||||
{
|
|
||||||
wxWindowID id = item->GetId();
|
|
||||||
wxUpdateUIEvent event(id);
|
|
||||||
event.SetEventObject( source );
|
|
||||||
|
|
||||||
if (source->ProcessEvent(event))
|
|
||||||
{
|
|
||||||
if (event.GetSetText())
|
|
||||||
SetLabel(id, event.GetText());
|
|
||||||
if (event.GetSetChecked())
|
|
||||||
Check(id, event.GetChecked());
|
|
||||||
if (event.GetSetEnabled())
|
|
||||||
Enable(id, event.GetEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item->GetSubMenu())
|
|
||||||
item->GetSubMenu()->UpdateUI(source);
|
|
||||||
}
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@@ -31,6 +31,10 @@
|
|||||||
extern void wxapp_install_idle_handler();
|
extern void wxapp_install_idle_handler();
|
||||||
extern bool g_isIdle;
|
extern bool g_isIdle;
|
||||||
|
|
||||||
|
#if (GTK_MINOR_VERSION > 0) && wxUSE_ACCEL
|
||||||
|
static wxString GetHotKey( const wxMenuItem& item );
|
||||||
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// wxMenuBar
|
// wxMenuBar
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -355,7 +359,7 @@ int wxMenuBar::FindMenuItem( const wxString &menuString, const wxString &itemStr
|
|||||||
// Find a wxMenuItem using its id. Recurses down into sub-menus
|
// Find a wxMenuItem using its id. Recurses down into sub-menus
|
||||||
static wxMenuItem* FindMenuItemByIdRecursive(const wxMenu* menu, int id)
|
static wxMenuItem* FindMenuItemByIdRecursive(const wxMenu* menu, int id)
|
||||||
{
|
{
|
||||||
wxMenuItem* result = menu->FindItem(id);
|
wxMenuItem* result = menu->FindChildItem(id);
|
||||||
|
|
||||||
wxNode *node = ((wxMenu *)menu)->GetItems().First(); // const_cast
|
wxNode *node = ((wxMenu *)menu)->GetItems().First(); // const_cast
|
||||||
while ( node && result == NULL )
|
while ( node && result == NULL )
|
||||||
@@ -440,7 +444,7 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu )
|
|||||||
if (!menu->IsEnabled(id))
|
if (!menu->IsEnabled(id))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxMenuItem* item = menu->FindItem( id );
|
wxMenuItem* item = menu->FindChildItem( id );
|
||||||
wxCHECK_RET( item, wxT("error in menu item callback") );
|
wxCHECK_RET( item, wxT("error in menu item callback") );
|
||||||
|
|
||||||
if (item->IsCheckable())
|
if (item->IsCheckable())
|
||||||
@@ -569,6 +573,28 @@ wxMenuItem::~wxMenuItem()
|
|||||||
// don't delete menu items, the menus take care of that
|
// don't delete menu items, the menus take care of that
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return the menu item text without any menu accels
|
||||||
|
wxString wxMenuItem::GetLabel() const
|
||||||
|
{
|
||||||
|
wxString label;
|
||||||
|
#if (GTK_MINOR_VERSION > 0)
|
||||||
|
for ( const wxChar *pc = m_text.c_str(); *pc; pc++ )
|
||||||
|
{
|
||||||
|
if ( *pc == wxT('_') )
|
||||||
|
{
|
||||||
|
// this is the escape character for GTK+ - skip it
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
label += *pc;
|
||||||
|
}
|
||||||
|
#else // GTK+ 1.0
|
||||||
|
label = m_text;
|
||||||
|
#endif // GTK+ 1.2/1.0
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
void wxMenuItem::SetText( const wxString& str )
|
void wxMenuItem::SetText( const wxString& str )
|
||||||
{
|
{
|
||||||
DoSetText(str);
|
DoSetText(str);
|
||||||
@@ -623,6 +649,25 @@ void wxMenuItem::DoSetText( const wxString& str )
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
|
||||||
|
wxAcceleratorEntry *wxMenuItem::GetAccel() const
|
||||||
|
{
|
||||||
|
if ( !item.GetHotKey() )
|
||||||
|
{
|
||||||
|
// nothing
|
||||||
|
return (wxAcceleratorEntry *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// as wxGetAccelFromString() looks for TAB, insert a dummy one here
|
||||||
|
wxString label;
|
||||||
|
label << wxT('\t') << item.GetHotKey();
|
||||||
|
|
||||||
|
return wxGetAccelFromString(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
void wxMenuItem::Check( bool check )
|
void wxMenuItem::Check( bool check )
|
||||||
{
|
{
|
||||||
wxCHECK_RET( m_menuItem, wxT("invalid menu item") );
|
wxCHECK_RET( m_menuItem, wxT("invalid menu item") );
|
||||||
@@ -658,11 +703,7 @@ wxString wxMenuItem::GetFactoryPath() const
|
|||||||
{
|
{
|
||||||
/* in order to get the pointer to the item we need the item text _without_ underscores */
|
/* in order to get the pointer to the item we need the item text _without_ underscores */
|
||||||
wxString path( wxT("<main>/") );
|
wxString path( wxT("<main>/") );
|
||||||
for ( const wxChar *pc = m_text; *pc != wxT('\0'); pc++ )
|
path += GetLabel();
|
||||||
{
|
|
||||||
while (*pc == wxT('_')) pc++; /* skip it */
|
|
||||||
path << *pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
@@ -673,17 +714,8 @@ wxString wxMenuItem::GetFactoryPath() const
|
|||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler)
|
IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler)
|
||||||
|
|
||||||
void
|
void wxMenu::Init()
|
||||||
wxMenu::Init( const wxString& title,
|
|
||||||
long style,
|
|
||||||
const wxFunction func
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
m_title = title;
|
|
||||||
m_items.DeleteContents( TRUE );
|
|
||||||
m_invokingWindow = (wxWindow *) NULL;
|
|
||||||
m_style = style;
|
|
||||||
|
|
||||||
#if (GTK_MINOR_VERSION > 0)
|
#if (GTK_MINOR_VERSION > 0)
|
||||||
m_accel = gtk_accel_group_new();
|
m_accel = gtk_accel_group_new();
|
||||||
m_factory = gtk_item_factory_new( GTK_TYPE_MENU, "<main>", m_accel );
|
m_factory = gtk_item_factory_new( GTK_TYPE_MENU, "<main>", m_accel );
|
||||||
@@ -692,18 +724,6 @@ wxMenu::Init( const wxString& title,
|
|||||||
m_menu = gtk_menu_new(); // Do not show!
|
m_menu = gtk_menu_new(); // Do not show!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_callback = func;
|
|
||||||
|
|
||||||
m_eventHandler = this;
|
|
||||||
m_clientData = (void*) NULL;
|
|
||||||
|
|
||||||
if (m_title.IsNull()) m_title = wxT("");
|
|
||||||
if (m_title != wxT(""))
|
|
||||||
{
|
|
||||||
Append(-2, m_title);
|
|
||||||
AppendSeparator();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_owner = (GtkWidget*) NULL;
|
m_owner = (GtkWidget*) NULL;
|
||||||
|
|
||||||
#if (GTK_MINOR_VERSION > 0)
|
#if (GTK_MINOR_VERSION > 0)
|
||||||
@@ -722,40 +742,30 @@ wxMenu::Init( const wxString& title,
|
|||||||
//GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, "<main>/tearoff" );
|
//GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, "<main>/tearoff" );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// append the title as the very first entry if we have it
|
||||||
|
if ( !!m_title )
|
||||||
|
{
|
||||||
|
Append(-2, m_title);
|
||||||
|
AppendSeparator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxMenu::~wxMenu()
|
wxMenu::~wxMenu()
|
||||||
{
|
{
|
||||||
wxNode *node = m_items.First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
|
||||||
wxMenu *submenu = item->GetSubMenu();
|
|
||||||
if (submenu)
|
|
||||||
delete submenu;
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_destroy( m_menu );
|
gtk_widget_destroy( m_menu );
|
||||||
|
|
||||||
gtk_object_unref( GTK_OBJECT(m_factory) );
|
gtk_object_unref( GTK_OBJECT(m_factory) );
|
||||||
|
|
||||||
|
// the menu items are deleted by the base class dtor
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenu::SetTitle( const wxString& title )
|
virtual bool wxMenu::DoAppend(wxMenuItem *mitem)
|
||||||
{
|
{
|
||||||
// TODO Waiting for something better
|
GtkWidget *menuItem;
|
||||||
m_title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString wxMenu::GetTitle() const
|
|
||||||
{
|
|
||||||
return m_title;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::AppendSeparator()
|
|
||||||
{
|
|
||||||
wxMenuItem *mitem = new wxMenuItem(this, wxID_SEPARATOR);
|
|
||||||
|
|
||||||
|
if ( mitem->IsSeparator() )
|
||||||
|
{
|
||||||
#if (GTK_MINOR_VERSION > 0)
|
#if (GTK_MINOR_VERSION > 0)
|
||||||
GtkItemFactoryEntry entry;
|
GtkItemFactoryEntry entry;
|
||||||
entry.path = "/sep";
|
entry.path = "/sep";
|
||||||
@@ -767,30 +777,191 @@ void wxMenu::AppendSeparator()
|
|||||||
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
||||||
|
|
||||||
/* this will be wrong for more than one separator. do we care? */
|
/* this will be wrong for more than one separator. do we care? */
|
||||||
GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, "<main>/sep" );
|
menuItem = gtk_item_factory_get_widget( m_factory, "<main>/sep" );
|
||||||
#else
|
#else // GTK+ 1.0
|
||||||
GtkWidget *menuItem = gtk_menu_item_new();
|
menuItem = gtk_menu_item_new();
|
||||||
|
#endif // GTK 1.2/1.0
|
||||||
|
}
|
||||||
|
else if ( mitem->IsSubMenu() )
|
||||||
|
{
|
||||||
|
#if (GTK_MINOR_VERSION > 0)
|
||||||
|
/* text has "_" instead of "&" after mitem->SetText() */
|
||||||
|
wxString text( mitem->GetText() );
|
||||||
|
|
||||||
|
/* local buffer in multibyte form */
|
||||||
|
char buf[200];
|
||||||
|
strcpy( buf, "/" );
|
||||||
|
strcat( buf, text.mb_str() );
|
||||||
|
|
||||||
|
GtkItemFactoryEntry entry;
|
||||||
|
entry.path = buf;
|
||||||
|
entry.callback = (GtkItemFactoryCallback) 0;
|
||||||
|
entry.callback_action = 0;
|
||||||
|
entry.item_type = "<Branch>";
|
||||||
|
|
||||||
|
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
||||||
|
|
||||||
|
wxString path( mitem->GetFactoryPath() );
|
||||||
|
GtkWidget *menuItem = gtk_item_factory_get_item( m_factory, path.mb_str() );
|
||||||
|
#else // GTK+ 1.0
|
||||||
|
GtkWidget *menuItem = gtk_menu_item_new_with_label(mitem->GetText().mbc_str());
|
||||||
|
#endif // GTK 1.2/1.0
|
||||||
|
|
||||||
|
gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), subMenu->m_menu );
|
||||||
|
}
|
||||||
|
else // a normal item
|
||||||
|
{
|
||||||
|
#if (GTK_MINOR_VERSION > 0)
|
||||||
|
/* text has "_" instead of "&" after mitem->SetText() */
|
||||||
|
wxString text( mitem->GetText() );
|
||||||
|
|
||||||
|
/* local buffer in multibyte form */
|
||||||
|
char buf[200];
|
||||||
|
strcpy( buf, "/" );
|
||||||
|
strcat( buf, text.mb_str() );
|
||||||
|
|
||||||
|
GtkItemFactoryEntry entry;
|
||||||
|
entry.path = buf;
|
||||||
|
entry.callback = (GtkItemFactoryCallback) gtk_menu_clicked_callback;
|
||||||
|
entry.callback_action = 0;
|
||||||
|
if (checkable)
|
||||||
|
entry.item_type = "<CheckItem>";
|
||||||
|
else
|
||||||
|
entry.item_type = "<Item>";
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
// due to an apparent bug in GTK+, we have to use a static buffer here -
|
||||||
|
// otherwise GTK+ 1.2.2 manages to override the memory we pass to it
|
||||||
|
// somehow! (VZ)
|
||||||
|
static char s_accel[32]; // must be big enough for <control><alt><shift>F12
|
||||||
|
strncpy(s_accel, GetHotKey(*mitem).mb_str(), WXSIZEOF(s_accel));
|
||||||
|
entry.accelerator = s_accel;
|
||||||
|
#else // !wxUSE_ACCEL
|
||||||
|
entry.accelerator = (char*) NULL;
|
||||||
|
#endif // wxUSE_ACCEL/!wxUSE_ACCEL
|
||||||
|
|
||||||
|
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
||||||
|
|
||||||
|
wxString path( mitem->GetFactoryPath() );
|
||||||
|
GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, path.mb_str() );
|
||||||
|
#else // GTK+ 1.0
|
||||||
|
GtkWidget *menuItem = checkable ? gtk_check_menu_item_new_with_label( mitem->GetText().mb_str() )
|
||||||
|
: gtk_menu_item_new_with_label( mitem->GetText().mb_str() );
|
||||||
|
|
||||||
|
gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
|
||||||
|
GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
|
||||||
|
(gpointer)this );
|
||||||
|
#endif // GTK+ 1.2/1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !mitem->IsSeparator() )
|
||||||
|
{
|
||||||
|
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
||||||
|
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
||||||
|
(gpointer)this );
|
||||||
|
|
||||||
|
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
||||||
|
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
||||||
|
(gpointer)this );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GTK_MINOR_VERSION == 0
|
||||||
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
||||||
gtk_widget_show( menuItem );
|
gtk_widget_show( menuItem );
|
||||||
#endif
|
#endif // GTK+ 1.0
|
||||||
|
|
||||||
mitem->SetMenuItem(menuItem);
|
mitem->SetMenuItem(menuItem);
|
||||||
m_items.Append( mitem );
|
|
||||||
|
return wxMenuBase::DoAppend(mitem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VZ: this seems to be GTK+ 1.0 only code, I don't understand why there were
|
||||||
|
// both specialized versions of Append() and this one before my changes,
|
||||||
|
// but it seems that the others are better...
|
||||||
|
#if 0
|
||||||
|
void wxMenu::Append( wxMenuItem *item )
|
||||||
|
{
|
||||||
|
GtkWidget *menuItem = (GtkWidget*) NULL;
|
||||||
|
|
||||||
|
if (item->IsSeparator())
|
||||||
|
menuItem = gtk_menu_item_new();
|
||||||
|
else if (item->IsSubMenu())
|
||||||
|
menuItem = gtk_menu_item_new_with_label(item->GetText().mbc_str());
|
||||||
|
else
|
||||||
|
menuItem = item->IsCheckable() ? gtk_check_menu_item_new_with_label(item->GetText().mbc_str())
|
||||||
|
: gtk_menu_item_new_with_label(item->GetText().mbc_str());
|
||||||
|
|
||||||
|
if (!item->IsSeparator())
|
||||||
|
{
|
||||||
|
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
||||||
|
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
||||||
|
(gpointer*)this );
|
||||||
|
|
||||||
|
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
||||||
|
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
||||||
|
(gpointer*)this );
|
||||||
|
|
||||||
|
if (!item->IsSubMenu())
|
||||||
|
{
|
||||||
|
gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
|
||||||
|
GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
|
||||||
|
(gpointer*)this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
||||||
|
gtk_widget_show( menuItem );
|
||||||
|
|
||||||
|
item->SetMenuItem(menuItem);
|
||||||
|
}
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
|
bool wxMenu::DoInsert(size_t pos, wxMenuItem *item)
|
||||||
|
{
|
||||||
|
if ( !wxMenuBase::DoInsert(pos, item) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
wxFAIL_MSG(wxT("not implemented"));
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
|
||||||
|
{
|
||||||
|
if ( !wxMenuBase::DoRemove(item) )
|
||||||
|
return (wxMenuItem *)NULL;
|
||||||
|
|
||||||
|
// TODO: this code doesn't delete the item factory item and this seems
|
||||||
|
// impossible as of GTK 1.2.6.
|
||||||
|
gtk_widget_destroy( item->GetMenuItem() );
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wxMenu::FindMenuIdByMenuItem( GtkWidget *menuItem ) const
|
||||||
|
{
|
||||||
|
wxNode *node = m_items.First();
|
||||||
|
while (node)
|
||||||
|
{
|
||||||
|
wxMenuItem *item = (wxMenuItem*)node->Data();
|
||||||
|
if (item->GetMenuItem() == menuItem)
|
||||||
|
return item->GetId();
|
||||||
|
node = node->Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxNOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// helpers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if (GTK_MINOR_VERSION > 0) && wxUSE_ACCEL
|
#if (GTK_MINOR_VERSION > 0) && wxUSE_ACCEL
|
||||||
static wxString GetHotKey( const wxMenuItem& item )
|
static wxString GetHotKey( const wxMenuItem& item )
|
||||||
{
|
{
|
||||||
wxString hotkey;
|
wxString hotkey;
|
||||||
|
|
||||||
// as wxGetAccelFromString() looks for TAB, insert a dummy one here
|
wxAcceleratorEntry *accel = item.GetAccel();
|
||||||
wxString label;
|
|
||||||
label << wxT('\t') << item.GetHotKey();
|
|
||||||
|
|
||||||
// but if the hotkey is empty don't do anything
|
|
||||||
if ( label.length() > 1 )
|
|
||||||
{
|
|
||||||
wxAcceleratorEntry *accel = wxGetAccelFromString(label);
|
|
||||||
if ( accel )
|
if ( accel )
|
||||||
{
|
{
|
||||||
int flags = accel->GetFlags();
|
int flags = accel->GetFlags();
|
||||||
@@ -835,361 +1006,8 @@ static wxString GetHotKey( const wxMenuItem& item )
|
|||||||
|
|
||||||
delete accel;
|
delete accel;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return hotkey;
|
return hotkey;
|
||||||
}
|
}
|
||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
void wxMenu::Append( int id, const wxString &item, const wxString &helpStr, bool checkable )
|
|
||||||
{
|
|
||||||
wxMenuItem *mitem = new wxMenuItem(this, id, item, helpStr, checkable);
|
|
||||||
|
|
||||||
#if (GTK_MINOR_VERSION > 0)
|
|
||||||
/* text has "_" instead of "&" after mitem->SetText() */
|
|
||||||
wxString text( mitem->GetText() );
|
|
||||||
|
|
||||||
/* local buffer in multibyte form */
|
|
||||||
char buf[200];
|
|
||||||
strcpy( buf, "/" );
|
|
||||||
strcat( buf, text.mb_str() );
|
|
||||||
|
|
||||||
GtkItemFactoryEntry entry;
|
|
||||||
entry.path = buf;
|
|
||||||
entry.callback = (GtkItemFactoryCallback) gtk_menu_clicked_callback;
|
|
||||||
entry.callback_action = 0;
|
|
||||||
if (checkable)
|
|
||||||
entry.item_type = "<CheckItem>";
|
|
||||||
else
|
|
||||||
entry.item_type = "<Item>";
|
|
||||||
|
|
||||||
#if wxUSE_ACCEL
|
|
||||||
// due to an apparent bug in GTK+, we have to use a static buffer here -
|
|
||||||
// otherwise GTK+ 1.2.2 manages to override the memory we pass to it
|
|
||||||
// somehow! (VZ)
|
|
||||||
static char s_accel[32]; // must be big enough for <control><alt><shift>F12
|
|
||||||
strncpy(s_accel, GetHotKey(*mitem).mb_str(), WXSIZEOF(s_accel));
|
|
||||||
entry.accelerator = s_accel;
|
|
||||||
#else
|
|
||||||
entry.accelerator = (char*) NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
|
||||||
|
|
||||||
wxString path( mitem->GetFactoryPath() );
|
|
||||||
GtkWidget *menuItem = gtk_item_factory_get_widget( m_factory, path.mb_str() );
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
GtkWidget *menuItem = checkable ? gtk_check_menu_item_new_with_label( mitem->GetText().mb_str() )
|
|
||||||
: gtk_menu_item_new_with_label( mitem->GetText().mb_str() );
|
|
||||||
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
|
|
||||||
(gpointer)this );
|
|
||||||
|
|
||||||
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
|
||||||
gtk_widget_show( menuItem );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
|
||||||
(gpointer)this );
|
|
||||||
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
|
||||||
(gpointer)this );
|
|
||||||
|
|
||||||
mitem->SetMenuItem(menuItem);
|
|
||||||
|
|
||||||
m_items.Append( mitem );
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::Append( int id, const wxString &item, wxMenu *subMenu, const wxString &helpStr )
|
|
||||||
{
|
|
||||||
wxMenuItem *mitem = new wxMenuItem(this, id, item, helpStr, FALSE, subMenu);
|
|
||||||
|
|
||||||
#if (GTK_MINOR_VERSION > 0)
|
|
||||||
/* text has "_" instead of "&" after mitem->SetText() */
|
|
||||||
wxString text( mitem->GetText() );
|
|
||||||
|
|
||||||
/* local buffer in multibyte form */
|
|
||||||
char buf[200];
|
|
||||||
strcpy( buf, "/" );
|
|
||||||
strcat( buf, text.mb_str() );
|
|
||||||
|
|
||||||
GtkItemFactoryEntry entry;
|
|
||||||
entry.path = buf;
|
|
||||||
entry.callback = (GtkItemFactoryCallback) 0;
|
|
||||||
entry.callback_action = 0;
|
|
||||||
entry.item_type = "<Branch>";
|
|
||||||
|
|
||||||
gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); /* what is 2 ? */
|
|
||||||
|
|
||||||
wxString path( mitem->GetFactoryPath() );
|
|
||||||
GtkWidget *menuItem = gtk_item_factory_get_item( m_factory, path.mb_str() );
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
GtkWidget *menuItem = gtk_menu_item_new_with_label(mitem->GetText().mbc_str());
|
|
||||||
|
|
||||||
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
|
||||||
gtk_widget_show( menuItem );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
|
||||||
(gpointer*)this );
|
|
||||||
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
|
||||||
(gpointer*)this );
|
|
||||||
|
|
||||||
gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), subMenu->m_menu );
|
|
||||||
|
|
||||||
mitem->SetMenuItem(menuItem);
|
|
||||||
|
|
||||||
m_items.Append( mitem );
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::Append( wxMenuItem *item )
|
|
||||||
{
|
|
||||||
m_items.Append( item );
|
|
||||||
|
|
||||||
GtkWidget *menuItem = (GtkWidget*) NULL;
|
|
||||||
|
|
||||||
if (item->IsSeparator())
|
|
||||||
menuItem = gtk_menu_item_new();
|
|
||||||
else if (item->IsSubMenu())
|
|
||||||
menuItem = gtk_menu_item_new_with_label(item->GetText().mbc_str());
|
|
||||||
else
|
|
||||||
menuItem = item->IsCheckable() ? gtk_check_menu_item_new_with_label(item->GetText().mbc_str())
|
|
||||||
: gtk_menu_item_new_with_label(item->GetText().mbc_str());
|
|
||||||
|
|
||||||
if (!item->IsSeparator())
|
|
||||||
{
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "select",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_hilight_callback),
|
|
||||||
(gpointer*)this );
|
|
||||||
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "deselect",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_nolight_callback),
|
|
||||||
(gpointer*)this );
|
|
||||||
|
|
||||||
if (!item->IsSubMenu())
|
|
||||||
{
|
|
||||||
gtk_signal_connect( GTK_OBJECT(menuItem), "activate",
|
|
||||||
GTK_SIGNAL_FUNC(gtk_menu_clicked_callback),
|
|
||||||
(gpointer*)this );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_menu_append( GTK_MENU(m_menu), menuItem );
|
|
||||||
gtk_widget_show( menuItem );
|
|
||||||
item->SetMenuItem(menuItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::Delete( int id )
|
|
||||||
{
|
|
||||||
wxNode *node = m_items.First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
|
||||||
if (item->GetId() == id)
|
|
||||||
{
|
|
||||||
/* TODO: this code doesn't delete the item factory item and
|
|
||||||
this seems impossible as of GTK 1.2.6. */
|
|
||||||
gtk_widget_destroy( item->GetMenuItem() );
|
|
||||||
m_items.DeleteNode( node );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxMenu::FindItem( const wxString itemString ) const
|
|
||||||
{
|
|
||||||
wxString s = wxT("");
|
|
||||||
for ( const wxChar *pc = itemString; *pc != wxT('\0'); pc++ )
|
|
||||||
{
|
|
||||||
if (*pc == wxT('&'))
|
|
||||||
{
|
|
||||||
pc++; /* skip it */
|
|
||||||
#if (GTK_MINOR_VERSION > 0)
|
|
||||||
s << wxT('_');
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
s << *pc;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxNode *node = m_items.First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
|
||||||
if (item->GetText() == s)
|
|
||||||
{
|
|
||||||
return item->GetId();
|
|
||||||
}
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxNOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::Enable( int id, bool enable )
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_RET( item, wxT("wxMenu::Enable: no such item") );
|
|
||||||
|
|
||||||
item->Enable(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxMenu::IsEnabled( int id ) const
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_MSG( item, FALSE, wxT("wxMenu::IsEnabled: no such item") );
|
|
||||||
|
|
||||||
return item->IsEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::Check( int id, bool enable )
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_RET( item, wxT("wxMenu::Check: no such item") );
|
|
||||||
|
|
||||||
item->Check(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxMenu::IsChecked( int id ) const
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_MSG( item, FALSE, wxT("wxMenu::IsChecked: no such item") );
|
|
||||||
|
|
||||||
return item->IsChecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::SetLabel( int id, const wxString &label )
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_RET( item, wxT("wxMenu::SetLabel: no such item") );
|
|
||||||
|
|
||||||
item->SetText(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxMenu::GetLabel( int id ) const
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_MSG( item, wxT(""), wxT("wxMenu::GetLabel: no such item") );
|
|
||||||
|
|
||||||
return item->GetText();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::SetHelpString( int id, const wxString& helpString )
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_RET( item, wxT("wxMenu::SetHelpString: no such item") );
|
|
||||||
|
|
||||||
item->SetHelp( helpString );
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxMenu::GetHelpString( int id ) const
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItem(id);
|
|
||||||
|
|
||||||
wxCHECK_MSG( item, wxT(""), wxT("wxMenu::GetHelpString: no such item") );
|
|
||||||
|
|
||||||
return item->GetHelp();
|
|
||||||
}
|
|
||||||
|
|
||||||
int wxMenu::FindMenuIdByMenuItem( GtkWidget *menuItem ) const
|
|
||||||
{
|
|
||||||
wxNode *node = m_items.First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
|
||||||
if (item->GetMenuItem() == menuItem)
|
|
||||||
return item->GetId();
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxNOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxMenuItem *wxMenu::FindItem(int id) const
|
|
||||||
{
|
|
||||||
wxNode *node = m_items.First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = (wxMenuItem*)node->Data();
|
|
||||||
if (item->GetId() == id)
|
|
||||||
{
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Not finding anything here can be correct
|
|
||||||
* when search the entire menu system for
|
|
||||||
* an entry -> no error message. */
|
|
||||||
|
|
||||||
return (wxMenuItem *) NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::SetInvokingWindow( wxWindow *win )
|
|
||||||
{
|
|
||||||
m_invokingWindow = win;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxWindow *wxMenu::GetInvokingWindow()
|
|
||||||
{
|
|
||||||
return m_invokingWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update a menu and all submenus recursively. source is the object that has
|
|
||||||
// the update event handlers defined for it. If NULL, the menu or associated
|
|
||||||
// window will be used.
|
|
||||||
void wxMenu::UpdateUI(wxEvtHandler* source)
|
|
||||||
{
|
|
||||||
if (!source && GetInvokingWindow())
|
|
||||||
source = GetInvokingWindow()->GetEventHandler();
|
|
||||||
if (!source)
|
|
||||||
source = GetEventHandler();
|
|
||||||
if (!source)
|
|
||||||
source = this;
|
|
||||||
|
|
||||||
wxNode* node = GetItems().First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem* item = (wxMenuItem*) node->Data();
|
|
||||||
if ( !item->IsSeparator() )
|
|
||||||
{
|
|
||||||
wxWindowID id = item->GetId();
|
|
||||||
wxUpdateUIEvent event(id);
|
|
||||||
event.SetEventObject( source );
|
|
||||||
|
|
||||||
if (source->ProcessEvent(event))
|
|
||||||
{
|
|
||||||
if (event.GetSetText())
|
|
||||||
SetLabel(id, event.GetText());
|
|
||||||
if (event.GetSetChecked())
|
|
||||||
Check(id, event.GetChecked());
|
|
||||||
if (event.GetSetEnabled())
|
|
||||||
Enable(id, event.GetEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item->GetSubMenu())
|
|
||||||
item->GetSubMenu()->UpdateUI(source);
|
|
||||||
}
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@@ -474,6 +474,8 @@ bool wxDialog::Show(bool show)
|
|||||||
if (hWndParent)
|
if (hWndParent)
|
||||||
::BringWindowToTop(hWndParent);
|
::BringWindowToTop(hWndParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( m_hWnd )
|
||||||
ShowWindow((HWND) GetHWND(), SW_HIDE);
|
ShowWindow((HWND) GetHWND(), SW_HIDE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -671,10 +671,9 @@ bool wxFrame::ProcessCommand(int id)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
wxMenuItem *item = bar->FindItemForId(id);
|
wxMenuItem *item = bar->FindItemForId(id);
|
||||||
|
|
||||||
if ( item && item->IsCheckable() )
|
if ( item && item->IsCheckable() )
|
||||||
{
|
{
|
||||||
bar->Check(id, !bar->IsChecked(id)) ;
|
item->Toggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
|
wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
|
||||||
|
574
src/msw/menu.cpp
574
src/msw/menu.cpp
@@ -33,6 +33,7 @@
|
|||||||
#include "wx/menu.h"
|
#include "wx/menu.h"
|
||||||
#include "wx/utils.h"
|
#include "wx/utils.h"
|
||||||
#include "wx/intl.h"
|
#include "wx/intl.h"
|
||||||
|
#include "wx/log.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if wxUSE_OWNER_DRAWN
|
#if wxUSE_OWNER_DRAWN
|
||||||
@@ -40,9 +41,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
#include "wx/msw/menu.h"
|
|
||||||
#include "wx/menuitem.h"
|
|
||||||
#include "wx/log.h"
|
|
||||||
|
|
||||||
// other standard headers
|
// other standard headers
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -78,33 +76,32 @@ static const int idMenuTitle = -2;
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Construct a menu with optional title (then use append)
|
// Construct a menu with optional title (then use append)
|
||||||
void wxMenu::Init(const wxString& title, const wxFunction func )
|
void wxMenu::Init()
|
||||||
{
|
{
|
||||||
m_title = title;
|
|
||||||
m_eventHandler = this;
|
|
||||||
m_pInvokingWindow = NULL;
|
|
||||||
m_doBreak = FALSE;
|
m_doBreak = FALSE;
|
||||||
m_noItems = 0;
|
|
||||||
m_menuBar = NULL;
|
|
||||||
m_hMenu = (WXHMENU) CreatePopupMenu();
|
|
||||||
m_savehMenu = 0;
|
|
||||||
m_topLevelMenu = this;
|
|
||||||
m_clientData = (void*) NULL;
|
|
||||||
|
|
||||||
|
// create the menu
|
||||||
|
m_hMenu = (WXHMENU)CreatePopupMenu();
|
||||||
|
if ( !m_hMenu )
|
||||||
|
{
|
||||||
|
wxLogLastError("CreatePopupMenu");
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have a title, insert it in the beginning of the menu
|
||||||
if ( !!m_title )
|
if ( !!m_title )
|
||||||
{
|
{
|
||||||
Append(idMenuTitle, m_title);
|
Append(idMenuTitle, m_title);
|
||||||
AppendSeparator();
|
AppendSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
Callback(func);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The wxWindow destructor will take care of deleting the submenus.
|
// The wxWindow destructor will take care of deleting the submenus.
|
||||||
wxMenu::~wxMenu()
|
wxMenu::~wxMenu()
|
||||||
{
|
{
|
||||||
// free Windows resources
|
// we should free Windows resources only if Windows doesn't do it for us
|
||||||
if ( m_hMenu )
|
// which happens if we're attached to a menubar or a submenu of another
|
||||||
|
// menu
|
||||||
|
if ( !IsAttached() && !GetParent() )
|
||||||
{
|
{
|
||||||
if ( !::DestroyMenu(GetHmenu()) )
|
if ( !::DestroyMenu(GetHmenu()) )
|
||||||
{
|
{
|
||||||
@@ -112,24 +109,6 @@ wxMenu::~wxMenu()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete submenus
|
|
||||||
wxNode *node = m_menuItems.First();
|
|
||||||
while ( node )
|
|
||||||
{
|
|
||||||
wxMenuItem *item = (wxMenuItem *)node->Data();
|
|
||||||
|
|
||||||
// Delete child menus.
|
|
||||||
// Beware: they must not be appended to children list!!!
|
|
||||||
// (because order of delete is significant)
|
|
||||||
if ( item->IsSubMenu() )
|
|
||||||
item->DeleteSubMenu();
|
|
||||||
|
|
||||||
wxNode *next = node->Next();
|
|
||||||
delete item;
|
|
||||||
delete node;
|
|
||||||
node = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if wxUSE_ACCEL
|
#if wxUSE_ACCEL
|
||||||
// delete accels
|
// delete accels
|
||||||
WX_CLEAR_ARRAY(m_accels);
|
WX_CLEAR_ARRAY(m_accels);
|
||||||
@@ -138,20 +117,64 @@ wxMenu::~wxMenu()
|
|||||||
|
|
||||||
void wxMenu::Break()
|
void wxMenu::Break()
|
||||||
{
|
{
|
||||||
|
// this will take effect during the next call to Append()
|
||||||
m_doBreak = TRUE;
|
m_doBreak = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// function appends a new item or submenu to the menu
|
|
||||||
void wxMenu::Append(wxMenuItem *pItem)
|
|
||||||
{
|
|
||||||
wxCHECK_RET( pItem != NULL, wxT("can't append NULL item to the menu") );
|
|
||||||
|
|
||||||
#if wxUSE_ACCEL
|
#if wxUSE_ACCEL
|
||||||
wxAcceleratorEntry *accel = wxGetAccelFromString(pItem->GetText());
|
|
||||||
if ( accel ) {
|
int wxMenu::FindAccel(int id) const
|
||||||
m_accels.Add(accel);
|
{
|
||||||
accel->m_command = pItem->GetId();
|
size_t n, count = m_accels.GetCount();
|
||||||
|
for ( n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
if ( m_accels[n]->m_command == id )
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return wxNOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxMenu::UpdateAccel(wxMenuItem *item)
|
||||||
|
{
|
||||||
|
// find the (new) accel for this item
|
||||||
|
wxAcceleratorEntry *accel = wxGetAccelFromString(item->GetText());
|
||||||
|
if ( accel )
|
||||||
|
accel->m_command = item->GetId();
|
||||||
|
|
||||||
|
// find the old one
|
||||||
|
int n = FindAccel(item->GetId());
|
||||||
|
if ( n == wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
// no old, add new if any
|
||||||
|
if ( accel )
|
||||||
|
m_accels.Add(accel);
|
||||||
|
else
|
||||||
|
return; // skipping RebuildAccelTable() below
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// replace old with new or just remove the old one if no new
|
||||||
|
delete m_accels[n];
|
||||||
|
if ( accel )
|
||||||
|
m_accels[n] = accel;
|
||||||
|
else
|
||||||
|
m_accels.Remove(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( IsAttached() )
|
||||||
|
{
|
||||||
|
m_menuBar->RebuildAccelTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
|
// append a new item or submenu to the menu
|
||||||
|
bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
|
||||||
|
{
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
UpdateAccel(pItem);
|
||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
UINT flags = 0;
|
UINT flags = 0;
|
||||||
@@ -172,12 +195,11 @@ void wxMenu::Append(wxMenuItem *pItem)
|
|||||||
UINT id;
|
UINT id;
|
||||||
wxMenu *submenu = pItem->GetSubMenu();
|
wxMenu *submenu = pItem->GetSubMenu();
|
||||||
if ( submenu != NULL ) {
|
if ( submenu != NULL ) {
|
||||||
wxASSERT( submenu->GetHMenu() != (WXHMENU) NULL );
|
wxASSERT_MSG( submenu->GetHMenu(), wxT("invalid submenu") );
|
||||||
|
|
||||||
|
submenu->SetParent(this);
|
||||||
|
|
||||||
id = (UINT)submenu->GetHMenu();
|
id = (UINT)submenu->GetHMenu();
|
||||||
submenu->m_topLevelMenu = m_topLevelMenu;
|
|
||||||
submenu->m_savehMenu = (WXHMENU)id;
|
|
||||||
submenu->m_hMenu = 0;
|
|
||||||
|
|
||||||
flags |= MF_POPUP;
|
flags |= MF_POPUP;
|
||||||
}
|
}
|
||||||
@@ -202,12 +224,25 @@ void wxMenu::Append(wxMenuItem *pItem)
|
|||||||
pData = (char*)pItem->GetText().c_str();
|
pData = (char*)pItem->GetText().c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !::AppendMenu(GetHmenu(), flags, id, pData) )
|
BOOL ok;
|
||||||
|
if ( pos == (size_t)-1 )
|
||||||
{
|
{
|
||||||
wxLogLastError("AppendMenu");
|
ok = ::AppendMenu(GetHmenu(), flags, id, pData);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
ok = ::InsertMenu(GetHmenu(), pos, flags | MF_BYPOSITION, id, pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !ok )
|
||||||
|
{
|
||||||
|
wxLogLastError("Insert or AppendMenu");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// if we just appended the title, highlight it
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
if ( (int)id == idMenuTitle )
|
if ( (int)id == idMenuTitle )
|
||||||
{
|
{
|
||||||
@@ -224,78 +259,76 @@ void wxMenu::Append(wxMenuItem *pItem)
|
|||||||
}
|
}
|
||||||
#endif // __WIN32__
|
#endif // __WIN32__
|
||||||
|
|
||||||
m_menuItems.Append(pItem);
|
// if we're already attached to the menubar, we must update it
|
||||||
m_noItems++;
|
if ( IsAttached() )
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::AppendSeparator()
|
|
||||||
{
|
|
||||||
Append(new wxMenuItem(this, ID_SEPARATOR));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pullright item
|
|
||||||
void wxMenu::Append(int id,
|
|
||||||
const wxString& label,
|
|
||||||
wxMenu *SubMenu,
|
|
||||||
const wxString& helpString)
|
|
||||||
{
|
|
||||||
Append(new wxMenuItem(this, id, label, helpString, FALSE, SubMenu));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ordinary menu item
|
|
||||||
void wxMenu::Append(int id,
|
|
||||||
const wxString& label,
|
|
||||||
const wxString& helpString,
|
|
||||||
bool checkable)
|
|
||||||
{
|
|
||||||
// 'checkable' parameter is useless for Windows.
|
|
||||||
Append(new wxMenuItem(this, id, label, helpString, checkable));
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete item by id
|
|
||||||
void wxMenu::Delete(int id)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = NULL;
|
|
||||||
int pos;
|
|
||||||
wxNode *node;
|
|
||||||
for (pos = 0, node = m_menuItems.First(); node; node = node->Next(), pos++)
|
|
||||||
{
|
{
|
||||||
item = (wxMenuItem *)node->Data();
|
m_menuBar->Refresh();
|
||||||
if ( item->GetId() == id )
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCHECK_RET( node, wxT("wxMenu::Delete(): item doesn't exist") );
|
return TRUE;
|
||||||
|
|
||||||
HMENU menu = GetHmenu();
|
|
||||||
|
|
||||||
wxMenu *pSubMenu = item->GetSubMenu();
|
|
||||||
if ( pSubMenu != NULL ) {
|
|
||||||
RemoveMenu(menu, (UINT)pos, MF_BYPOSITION);
|
|
||||||
pSubMenu->m_hMenu = pSubMenu->m_savehMenu;
|
|
||||||
pSubMenu->m_savehMenu = 0;
|
|
||||||
// RemoveChild(item->subMenu);
|
|
||||||
pSubMenu->m_topLevelMenu = NULL;
|
|
||||||
// TODO: Why isn't subMenu deleted here???
|
|
||||||
// Will put this in for now. Assuming this is supposed
|
|
||||||
// to delete the menu, not just remove it.
|
|
||||||
item->DeleteSubMenu();
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
DeleteMenu(menu, (UINT)pos, MF_BYPOSITION);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_menuItems.DeleteNode(node);
|
|
||||||
delete item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxMenu::DoAppend(wxMenuItem *item)
|
||||||
|
{
|
||||||
|
return wxMenuBase::DoAppend(item) && DoInsertOrAppend(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxMenu::DoInsert(size_t pos, wxMenuItem *item)
|
||||||
|
{
|
||||||
|
return wxMenuBase::DoInsert(pos, item) && DoInsertOrAppend(item, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
|
||||||
|
{
|
||||||
|
// we need to find the items position in the child list
|
||||||
|
size_t pos;
|
||||||
|
wxMenuItemList::Node *node = GetMenuItems().GetFirst();
|
||||||
|
for ( pos = 0; node; pos++ )
|
||||||
|
{
|
||||||
|
if ( node->GetData() == item )
|
||||||
|
break;
|
||||||
|
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoRemove() (unlike Remove) can only be called for existing item!
|
||||||
|
wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
|
||||||
|
|
||||||
#if wxUSE_ACCEL
|
#if wxUSE_ACCEL
|
||||||
|
// remove the corresponding accel from the accel table
|
||||||
|
int n = FindAccel(item->GetId());
|
||||||
|
if ( n != wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
delete m_accels[n];
|
||||||
|
|
||||||
|
m_accels.Remove(n);
|
||||||
|
}
|
||||||
|
//else: this item doesn't have an accel, nothing to do
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
|
// remove the item from the menu
|
||||||
|
if ( !::RemoveMenu(GetHmenu(), (UINT)pos, MF_BYPOSITION) )
|
||||||
|
{
|
||||||
|
wxLogLastError("RemoveMenu");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( IsAttached() )
|
||||||
|
{
|
||||||
|
// otherwise, the chane won't be visible
|
||||||
|
m_menuBar->Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
// and from internal data structures
|
||||||
|
return wxMenuBase::DoRemove(item);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// accelerator helpers
|
// accelerator helpers
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
|
||||||
// create the wxAcceleratorEntries for our accels and put them into provided
|
// create the wxAcceleratorEntries for our accels and put them into provided
|
||||||
// array - return the number of accels we have
|
// array - return the number of accels we have
|
||||||
size_t wxMenu::CopyAccels(wxAcceleratorEntry *accels) const
|
size_t wxMenu::CopyAccels(wxAcceleratorEntry *accels) const
|
||||||
@@ -312,84 +345,7 @@ size_t wxMenu::CopyAccels(wxAcceleratorEntry *accels) const
|
|||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// wxMenu functions implemented in wxMenuItem
|
// set wxMenu title
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void wxMenu::Enable(int id, bool Flag)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItemForId(id);
|
|
||||||
wxCHECK_RET( item != NULL, wxT("can't enable non-existing menu item") );
|
|
||||||
|
|
||||||
item->Enable(Flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxMenu::IsEnabled(int id) const
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItemForId(id);
|
|
||||||
wxCHECK_MSG( item != NULL, FALSE, wxT("invalid item id") );
|
|
||||||
|
|
||||||
return item->IsEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::Check(int id, bool Flag)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItemForId(id);
|
|
||||||
wxCHECK_RET( item != NULL, wxT("can't get status of non-existing menu item") );
|
|
||||||
|
|
||||||
item->Check(Flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxMenu::IsChecked(int id) const
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItemForId(id);
|
|
||||||
wxCHECK_MSG( item != NULL, FALSE, wxT("invalid item id") );
|
|
||||||
|
|
||||||
return item->IsChecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::SetLabel(int id, const wxString& label)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItemForId(id);
|
|
||||||
wxCHECK_RET( item, wxT("wxMenu::SetLabel: no such item") );
|
|
||||||
|
|
||||||
item->SetText(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxMenu::GetLabel(int id) const
|
|
||||||
{
|
|
||||||
wxString label;
|
|
||||||
wxMenuItem *pItem = FindItemForId(id);
|
|
||||||
if (pItem)
|
|
||||||
label = pItem->GetText();
|
|
||||||
else
|
|
||||||
wxFAIL_MSG(wxT("wxMenu::GetLabel: item doesn't exist"));
|
|
||||||
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxMenu::SetHelpString(int itemId, const wxString& helpString)
|
|
||||||
{
|
|
||||||
wxMenuItem *item = FindItemForId (itemId);
|
|
||||||
if (item)
|
|
||||||
item->SetHelp(helpString);
|
|
||||||
else
|
|
||||||
wxFAIL_MSG(wxT("wxMenu::SetHelpString: item doesn't exist"));
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString wxMenu::GetHelpString (int itemId) const
|
|
||||||
{
|
|
||||||
wxString help;
|
|
||||||
wxMenuItem *item = FindItemForId (itemId);
|
|
||||||
if (item)
|
|
||||||
help = item->GetHelp();
|
|
||||||
else
|
|
||||||
wxFAIL_MSG(wxT("wxMenu::GetHelpString: item doesn't exist"));
|
|
||||||
|
|
||||||
return help;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// wxMenu title
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
void wxMenu::SetTitle(const wxString& label)
|
void wxMenu::SetTitle(const wxString& label)
|
||||||
@@ -403,11 +359,11 @@ void wxMenu::SetTitle(const wxString& label)
|
|||||||
{
|
{
|
||||||
if ( !label.IsEmpty() )
|
if ( !label.IsEmpty() )
|
||||||
{
|
{
|
||||||
if ( !InsertMenu(hMenu, 0u, MF_BYPOSITION | MF_STRING,
|
if ( !::InsertMenu(hMenu, 0u, MF_BYPOSITION | MF_STRING,
|
||||||
(unsigned)idMenuTitle, m_title) ||
|
(unsigned)idMenuTitle, m_title) ||
|
||||||
!InsertMenu(hMenu, 1u, MF_BYPOSITION, (unsigned)-1, NULL) )
|
!::InsertMenu(hMenu, 1u, MF_BYPOSITION, (unsigned)-1, NULL) )
|
||||||
{
|
{
|
||||||
wxLogLastError(wxT("InsertMenu"));
|
wxLogLastError("InsertMenu");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,12 +404,7 @@ void wxMenu::SetTitle(const wxString& label)
|
|||||||
wxLogLastError("SetMenuItemInfo");
|
wxLogLastError("SetMenuItemInfo");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif // Win32
|
||||||
}
|
|
||||||
|
|
||||||
const wxString wxMenu::GetTitle() const
|
|
||||||
{
|
|
||||||
return m_title;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -481,12 +432,14 @@ bool wxMenu::ProcessCommand(wxCommandEvent & event)
|
|||||||
{
|
{
|
||||||
bool processed = FALSE;
|
bool processed = FALSE;
|
||||||
|
|
||||||
|
#if WXWIN_COMPATIBILITY
|
||||||
// Try a callback
|
// Try a callback
|
||||||
if (m_callback)
|
if (m_callback)
|
||||||
{
|
{
|
||||||
(void)(*(m_callback))(*this, event);
|
(void)(*(m_callback))(*this, event);
|
||||||
processed = TRUE;
|
processed = TRUE;
|
||||||
}
|
}
|
||||||
|
#endif WXWIN_COMPATIBILITY
|
||||||
|
|
||||||
// Try the menu's event handler
|
// Try the menu's event handler
|
||||||
if ( !processed && GetEventHandler())
|
if ( !processed && GetEventHandler())
|
||||||
@@ -503,63 +456,6 @@ bool wxMenu::ProcessCommand(wxCommandEvent & event)
|
|||||||
return processed;
|
return processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// Item search
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Finds the item id matching the given string, -1 if not found.
|
|
||||||
int wxMenu::FindItem (const wxString& itemString) const
|
|
||||||
{
|
|
||||||
wxString itemLabel = wxStripMenuCodes(itemString);
|
|
||||||
for ( wxNode *node = m_menuItems.First(); node; node = node->Next() )
|
|
||||||
{
|
|
||||||
wxMenuItem *item = (wxMenuItem *)node->Data();
|
|
||||||
if ( item->IsSubMenu() )
|
|
||||||
{
|
|
||||||
int ans = item->GetSubMenu()->FindItem(itemString);
|
|
||||||
if ( ans != wxNOT_FOUND )
|
|
||||||
return ans;
|
|
||||||
}
|
|
||||||
else if ( !item->IsSeparator() )
|
|
||||||
{
|
|
||||||
wxString label = wxStripMenuCodes(item->GetText());
|
|
||||||
if ( itemLabel == label )
|
|
||||||
return item->GetId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return wxNOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxMenuItem *wxMenu::FindItemForId(int itemId, wxMenu ** itemMenu) const
|
|
||||||
{
|
|
||||||
if ( itemMenu )
|
|
||||||
*itemMenu = NULL;
|
|
||||||
|
|
||||||
wxMenuItem *item = NULL;
|
|
||||||
for ( wxNode *node = m_menuItems.First(); node && !item; node = node->Next() )
|
|
||||||
{
|
|
||||||
item = (wxMenuItem *)node->Data();
|
|
||||||
|
|
||||||
if ( item->GetId() == itemId )
|
|
||||||
{
|
|
||||||
if (itemMenu)
|
|
||||||
*itemMenu = (wxMenu *)this;
|
|
||||||
}
|
|
||||||
else if ( item->IsSubMenu() )
|
|
||||||
{
|
|
||||||
item = item->GetSubMenu()->FindItemForId(itemId, itemMenu);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// don't exit the loop
|
|
||||||
item = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// other
|
// other
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -571,8 +467,6 @@ void wxMenu::Attach(wxMenuBar *menubar)
|
|||||||
wxASSERT_MSG( !m_menuBar, wxT("menu belongs to 2 menubars, expect a crash") );
|
wxASSERT_MSG( !m_menuBar, wxT("menu belongs to 2 menubars, expect a crash") );
|
||||||
|
|
||||||
m_menuBar = menubar;
|
m_menuBar = menubar;
|
||||||
m_savehMenu = m_hMenu;
|
|
||||||
m_hMenu = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenu::Detach()
|
void wxMenu::Detach()
|
||||||
@@ -580,8 +474,16 @@ void wxMenu::Detach()
|
|||||||
wxASSERT_MSG( m_menuBar, wxT("can't detach menu if it's not attached") );
|
wxASSERT_MSG( m_menuBar, wxT("can't detach menu if it's not attached") );
|
||||||
|
|
||||||
m_menuBar = NULL;
|
m_menuBar = NULL;
|
||||||
m_hMenu = m_savehMenu;
|
}
|
||||||
m_savehMenu = 0;
|
|
||||||
|
wxWindow *wxMenu::GetWindow() const
|
||||||
|
{
|
||||||
|
if ( m_invokingWindow != NULL )
|
||||||
|
return m_invokingWindow;
|
||||||
|
else if ( m_menuBar != NULL)
|
||||||
|
return m_menuBar->GetFrame();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -674,7 +576,9 @@ WXHMENU wxMenuBar::Create()
|
|||||||
|
|
||||||
void wxMenuBar::EnableTop(size_t pos, bool enable)
|
void wxMenuBar::EnableTop(size_t pos, bool enable)
|
||||||
{
|
{
|
||||||
int flag = enable ? MF_ENABLED : MF_GRAYED;;
|
wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
|
||||||
|
|
||||||
|
int flag = enable ? MF_ENABLED : MF_GRAYED;
|
||||||
|
|
||||||
EnableMenuItem((HMENU)m_hMenu, pos, MF_BYPOSITION | flag);
|
EnableMenuItem((HMENU)m_hMenu, pos, MF_BYPOSITION | flag);
|
||||||
|
|
||||||
@@ -683,6 +587,16 @@ void wxMenuBar::EnableTop(size_t pos, bool enable)
|
|||||||
|
|
||||||
void wxMenuBar::SetLabelTop(size_t pos, const wxString& label)
|
void wxMenuBar::SetLabelTop(size_t pos, const wxString& label)
|
||||||
{
|
{
|
||||||
|
wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") );
|
||||||
|
|
||||||
|
m_titles[pos] = label;
|
||||||
|
|
||||||
|
if ( !IsAttached() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//else: have to modify the existing menu
|
||||||
|
|
||||||
UINT id;
|
UINT id;
|
||||||
UINT flagsOld = ::GetMenuState((HMENU)m_hMenu, pos, MF_BYPOSITION);
|
UINT flagsOld = ::GetMenuState((HMENU)m_hMenu, pos, MF_BYPOSITION);
|
||||||
if ( flagsOld == 0xFFFFFFFF )
|
if ( flagsOld == 0xFFFFFFFF )
|
||||||
@@ -708,18 +622,16 @@ void wxMenuBar::SetLabelTop(size_t pos, const wxString& label)
|
|||||||
{
|
{
|
||||||
wxLogLastError("ModifyMenu");
|
wxLogLastError("ModifyMenu");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString wxMenuBar::GetLabelTop(size_t pos) const
|
wxString wxMenuBar::GetLabelTop(size_t pos) const
|
||||||
{
|
{
|
||||||
int len = ::GetMenuString((HMENU)m_hMenu, pos, NULL, 0, MF_BYCOMMAND);
|
wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString,
|
||||||
|
wxT("invalid menu index in wxMenuBar::GetLabelTop") );
|
||||||
|
|
||||||
len++; // for the NUL character
|
return m_titles[pos];
|
||||||
wxString label;
|
|
||||||
::GetMenuString(GetHmenu(), pos, label.GetWriteBuf(len), len, MF_BYCOMMAND);
|
|
||||||
label.UngetWriteBuf();
|
|
||||||
|
|
||||||
return label;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxMenuBar::FindMenu(const wxString& title)
|
int wxMenuBar::FindMenu(const wxString& title)
|
||||||
@@ -764,6 +676,14 @@ wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
|
|||||||
wxLogLastError("InsertMenu");
|
wxLogLastError("InsertMenu");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
if ( menuOld->HasAccels() || menu->HasAccels() )
|
||||||
|
{
|
||||||
|
// need to rebuild accell table
|
||||||
|
RebuildAccelTable();
|
||||||
|
}
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,6 +708,14 @@ bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
|
|||||||
wxLogLastError("InsertMenu");
|
wxLogLastError("InsertMenu");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
if ( menu->HasAccels() )
|
||||||
|
{
|
||||||
|
// need to rebuild accell table
|
||||||
|
RebuildAccelTable();
|
||||||
|
}
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -799,8 +727,13 @@ bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
|
|||||||
WXHMENU submenu = menu ? menu->GetHMenu() : 0;
|
WXHMENU submenu = menu ? menu->GetHMenu() : 0;
|
||||||
wxCHECK_MSG( submenu, FALSE, wxT("can't append invalid menu to menubar") );
|
wxCHECK_MSG( submenu, FALSE, wxT("can't append invalid menu to menubar") );
|
||||||
|
|
||||||
|
if ( !wxMenuBarBase::Append(menu, title) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
menu->Attach(this);
|
menu->Attach(this);
|
||||||
|
|
||||||
|
m_titles.Add(title);
|
||||||
|
|
||||||
if ( IsAttached() )
|
if ( IsAttached() )
|
||||||
{
|
{
|
||||||
if ( !::AppendMenu(GetHmenu(), MF_POPUP | MF_STRING,
|
if ( !::AppendMenu(GetHmenu(), MF_POPUP | MF_STRING,
|
||||||
@@ -809,13 +742,17 @@ bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
|
|||||||
wxLogLastError(wxT("AppendMenu"));
|
wxLogLastError(wxT("AppendMenu"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
if ( menu->HasAccels() )
|
||||||
|
{
|
||||||
|
// need to rebuild accell table
|
||||||
|
RebuildAccelTable();
|
||||||
|
}
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxMenuBarBase::Append(menu, title);
|
|
||||||
|
|
||||||
m_titles.Add(title);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -834,6 +771,14 @@ wxMenu *wxMenuBar::Remove(size_t pos)
|
|||||||
|
|
||||||
menu->Detach();
|
menu->Detach();
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
if ( menu->HasAccels() )
|
||||||
|
{
|
||||||
|
// need to rebuild accell table
|
||||||
|
RebuildAccelTable();
|
||||||
|
}
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -842,15 +787,11 @@ wxMenu *wxMenuBar::Remove(size_t pos)
|
|||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenuBar::Attach(wxFrame *frame)
|
|
||||||
{
|
|
||||||
wxASSERT_MSG( !IsAttached(), wxT("menubar already attached!") );
|
|
||||||
|
|
||||||
m_menuBarFrame = frame;
|
|
||||||
|
|
||||||
#if wxUSE_ACCEL
|
#if wxUSE_ACCEL
|
||||||
// create the accel table - we consider that the menubar construction is
|
|
||||||
// finished
|
void wxMenuBar::RebuildAccelTable()
|
||||||
|
{
|
||||||
|
// merge the accelerators of all menus into one accel table
|
||||||
size_t nAccelCount = 0;
|
size_t nAccelCount = 0;
|
||||||
size_t i, count = GetMenuCount();
|
size_t i, count = GetMenuCount();
|
||||||
for ( i = 0; i < count; i++ )
|
for ( i = 0; i < count; i++ )
|
||||||
@@ -872,6 +813,18 @@ void wxMenuBar::Attach(wxFrame *frame)
|
|||||||
|
|
||||||
delete [] accelEntries;
|
delete [] accelEntries;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
|
void wxMenuBar::Attach(wxFrame *frame)
|
||||||
|
{
|
||||||
|
wxASSERT_MSG( !IsAttached(), wxT("menubar already attached!") );
|
||||||
|
|
||||||
|
m_menuBarFrame = frame;
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
RebuildAccelTable();
|
||||||
#endif // wxUSE_ACCEL
|
#endif // wxUSE_ACCEL
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -918,68 +871,3 @@ wxMenuItem *wxMenuBar::FindItem(int id, wxMenu **itemMenu) const
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// helper functions
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
wxWindow *wxMenu::GetWindow() const
|
|
||||||
{
|
|
||||||
if ( m_pInvokingWindow != NULL )
|
|
||||||
return m_pInvokingWindow;
|
|
||||||
else if ( m_menuBar != NULL)
|
|
||||||
return m_menuBar->GetFrame();
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
WXHMENU wxMenu::GetHMenu() const
|
|
||||||
{
|
|
||||||
if ( m_hMenu != 0 )
|
|
||||||
return m_hMenu;
|
|
||||||
else if ( m_savehMenu != 0 )
|
|
||||||
return m_savehMenu;
|
|
||||||
|
|
||||||
wxFAIL_MSG(wxT("wxMenu without HMENU"));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update a menu and all submenus recursively. source is the object that has
|
|
||||||
// the update event handlers defined for it. If NULL, the menu or associated
|
|
||||||
// window will be used.
|
|
||||||
void wxMenu::UpdateUI(wxEvtHandler* source)
|
|
||||||
{
|
|
||||||
if (!source && GetInvokingWindow())
|
|
||||||
source = GetInvokingWindow()->GetEventHandler();
|
|
||||||
if (!source)
|
|
||||||
source = GetEventHandler();
|
|
||||||
if (!source)
|
|
||||||
source = this;
|
|
||||||
|
|
||||||
wxNode* node = GetItems().First();
|
|
||||||
while (node)
|
|
||||||
{
|
|
||||||
wxMenuItem* item = (wxMenuItem*) node->Data();
|
|
||||||
if ( !item->IsSeparator() )
|
|
||||||
{
|
|
||||||
wxWindowID id = item->GetId();
|
|
||||||
wxUpdateUIEvent event(id);
|
|
||||||
event.SetEventObject( source );
|
|
||||||
|
|
||||||
if (source->ProcessEvent(event))
|
|
||||||
{
|
|
||||||
if (event.GetSetText())
|
|
||||||
SetLabel(id, event.GetText());
|
|
||||||
if (event.GetSetChecked())
|
|
||||||
Check(id, event.GetChecked());
|
|
||||||
if (event.GetSetEnabled())
|
|
||||||
Enable(id, event.GetEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item->GetSubMenu())
|
|
||||||
item->GetSubMenu()->UpdateUI(source);
|
|
||||||
}
|
|
||||||
node = node->Next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -42,6 +42,10 @@
|
|||||||
#include "wx/menuitem.h"
|
#include "wx/menuitem.h"
|
||||||
#include "wx/log.h"
|
#include "wx/log.h"
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
#include "wx/accel.h"
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -129,14 +133,6 @@ int wxMenuItem::GetRealId() const
|
|||||||
return m_subMenu ? (int)m_subMenu->GetHMenu() : GetId();
|
return m_subMenu ? (int)m_subMenu->GetHMenu() : GetId();
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the sub menu
|
|
||||||
// -------------------
|
|
||||||
void wxMenuItem::DeleteSubMenu()
|
|
||||||
{
|
|
||||||
delete m_subMenu;
|
|
||||||
m_subMenu = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get item state
|
// get item state
|
||||||
// --------------
|
// --------------
|
||||||
|
|
||||||
@@ -148,41 +144,60 @@ bool wxMenuItem::IsChecked() const
|
|||||||
return (flag & MF_DISABLED) == 0;
|
return (flag & MF_DISABLED) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString wxMenuItem::GetLabel() const
|
||||||
|
{
|
||||||
|
return wxStripMenuCodes(m_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// accelerators
|
||||||
|
// ------------
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
|
||||||
|
wxAcceleratorEntry *wxMenuItem::GetAccel() const
|
||||||
|
{
|
||||||
|
return wxGetAccelFromString(GetText());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
// change item state
|
// change item state
|
||||||
// -----------------
|
// -----------------
|
||||||
|
|
||||||
void wxMenuItem::Enable(bool bDoEnable)
|
void wxMenuItem::Enable(bool enable)
|
||||||
{
|
{
|
||||||
if ( m_isEnabled != bDoEnable ) {
|
if ( m_isEnabled == enable )
|
||||||
|
return;
|
||||||
|
|
||||||
long rc = EnableMenuItem(GetHMenuOf(m_parentMenu),
|
long rc = EnableMenuItem(GetHMenuOf(m_parentMenu),
|
||||||
GetRealId(),
|
GetRealId(),
|
||||||
MF_BYCOMMAND |
|
MF_BYCOMMAND |
|
||||||
(bDoEnable ? MF_ENABLED : MF_GRAYED));
|
(enable ? MF_ENABLED : MF_GRAYED));
|
||||||
|
|
||||||
if ( rc == -1 ) {
|
if ( rc == -1 ) {
|
||||||
wxLogLastError("EnableMenuItem");
|
wxLogLastError("EnableMenuItem");
|
||||||
}
|
}
|
||||||
|
|
||||||
wxMenuItemBase::Enable(m_isEnabled);
|
wxMenuItemBase::Enable(enable);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenuItem::Check(bool bDoCheck)
|
void wxMenuItem::Check(bool check)
|
||||||
{
|
{
|
||||||
wxCHECK_RET( m_isCheckable, wxT("only checkable items may be checked") );
|
wxCHECK_RET( m_isCheckable, wxT("only checkable items may be checked") );
|
||||||
|
|
||||||
if ( m_isChecked != bDoCheck ) {
|
if ( m_isChecked == check )
|
||||||
|
return;
|
||||||
|
|
||||||
long rc = CheckMenuItem(GetHMenuOf(m_parentMenu),
|
long rc = CheckMenuItem(GetHMenuOf(m_parentMenu),
|
||||||
GetId(),
|
GetRealId(),
|
||||||
MF_BYCOMMAND |
|
MF_BYCOMMAND |
|
||||||
(bDoCheck ? MF_CHECKED : MF_UNCHECKED));
|
(check ? MF_CHECKED : MF_UNCHECKED));
|
||||||
|
|
||||||
if ( rc == -1 ) {
|
if ( rc == -1 ) {
|
||||||
wxLogLastError("CheckMenuItem");
|
wxLogLastError("CheckMenuItem");
|
||||||
}
|
}
|
||||||
|
|
||||||
wxMenuItemBase::Check(m_isChecked);
|
wxMenuItemBase::Check(check);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxMenuItem::SetText(const wxString& text)
|
void wxMenuItem::SetText(const wxString& text)
|
||||||
@@ -195,6 +210,11 @@ void wxMenuItem::SetText(const wxString& text)
|
|||||||
OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) );
|
OWNER_DRAWN_ONLY( wxOwnerDrawn::SetName(text) );
|
||||||
|
|
||||||
HMENU hMenu = GetHMenuOf(m_parentMenu);
|
HMENU hMenu = GetHMenuOf(m_parentMenu);
|
||||||
|
wxCHECK_RET( hMenu, wxT("menuitem without menu") );
|
||||||
|
|
||||||
|
#if wxUSE_ACCEL
|
||||||
|
m_parentMenu->UpdateAccel(this);
|
||||||
|
#endif // wxUSE_ACCEL
|
||||||
|
|
||||||
UINT id = GetRealId();
|
UINT id = GetRealId();
|
||||||
UINT flagsOld = ::GetMenuState(hMenu, id, MF_BYCOMMAND);
|
UINT flagsOld = ::GetMenuState(hMenu, id, MF_BYCOMMAND);
|
||||||
|
Reference in New Issue
Block a user