📄 menubtn.cpp
字号:
/////////////////////////////////////////////////////////////////////////////// Name: wxMenuButton// Purpose: A button with a dropdown wxMenu// Author: John Labenski// Modified by:// Created: 11/05/2002// RCS-ID:// Copyright: (c) John Labenki// Licence: wxWidgets licence/////////////////////////////////////////////////////////////////////////////#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "menubtn.h"#endif// For compilers that support precompilation, includes "wx/wx.h".#include "wx/wxprec.h"#ifdef __BORLANDC__ #pragma hdrstop#endif#ifndef WX_PRECOMP #include "wx/control.h" #include "wx/menu.h" #include "wx/settings.h" #include "wx/bitmap.h" #include "wx/pen.h" #include "wx/dc.h"#endif // WX_PRECOMP#include <wx/tglbtn.h>#include <wx/dcclient.h>#include <wx/timer.h>#include <wx/image.h>#include "menubtn.h"// ==========================================================================// wxCustomButton// ==========================================================================IMPLEMENT_DYNAMIC_CLASS( wxCustomButton, wxControl )BEGIN_EVENT_TABLE(wxCustomButton,wxControl) EVT_MOUSE_EVENTS ( wxCustomButton::OnMouseEvents ) EVT_PAINT ( wxCustomButton::OnPaint ) EVT_SIZE ( wxCustomButton::OnSize )END_EVENT_TABLE()wxCustomButton::~wxCustomButton(){ if (HasCapture()) ReleaseMouse(); if (m_timer) delete m_timer;}void wxCustomButton::Init(){ m_focused = FALSE; m_labelMargin = wxSize(4,4); m_bitmapMargin = wxSize(2,2); m_down = 0; m_timer = NULL; m_eventType = 0; m_button_style = wxCUSTBUT_TOGGLE|wxCUSTBUT_BOTTOM;}bool wxCustomButton::Create(wxWindow* parent, wxWindowID id, const wxString& label, const wxBitmap &bitmap, const wxPoint& pos, const wxSize& size, long style, const wxValidator& val, const wxString& name){ if (!wxControl::Create(parent,id,pos,size,wxNO_BORDER|wxCLIP_CHILDREN,val,name)) return FALSE; wxControl::SetLabel(label); wxControl::SetBackgroundColour(parent->GetBackgroundColour()); wxControl::SetForegroundColour(parent->GetForegroundColour()); wxControl::SetFont(parent->GetFont()); if (bitmap.Ok()) m_bmpLabel = bitmap; if (!SetButtonStyle(style)) return FALSE; wxSize bestSize = DoGetBestSize(); SetSize(wxSize(size.x<0 ? bestSize.x:size.x, size.y<0 ? bestSize.y:size.y));#if (wxMINOR_VERSION<8) SetBestSize(GetSize());#else SetInitialSize(GetSize());#endif CalcLayout(TRUE); return TRUE;}void wxCustomButton::SetValue(bool depressed){ wxCHECK_RET(!(m_button_style & wxCUSTBUT_NOTOGGLE), wxT("can't set button state")); m_down = depressed ? 1 : 0; Refresh(FALSE);}bool wxCustomButton::SetButtonStyle(long style){ int n_styles = 0; if ((style & wxCUSTBUT_LEFT) != 0) n_styles++; if ((style & wxCUSTBUT_RIGHT) != 0) n_styles++; if ((style & wxCUSTBUT_TOP) != 0) n_styles++; if ((style & wxCUSTBUT_BOTTOM) != 0) n_styles++; wxCHECK_MSG(n_styles < 2, FALSE, wxT("Only one wxCustomButton label position allowed")); n_styles = 0; if ((style & wxCUSTBUT_NOTOGGLE) != 0) n_styles++; if ((style & wxCUSTBUT_BUTTON) != 0) n_styles++; if ((style & wxCUSTBUT_TOGGLE) != 0) n_styles++; if ((style & wxCUSTBUT_BUT_DCLICK_TOG) != 0) n_styles++; if ((style & wxCUSTBUT_TOG_DCLICK_BUT) != 0) n_styles++; wxCHECK_MSG(n_styles < 2, FALSE, wxT("Only one wxCustomButton style allowed")); m_button_style = style; if ((m_button_style & wxCUSTBUT_BUTTON) != 0) m_down = 0; CalcLayout(TRUE); return TRUE;}void wxCustomButton::SetLabel( const wxString &label ){ wxControl::SetLabel(label); CalcLayout(TRUE);}// sequence of events in GTK is up, dclick, up.void wxCustomButton::OnMouseEvents(wxMouseEvent& event){ if (m_button_style & wxCUSTBUT_NOTOGGLE) return; if (event.LeftDown() || event.RightDown()) { if (!HasCapture()) CaptureMouse(); // keep depressed until up m_down++; Redraw(); } else if (event.LeftDClick() || event.RightDClick()) { m_down++; // GTK eats second down event Redraw(); } else if (event.LeftUp()) { if (HasCapture()) ReleaseMouse(); m_eventType = wxEVT_LEFT_UP; #if (wxMINOR_VERSION<8) if (wxRect(wxPoint(0,0), GetSize()).Inside(event.GetPosition()))#else if (wxRect(wxPoint(0,0), GetSize()).Contains(event.GetPosition()))#endif { if ((m_button_style & wxCUSTBUT_BUTTON) && (m_down > 0)) { m_down = 0; Redraw(); SendEvent(); return; } else { if (!m_timer) { m_timer = new wxTimer(this, m_down+1); m_timer->Start(200, TRUE); } else { m_eventType = wxEVT_LEFT_DCLICK; } if ((m_button_style & wxCUSTBUT_TOGGLE) && (m_button_style & wxCUSTBUT_TOG_DCLICK_BUT)) m_down++; } } Redraw(); } else if (event.RightUp()) { if (HasCapture()) ReleaseMouse(); m_eventType = wxEVT_RIGHT_UP;#if (wxMINOR_VERSION<8) if (wxRect(wxPoint(0,0), GetSize()).Inside(event.GetPosition()))#else if (wxRect(wxPoint(0,0), GetSize()).Contains(event.GetPosition()))#endif { if ((m_button_style & wxCUSTBUT_BUTTON) && (m_down > 0)) { m_down = 0; Redraw(); SendEvent(); return; } else { m_down++; if (!m_timer) { m_timer = new wxTimer(this, m_down); m_timer->Start(250, TRUE); } else { m_eventType = wxEVT_RIGHT_DCLICK; } } } Redraw(); } else if (event.Entering()) { m_focused = TRUE; if ((event.LeftIsDown() || event.RightIsDown()) && HasCapture()) m_down++; Redraw(); } else if (event.Leaving()) { m_focused = FALSE; if ((event.LeftIsDown() || event.RightIsDown()) && HasCapture()) m_down--; Redraw(); }}void wxCustomButton::SendEvent(){ if (((m_button_style & wxCUSTBUT_TOGGLE) && (m_eventType == wxEVT_LEFT_UP)) || ((m_button_style & wxCUSTBUT_BUT_DCLICK_TOG) && (m_eventType == wxEVT_LEFT_DCLICK)) || ((m_button_style & wxCUSTBUT_TOG_DCLICK_BUT) && (m_eventType == wxEVT_LEFT_UP))) { wxCommandEvent eventOut(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, GetId()); eventOut.SetInt(m_down%2 ? 1 : 0); eventOut.SetExtraLong(m_eventType); eventOut.SetEventObject(this); GetEventHandler()->ProcessEvent(eventOut); } else { wxCommandEvent eventOut(wxEVT_COMMAND_BUTTON_CLICKED, GetId()); eventOut.SetInt(0); eventOut.SetExtraLong(m_eventType); eventOut.SetEventObject(this); GetEventHandler()->ProcessEvent(eventOut); }}wxBitmap wxCustomButton::CreateBitmapDisabled(const wxBitmap &bitmap) const{ wxCHECK_MSG(bitmap.Ok(), wxNullBitmap, wxT("invalid bitmap")); unsigned char br = GetBackgroundColour().Red(); unsigned char bg = GetBackgroundColour().Green(); unsigned char bb = GetBackgroundColour().Blue(); wxImage image = bitmap.ConvertToImage(); int pos, width = image.GetWidth(), height = image.GetHeight(); unsigned char *img_data = image.GetData(); for (int j=0; j<height; j++) { for (int i=j%2; i<width; i+=2) { pos = (j*width+i)*3; img_data[pos ] = br; img_data[pos+1] = bg; img_data[pos+2] = bb; } } return wxBitmap(image);}void wxCustomButton::SetBitmapLabel(const wxBitmap& bitmap){ m_bmpLabel = bitmap; CalcLayout(TRUE); }void wxCustomButton::OnPaint(wxPaintEvent& WXUNUSED(event)){ wxPaintDC dc(this); Paint(dc);}void wxCustomButton::Redraw(){ wxClientDC dc(this); Paint(dc);}void wxCustomButton::Paint( wxDC &dc ){#if (wxMINOR_VERSION<8) dc.BeginDrawing();#endif int w, h; GetSize(&w,&h); wxColour foreColour = GetForegroundColour(); wxColour backColour = GetBackgroundColour(); if (m_focused) { backColour.Set( wxMin(backColour.Red() + 20, 255), wxMin(backColour.Green() + 20, 255), wxMin(backColour.Blue() + 20, 255) ); } wxBitmap bitmap; if (IsEnabled()) { if (GetValue() && m_bmpSelected.Ok()) bitmap = m_bmpSelected; else if (m_focused && m_bmpFocus.Ok()) bitmap = m_bmpFocus; else if (m_bmpLabel.Ok()) bitmap = m_bmpLabel; } else { // try to create disabled if it doesn't exist if (!m_bmpDisabled.Ok() && m_bmpLabel.Ok()) m_bmpDisabled = CreateBitmapDisabled(m_bmpLabel); if (m_bmpDisabled.Ok()) bitmap = m_bmpDisabled; else if (m_bmpLabel.Ok()) bitmap = m_bmpLabel; foreColour = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT); } wxBrush brush(backColour, wxSOLID); dc.SetBackground(brush); dc.SetBrush(brush); dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(0, 0, w, h); if (bitmap.Ok()) dc.DrawBitmap(bitmap, m_bitmapPos.x, m_bitmapPos.y, TRUE ); if (!GetLabel().IsEmpty()) { dc.SetFont(GetFont()); dc.SetTextBackground(backColour); dc.SetTextForeground(foreColour); dc.DrawText(GetLabel(), m_labelPos.x, m_labelPos.y); } if (GetValue()) // draw sunken border { dc.SetPen(*wxGREY_PEN); dc.DrawLine(0,h-1,0,0); dc.DrawLine(0,0,w,0); dc.SetPen(*wxWHITE_PEN); dc.DrawLine(w-1,1,w-1,h-1); dc.DrawLine(w-1,h-1,0,h-1); dc.SetPen(*wxBLACK_PEN); dc.DrawLine(1,h-2,1,1); dc.DrawLine(1,1,w-1,1); } else if (((m_button_style & wxCUSTBUT_FLAT) == 0) || m_focused) // draw raised border { dc.SetPen(*wxWHITE_PEN); dc.DrawLine(0,h-2,0,0); dc.DrawLine(0,0,w-1,0); dc.SetPen(*wxBLACK_PEN); dc.DrawLine(w-1,0,w-1,h-1); dc.DrawLine(w-1,h-1,-1,h-1); dc.SetPen(*wxGREY_PEN); dc.DrawLine(2,h-2,w-2,h-2); dc.DrawLine(w-2,h-2,w-2,1); } dc.SetBackground(wxNullBrush); dc.SetBrush(wxNullBrush); dc.SetPen(wxNullPen);#if (wxMINOR_VERSION<8) dc.EndDrawing();#endif}void wxCustomButton::OnSize( wxSizeEvent &event ){ CalcLayout(TRUE); event.Skip();}void wxCustomButton::SetMargins(const wxSize &margin, bool fit){ m_labelMargin = margin; m_bitmapMargin = margin; CalcLayout(TRUE); if (fit) SetSize(DoGetBestSize());}void wxCustomButton::SetLabelMargin(const wxSize &margin, bool fit) { m_labelMargin = margin; CalcLayout(TRUE); if (fit) SetSize(DoGetBestSize());}void wxCustomButton::SetBitmapMargin(const wxSize &margin, bool fit) { m_bitmapMargin = margin; CalcLayout(TRUE); if (fit) SetSize(DoGetBestSize());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -