/////////////////////////////////////////////////////////////////////////////
// Name: wxMenuButton
// Purpose: A button with a dropdown wxMenu
// Author: John Labenski
// Modified by:
// Created: 11/05/2002
// Copyright: (c) John Labenski
// Licence: wxWidgets licence
/////////////////////////////////////////////////////////////////////////////
/*
wxMenuButton is a button that drops down an assigned wxMenu
Create the button with either a text or bitmap label.
Create a new wxMenu and call AssignMenu and thats it. When you press the
dropdown button the menu appears. When you press the label button the next
wxITEM_RADIO (ie wxMenuItem::GetKind) in the menu is selected round robin.
If there are no radio items then it really just acts like a menubar, though
this is probably not too useful. The events sent in this case are EVT_MENUs
either generated by the menu when you click on it or created when you click
on the label to select the next radio item.
*/
#ifndef _WX_MENUBTN_H_
#define _WX_MENUBTN_H_
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma interface "menubtn.h"
#endif
class wxMenu;
class wxBitmap;
class wxCustomButton;
//-----------------------------------------------------------------------------
// wxCustomButton styles
//-----------------------------------------------------------------------------
enum wxCustomButton_Style
{
// Position of the label, use only one
wxCUSTBUT_LEFT = 0x0001,
wxCUSTBUT_RIGHT = 0x0002,
wxCUSTBUT_TOP = 0x0004,
wxCUSTBUT_BOTTOM = 0x0008,
// Button style, use only one
wxCUSTBUT_NOTOGGLE = 0x0100,
wxCUSTBUT_BUTTON = 0x0200,
wxCUSTBUT_TOGGLE = 0x0400,
wxCUSTBUT_BUT_DCLICK_TOG = 0x0800,
wxCUSTBUT_TOG_DCLICK_BUT = 0x1000,
// drawing styles
wxCUSTBUT_FLAT = 0x2000 // flat, mouseover raises if not depressed
};
//-----------------------------------------------------------------------------
// wxCustomButton
//-----------------------------------------------------------------------------
class WXDLLEXPORT wxCustomButton : public wxControl
{
public:
wxCustomButton() : wxControl() {
Init();
}
// wxToggleButton or wxButton compatible constructor (also wxTextCtrl)
wxCustomButton(wxWindow* parent, wxWindowID id,
const wxString& label,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxCUSTBUT_TOGGLE,
const wxValidator& val = wxDefaultValidator,
const wxString& name = wxT("wxCustomButton"))
: wxControl()
{
Init();
Create(parent,id,label,wxNullBitmap,pos,size,style,val,name);
}
// wxBitmapButton compatible constructor
wxCustomButton(wxWindow *parent, wxWindowID id,
const wxBitmap& bitmap,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxCUSTBUT_TOGGLE,
const wxValidator& val = wxDefaultValidator,
const wxString& name = wxT("wxCustomButton"))
: wxControl()
{
Init();
Create(parent,id,wxEmptyString,bitmap,pos,size,style,val,name);
}
// Native constructor
wxCustomButton(wxWindow *parent, wxWindowID id,
const wxString& label, const wxBitmap& bitmap,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxCUSTBUT_TOGGLE|wxCUSTBUT_BOTTOM,
const wxValidator& val = wxDefaultValidator,
const wxString& name = wxT("wxCustomButton"))
: wxControl()
{
Init();
Create(parent,id,label,bitmap,pos,size,style,val,name);
}
virtual ~wxCustomButton();
bool Create(wxWindow* parent,
wxWindowID id,
const wxString& label,
const wxBitmap &bitmap,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
const wxValidator& val = wxDefaultValidator,
const wxString& name = wxT("wxCustomButton"));
bool GetValue() const {
return m_down%2 != 0;
}
void SetValue( bool depressed );
// Use combinations of wxCustomButton_Style(s)
long GetButtonStyle() const {
return m_button_style;
}
bool SetButtonStyle( long style );
// Set the text label, wxEmptyString for none
void SetLabel( const wxString &label );
// set the bitmaps, ONLY this Label bitmap is used for calculating control size
// all bitmaps will be centered accordingly in any case
// call SetSet(GetBestSize()) if you change their size and want the control to resize appropriately
void SetBitmapLabel(const wxBitmap& bitmap);
void SetBitmapSelected(const wxBitmap& sel) {
m_bmpSelected = sel;
CalcLayout(TRUE);
};
void SetBitmapFocus(const wxBitmap& focus) {
m_bmpFocus = focus;
CalcLayout(TRUE);
};
void SetBitmapDisabled(const wxBitmap& disabled) {
m_bmpDisabled = disabled;
CalcLayout(TRUE);
};
// wxBitmapButton compatibility
void SetLabel(const wxBitmap& bitmap) {
SetBitmapLabel(bitmap);
}
// retrieve the bitmaps
const wxBitmap& GetBitmapLabel() const {
return m_bmpLabel;
}
const wxBitmap& GetBitmapSelected() const {
return m_bmpSelected;
}
const wxBitmap& GetBitmapFocus() const {
return m_bmpFocus;
}
const wxBitmap& GetBitmapDisabled() const {
return m_bmpDisabled;
}
// Creates a "disabled" bitmap by dithering it with the background colour
wxBitmap CreateBitmapDisabled(const wxBitmap &bitmap) const;
// set/get the margins (in pixels) around the label and bitmap
// if fit = TRUE then resize the button to fit
void SetMargins(const wxSize &margin, bool fit = FALSE);
// set/get the margins around the text label
// the inter bitmap/label margin is the max of either margin, not the sum
void SetLabelMargin(const wxSize &margin, bool fit = FALSE);
wxSize GetLabelMargin() const {
return m_labelMargin;
}
// set/get the margins around the bitmap
// the inter bitmap/label margin is the max of either margin, not the sum
void SetBitmapMargin(const wxSize &margin, bool fit = FALSE);
wxSize GetBitmapMargin() const {
return m_bitmapMargin;
}
// can be used to activate the focused behavior (see MenuButton)
void SetFocused(bool focused) {
m_focused = focused;
Refresh(FALSE);
}
bool GetFocused() const {
return m_focused;
}
protected:
void OnPaint(wxPaintEvent &event);
void Redraw();
virtual void Paint( wxDC &dc );
virtual wxSize DoGetBestSize() const;
virtual void SendEvent();
void OnMouseEvents(wxMouseEvent &event);
void OnSize( wxSizeEvent &event );
virtual void CalcLayout(bool refresh);
long m_down; // toggle state if m_down%2 then depressed
bool m_focused; // mouse in window
long m_button_style;
// the bitmaps for various states
wxBitmap m_bmpLabel,
m_bmpSelected,
m_bmpFocus,
m_bmpDisabled;
// the margins around the label/bitmap
wxSize m_labelMargin,
m_bitmapMargin;
wxPoint m_bitmapPos,
m_labelPos;
wxTimer *m_timer;
wxEventType m_eventType; // store the mouse event type
private:
void Init();
DECLARE_DYNAMIC_CLASS(wxCustomButton)
DECLARE_EVENT_TABLE()
};
//-----------------------------------------------------------------------------
// wxMenuButton styles
//-----------------------------------------------------------------------------
#define wxMENUBUTTON_DROP_WIDTH 10
#define wxMENUBUTTON_DROP_HEIGHT 22
enum wxMenuButton_Styles
{
wxMENUBUT_FLAT = wxCUSTBUT_FLAT
};
//-----------------------------------------------------------------------------
// wxMenuButton
//-----------------------------------------------------------------------------
class wxMenuButton : public wxControl
{
public:
wxMenuButton() : wxControl() {
Init();
}
// Use this constructor if you need one compatible with a wxBitmapButton
// setup the button later with AssignMenu
wxMenuButton( wxWindow* parent, wxWindowID id,
const wxBitmap &bitmap,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
const wxValidator& val = wxDefaultValidator,
const wxString& name = wxT("wxMenuButton"))
: wxControl()
{
Init();
Create(parent,id,wxEmptyString,bitmap,pos,size,style,val,name);
}
virtual ~wxMenuButton();
bool Create( wxWindow* parent,
wxWindowID id,
const wxString &label,
const wxBitmap &bitmap,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxNO_BORDER,
const wxValidator& val = wxDefaultValidator,
const wxString& name = wxT("wxMenuButton"));
// Gets the id of the first selected radio item or wxNOT_FOUND (-1) if none
int GetSelection() const;
// This menu will be displayed when the dropdown button is pressed.
// if static_menu is FALSE it will be deleted when the buttton is destroyed.
void AssignMenu(wxMenu *menu, bool static_menu = FALSE);
wxMenu *GetMenu() const {
return m_menu;
}
// get a pointer to the label button, for turning it into a toggle perhaps
wxCustomButton *GetLabelButton() const {
return m_labelButton;
}
wxCustomButton *GetDropDownButton() const {
return m_dropdownButton;
}
void SetToolTip(const wxString &tip);
void SetToolTip(wxToolTip *tip);
protected:
void OnButton(wxCommandEvent &event);
virtual void DoSetSize(int x, int y, int width, int height,
int sizeFlags = wxSIZE_AUTO);
virtual wxSize DoGetBestSize();
// FIXME! - in MSW the radio items don't check themselves
#ifdef __WXMSW__
void OnMenu( wxCommandEvent &event );
#endif
wxCustomButton *m_labelButton;
wxCustomButton *m_dropdownButton;
wxMenu *m_menu;
bool m_menu_static;
long m_style;
private:
void Init();
DECLARE_DYNAMIC_CLASS(wxMenuButton)
DECLARE_EVENT_TABLE()
};
//-----------------------------------------------------------------------------
// wxMenuButtonEvents
//
// EVT_MENUBUTTON_OPEN(id, fn) - menu is about to be opened, (dis)(en)able items
// or call Veto() to stop menu from popping up
// this is a wxNotifyEvent
//-----------------------------------------------------------------------------
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_LOCAL_EVENT_TYPE( wxEVT_MENUBUTTON_OPEN, 0 )
END_DECLARE_EVENT_TYPES()
#define EVT_MENUBUTTON_OPEN(id, fn) DECLARE_EVENT_TABLE_ENTRY(wxEVT_MENUBUTTON_OPEN, id, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) & fn, (wxObject *) NULL ),
#endif // _WX_MENUBTN_H_