added support for drop down toolbar buttons (patch 1713470)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45987 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2007-05-11 23:35:49 +00:00
parent 884898a79a
commit a9a0ceca5b
8 changed files with 133 additions and 5 deletions

View File

@@ -104,6 +104,24 @@ Pass the id of the tool.}
for a range of ids. Pass the ids of the tools.}
\twocolitem{{\bf EVT\_TOOL\_ENTER(id, func)}}{Process a wxEVT\_COMMAND\_TOOL\_ENTER event.
Pass the id of the toolbar itself. The value of wxCommandEvent::GetSelection is the tool id, or -1 if the mouse cursor has moved off a tool.}
\twocolitem{{\bf EVT\_TOOL\_DROPDOWN(id, func)}}{Process a wxEVT\_COMMAND\_TOOL\_DROPDOWN\_CLICKED event. If unhandled, displays the default dropdown menu set using \helpref{wxToolBar::SetDropdownMenu}{wxtoolbarsetdropdownmenu}.}
\end{twocollist}
\wxheading{wxItemKind}
There are several different types of tools you can add to a toolbar. These
types are controlled by the wxItemKind enumeration which has the following
values:
\twocolwidtha{5cm}
\begin{twocollist}\itemsep=0pt
\twocolitem{{\bf wxITEM\_NORMAL}}{Normal tool button}
\twocolitem{{\bf wxITEM\_CHECK}}{Check (or toggle) tool button.}
\twocolitem{{\bf wxITEM\_NORMAL}}{Radio tool button. See \helpref{wxToolBar::AddRadioTool}{wxtoolbaraddradiotool} for details}
\twocolitem{{\bf wxITEM\_DROPDOWN}}{Normal tool button with a dropdown arrow
next to it. Clicking the dropdown arrow sends a wxEVT\_COMMAND\_TOOL\_DROPDOWN\_CLICKED
event and may also display the menu previously associated with the item with
\helpref{wxToolBar::SetDropdownMenu}{wxtoolbarsetdropdownmenu}. Currently this
type of tools is only supported under MSW.}
\end{twocollist}
\wxheading{See also}
@@ -738,6 +756,17 @@ default (zero-size) margins are to be overridden.
\helpref{wxToolBar::GetMargins}{wxtoolbargetmargins}, \helpref{wxSize}{wxsize}
\membersection{wxToolBar::SetDropdownMenu}\label{wxtoolbarsetdropdownmenu}
\func{bool}{SetDropdownMenu}{\param{int }{id}, \param{wxMenu* }{menu}}
Sets the dropdown menu for the tool given by its \arg{id}. The tool itself will
delete the menu when it's no longer needed.
If you define a EVT\_TOOL\_DROPDOWN handler in your program, you must call
\helpref{wxEvent::Skip()}{wxeventskip} from it or the menu won't be displayed.
\membersection{wxToolBar::SetToolBitmapSize}\label{wxtoolbarsettoolbitmapsize}
\func{void}{SetToolBitmapSize}{\param{const wxSize\&}{ size}}

View File

@@ -1862,6 +1862,7 @@ enum wxItemKind
wxITEM_NORMAL,
wxITEM_CHECK,
wxITEM_RADIO,
wxITEM_DROPDOWN,
wxITEM_MAX
};

View File

@@ -155,6 +155,9 @@ BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE(wxEVT_COMMAND_TOOL_ENTER, 17)
DECLARE_EVENT_TYPE(wxEVT_COMMAND_SPINCTRL_UPDATED, 18)
// Toolbar dropdown arrows
DECLARE_EVENT_TYPE(wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED, 19)
// Sockets and timers send events, too
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_BASE, wxEVT_SOCKET, 50)
DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_BASE, wxEVT_TIMER , 80)
@@ -2988,6 +2991,7 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent&
#define EVT_VLBOX(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_VLBOX_SELECTED, winid, wxCommandEventHandler(func))
#define EVT_COMBOBOX(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_COMBOBOX_SELECTED, winid, wxCommandEventHandler(func))
#define EVT_TOOL(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_TOOL_CLICKED, winid, wxCommandEventHandler(func))
#define EVT_TOOL_DROPDOWN(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED, winid, wxCommandEventHandler(func))
#define EVT_TOOL_RANGE(id1, id2, func) wx__DECLARE_EVT2(wxEVT_COMMAND_TOOL_CLICKED, id1, id2, wxCommandEventHandler(func))
#define EVT_TOOL_RCLICKED(winid, func) wx__DECLARE_EVT1(wxEVT_COMMAND_TOOL_RCLICKED, winid, wxCommandEventHandler(func))
#define EVT_TOOL_RCLICKED_RANGE(id1, id2, func) wx__DECLARE_EVT2(wxEVT_COMMAND_TOOL_RCLICKED, id1, id2, wxCommandEventHandler(func))

View File

@@ -71,7 +71,8 @@ public:
const wxString& longHelpString = wxEmptyString)
: m_label(label),
m_shortHelpString(shortHelpString),
m_longHelpString(longHelpString)
m_longHelpString(longHelpString),
m_dropdownMenu(NULL)
{
m_tbar = tbar;
m_id = toolid;
@@ -106,9 +107,11 @@ public:
m_toggled = false;
m_toolStyle = wxTOOL_STYLE_CONTROL;
m_dropdownMenu = 0;
}
virtual ~wxToolBarToolBase(){}
virtual ~wxToolBarToolBase();
// accessors
// ---------
@@ -197,6 +200,11 @@ public:
virtual void Detach() { m_tbar = (wxToolBarBase *)NULL; }
virtual void Attach(wxToolBarBase *tbar) { m_tbar = tbar; }
// these methods are only for tools of wxITEM_DROPDOWN kind (but even such
// tools can have a NULL associated menu)
void SetDropdownMenu(wxMenu *menu);
wxMenu *GetDropdownMenu() const { return m_dropdownMenu; }
protected:
wxToolBarBase *m_tbar; // the toolbar to which we belong (may be NULL)
@@ -227,6 +235,8 @@ protected:
wxString m_shortHelpString;
wxString m_longHelpString;
wxMenu *m_dropdownMenu;
DECLARE_DYNAMIC_CLASS_NO_COPY(wxToolBarToolBase)
};
@@ -525,6 +535,9 @@ public:
// don't want toolbars to accept the focus
virtual bool AcceptsFocus() const { return false; }
// Set dropdown menu
bool SetDropdownMenu(int toolid, wxMenu *menu);
protected:
// to implement in derived classes
// -------------------------------

View File

@@ -125,6 +125,7 @@ public:
void OnToolLeftClick(wxCommandEvent& event);
void OnToolRightClick(wxCommandEvent& event);
void OnToolDropdown(wxCommandEvent& event);
void OnCombo(wxCommandEvent& event);
@@ -245,6 +246,8 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_TOOL_RCLICKED(wxID_ANY, MyFrame::OnToolRightClick)
EVT_TOOL_DROPDOWN(wxID_ANY, MyFrame::OnToolDropdown)
EVT_UPDATE_UI(wxID_COPY, MyFrame::OnUpdateCopyAndCut)
EVT_UPDATE_UI(wxID_CUT, MyFrame::OnUpdateCopyAndCut)
@@ -385,8 +388,16 @@ void MyFrame::RecreateToolbar()
toolBar->SetToolBitmapSize(wxSize(w, h));
toolBar->AddTool(wxID_NEW, _T("New"),
toolBarBitmaps[Tool_new], wxNullBitmap, wxITEM_NORMAL,
toolBarBitmaps[Tool_new], wxNullBitmap, wxITEM_DROPDOWN,
_T("New file"), _T("This is help for new file tool"));
wxMenu* menu = new wxMenu;
menu->Append(wxID_ANY, _T("&First dummy item"));
menu->Append(wxID_ANY, _T("&Second dummy item"));
menu->AppendSeparator();
menu->Append(wxID_EXIT, _T("Exit"));
toolBar->SetDropdownMenu(wxID_NEW, menu);
toolBar->AddTool(wxID_OPEN, _T("Open"),
toolBarBitmaps[Tool_open], wxNullBitmap, wxITEM_NORMAL,
_T("Open file"), _T("This is help for open file tool"));
@@ -868,3 +879,12 @@ void MyFrame::OnToggleRadioBtn(wxCommandEvent& event)
event.GetId() - IDM_TOOLBAR_TOGGLERADIOBTN1, true);
}
}
void MyFrame::OnToolDropdown(wxCommandEvent& event)
{
wxString str;
str.Printf( _T("Dropdown on tool %d\n"), event.GetId());
m_textWindow->WriteText( str );
event.Skip();
}

View File

@@ -173,6 +173,7 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_COMBOBOX_SELECTED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_RCLICKED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_ENTER)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_SPINCTRL_UPDATED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED)
// Mouse event types
DEFINE_EVENT_TYPE(wxEVT_LEFT_DOWN)

View File

@@ -35,6 +35,7 @@
#if WXWIN_COMPATIBILITY_2_8
#include "wx/image.h"
#endif // WXWIN_COMPATIBILITY_2_8
#include "wx/menu.h"
#endif
// ----------------------------------------------------------------------------
@@ -58,6 +59,12 @@ WX_DEFINE_LIST(wxToolBarToolsList)
IMPLEMENT_DYNAMIC_CLASS(wxToolBarToolBase, wxObject)
wxToolBarToolBase::~wxToolBarToolBase()
{
delete m_dropdownMenu;
}
bool wxToolBarToolBase::Enable(bool enable)
{
if ( m_enabled == enable )
@@ -111,6 +118,13 @@ bool wxToolBarToolBase::SetLongHelp(const wxString& help)
return true;
}
void wxToolBarToolBase::SetDropdownMenu(wxMenu* menu)
{
delete m_dropdownMenu;
m_dropdownMenu = menu;
}
// ----------------------------------------------------------------------------
// wxToolBarBase adding/deleting items
// ----------------------------------------------------------------------------
@@ -690,6 +704,19 @@ void wxToolBarBase::UpdateWindowUI(long flags)
}
}
bool wxToolBarBase::SetDropdownMenu(int toolid, wxMenu* menu)
{
wxToolBarToolBase * const tool = FindById(toolid);
wxCHECK_MSG( tool, false, _T("invalid tool id") );
wxCHECK_MSG( tool->GetKind() == wxITEM_DROPDOWN, false,
_T("menu can be only associated with drop down tools") );
tool->SetDropdownMenu(menu);
return true;
}
#if WXWIN_COMPATIBILITY_2_8
bool wxCreateGreyedImage(const wxImage& in, wxImage& out)
@@ -699,7 +726,6 @@ bool wxCreateGreyedImage(const wxImage& in, wxImage& out)
if ( out.Ok() )
return true;
#endif // wxUSE_IMAGE
return false;
}

View File

@@ -303,6 +303,9 @@ bool wxToolBar::MSWCreateToolbar(const wxPoint& pos, const wxSize& size)
// toolbar-specific post initialisation
::SendMessage(GetHwnd(), TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
if ( wxApp::GetComCtl32Version() >= 471 )
::SendMessage(GetHwnd(), TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_DRAWDDARROWS);
return true;
}
@@ -958,6 +961,10 @@ bool wxToolBar::Realize()
button.fsStyle = TBSTYLE_BUTTON;
break;
case wxITEM_DROPDOWN:
button.fsStyle = TBSTYLE_DROPDOWN;
break;
default:
wxFAIL_MSG( _T("unexpected toolbar button kind") );
button.fsStyle = TBSTYLE_BUTTON;
@@ -1200,11 +1207,38 @@ bool wxToolBar::MSWOnNotify(int WXUNUSED(idCtrl),
WXLPARAM lParam,
WXLPARAM *WXUNUSED(result))
{
LPNMHDR hdr = (LPNMHDR)lParam;
if ( hdr->code == TBN_DROPDOWN )
{
LPNMTOOLBAR tbhdr = (LPNMTOOLBAR)lParam;
wxCommandEvent evt(wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED, tbhdr->iItem);
if ( GetEventHandler()->ProcessEvent(evt) )
{
// Event got handled, don't display default popup menu
return false;
}
const wxToolBarToolBase * const tool = FindById(tbhdr->iItem);
wxCHECK_MSG( tool, false, _T("drop down message for unknown tool") );
wxMenu * const menu = tool->GetDropdownMenu();
if ( !menu )
return false;
// Display popup menu below button
RECT r;
if (::SendMessage(GetHwnd(), TB_GETITEMRECT, GetToolPos(tbhdr->iItem), (LPARAM)&r))
PopupMenu(menu, r.left, r.bottom);
return true;
}
if( !HasFlag(wxTB_NO_TOOLTIPS) )
{
#if wxUSE_TOOLTIPS
// First check if this applies to us
NMHDR *hdr = (NMHDR *)lParam;
// the tooltips control created by the toolbar is sometimes Unicode, even
// in an ANSI application - this seems to be a bug in comctl32.dll v5