📄 menubtn.cpp
字号:
}wxSize wxCustomButton::DoGetBestSize() const{ int lw=0, lh=0; int bw=0, bh=0; bool has_bitmap = FALSE; bool has_label = FALSE; if (!GetLabel().IsEmpty()) { GetTextExtent(GetLabel(), &lw, &lh); lw += 2*m_labelMargin.x; lh += 2*m_labelMargin.y; has_label = TRUE; } if (m_bmpLabel.Ok()) { bw = m_bmpLabel.GetWidth() + 2*m_bitmapMargin.x; bh = m_bmpLabel.GetHeight() + 2*m_bitmapMargin.y; has_bitmap = TRUE; } if ((m_button_style & wxCUSTBUT_LEFT) || (m_button_style & wxCUSTBUT_RIGHT)) { int h = bh > lh ? bh : lh; if (has_bitmap && has_label) lw -= wxMin(m_labelMargin.x, m_bitmapMargin.x); return wxSize(lw+bw, h); } int w = bw > lw ? bw : lw; if (has_bitmap && has_label) lh -= wxMin(m_labelMargin.y, m_bitmapMargin.y); return wxSize(w, lh+bh);}void wxCustomButton::CalcLayout(bool refresh){ int w, h; GetSize(&w,&h); int bw = 0, bh = 0; int lw = 0, lh = 0; if (m_bmpLabel.Ok()) // assume they're all the same size { bw = m_bmpLabel.GetWidth(); bh = m_bmpLabel.GetHeight(); } wxString label = GetLabel(); if (!label.IsEmpty()) { GetTextExtent(label, &lw, &lh); } // Center the label or bitmap if only one or the other if (!m_bmpLabel.Ok()) { m_bitmapPos = wxPoint(0,0); m_labelPos = wxPoint((w-lw)/2, (h-lh)/2); } else if (label.IsEmpty()) { m_bitmapPos = wxPoint((w-bw)/2, (h-bh)/2); m_labelPos = wxPoint(0,0); } else if (m_button_style & wxCUSTBUT_LEFT) { int mid_margin = wxMax(m_labelMargin.x, m_bitmapMargin.x); m_labelPos = wxPoint((w - (bw+lw+m_labelMargin.x+m_bitmapMargin.x+mid_margin))/2 + m_labelMargin.x, (h - lh)/2); m_bitmapPos = wxPoint(m_labelPos.x + lw + mid_margin, (h - bh)/2); } else if (m_button_style & wxCUSTBUT_RIGHT) { int mid_margin = wxMax(m_labelMargin.x, m_bitmapMargin.x); m_bitmapPos = wxPoint((w - (bw+lw+m_labelMargin.x+m_bitmapMargin.x+mid_margin))/2 + m_bitmapMargin.x, (h - bh)/2); m_labelPos = wxPoint(m_bitmapPos.x + bw + mid_margin, (h - lh)/2); } else if (m_button_style & wxCUSTBUT_TOP) { int mid_margin = wxMax(m_labelMargin.y, m_bitmapMargin.y); m_labelPos = wxPoint((w - lw)/2, (h - (bh+lh+m_labelMargin.y+m_bitmapMargin.y+mid_margin))/2 + m_labelMargin.y); m_bitmapPos = wxPoint((w - bw)/2, m_labelPos.y + lh + mid_margin); } else // if (m_button_style & wxCUSTBUT_BOTTOM) DEFAULT { int mid_margin = wxMax(m_labelMargin.y, m_bitmapMargin.y); m_bitmapPos = wxPoint((w - bw)/2, (h - (bh+lh+m_labelMargin.y+m_bitmapMargin.y+mid_margin))/2 + m_bitmapMargin.y); m_labelPos = wxPoint((w - lw)/2, m_bitmapPos.y + bh + mid_margin); } if (refresh) Refresh(FALSE);}/* XPM */static const char *down_arrow_xpm_data[] = {/* columns rows colors chars-per-pixel */"5 3 2 1"," c None","a c Black",/* pixels */"aaaaa"," aaa "," a "};static wxBitmap s_dropdownBitmap; // all buttons share the same bitmapenum{ IDD_DROPDOWN_BUTTON = 100};//-----------------------------------------------------------------------------// wxMenuButtonEvents//-----------------------------------------------------------------------------DEFINE_LOCAL_EVENT_TYPE(wxEVT_MENUBUTTON_OPEN)// ==========================================================================// MenuDropButton// ==========================================================================class MenuDropButton : public wxCustomButton{public: MenuDropButton( wxWindow *parent, wxWindowID id, long style) : wxCustomButton() { if (!s_dropdownBitmap.Ok()) s_dropdownBitmap = wxBitmap(down_arrow_xpm_data); Create( parent, id, wxEmptyString, s_dropdownBitmap, wxDefaultPosition, wxSize(wxMENUBUTTON_DROP_WIDTH, wxMENUBUTTON_DROP_HEIGHT), style); } virtual void Paint( wxDC &dc ) { wxCustomButton *labelBut = ((wxMenuButton*)GetParent())->GetLabelButton(); // pretend that both buttons have focus (for flat style) if (labelBut) { wxPoint p = GetParent()->ScreenToClient(wxGetMousePosition()); #if (wxMINOR_VERSION<8) if (GetRect().Inside(p) || labelBut->GetRect().Inside(p))#else if (GetRect().Contains(p) || labelBut->GetRect().Contains(p))#endif { m_focused = TRUE; if (!labelBut->GetFocused()) labelBut->SetFocused(TRUE); } else { m_focused = FALSE; if (labelBut->GetFocused()) labelBut->SetFocused(FALSE); } } wxCustomButton::Paint(dc); }};// ==========================================================================// MenuLabelButton// ==========================================================================class MenuLabelButton : public wxCustomButton{public: MenuLabelButton( wxWindow* parent, wxWindowID id, const wxString &label, const wxBitmap &bitmap, long style ) : wxCustomButton() { Create(parent, id, label, bitmap, wxDefaultPosition, wxDefaultSize, style); } virtual void Paint( wxDC &dc ) { wxCustomButton *dropBut = ((wxMenuButton*)GetParent())->GetDropDownButton(); // pretend that both buttons have focus (for flat style) if (dropBut) { wxPoint p = GetParent()->ScreenToClient(wxGetMousePosition()); #if (wxMINOR_VERSION<8) if (GetRect().Inside(p) || dropBut->GetRect().Inside(p))#else if (GetRect().Contains(p) || dropBut->GetRect().Contains(p))#endif { m_focused = TRUE; if (!dropBut->GetFocused()) dropBut->SetFocused(TRUE); } else { m_focused = FALSE; if (dropBut->GetFocused()) dropBut->SetFocused(FALSE); } } wxCustomButton::Paint(dc); }};// ==========================================================================// wxMenuButton// ==========================================================================IMPLEMENT_DYNAMIC_CLASS( wxMenuButton, wxControl )BEGIN_EVENT_TABLE(wxMenuButton,wxControl) EVT_BUTTON(wxID_ANY, wxMenuButton::OnButton)#ifdef __WXMSW__ EVT_MENU(wxID_ANY, wxMenuButton::OnMenu)#endifEND_EVENT_TABLE()wxMenuButton::~wxMenuButton(){ AssignMenu(NULL, TRUE);}void wxMenuButton::Init(){ m_labelButton = NULL; m_dropdownButton = NULL; m_menu = NULL; m_menu_static = FALSE; m_style = 0;}bool wxMenuButton::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){ m_style = style; long flat = style & wxMENUBUT_FLAT; wxControl::Create(parent,id,pos,size,wxNO_BORDER|wxCLIP_CHILDREN,val,name); wxControl::SetLabel(label); SetBackgroundColour(parent->GetBackgroundColour()); SetForegroundColour(parent->GetForegroundColour()); SetFont(parent->GetFont()); m_labelButton = new MenuLabelButton(this, id, label, bitmap, wxCUSTBUT_BUTTON|flat); m_dropdownButton = new MenuDropButton(this, IDD_DROPDOWN_BUTTON, wxCUSTBUT_BUTTON|flat); 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 return TRUE;}#ifdef __WXMSW__// FIXME - I think there was a patch to fix thisvoid wxMenuButton::OnMenu( wxCommandEvent &event ) { event.Skip(); wxMenuItem *mi = m_menu->FindItem(event.GetId()); if (mi && (mi->GetKind() == wxITEM_RADIO)) m_menu->Check(event.GetId(), TRUE); }#endif // __WXMSW__void wxMenuButton::OnButton( wxCommandEvent &event){ int win_id = event.GetId(); if (win_id == IDD_DROPDOWN_BUTTON) { wxNotifyEvent mevent(wxEVT_MENUBUTTON_OPEN, GetId()); mevent.SetEventObject(this); if (GetEventHandler()->ProcessEvent(mevent) && !mevent.IsAllowed()) return; if (!m_menu) return; PopupMenu(m_menu, wxPoint(0, GetSize().y)); m_labelButton->Refresh(FALSE); m_dropdownButton->Refresh(FALSE); } else if (win_id == m_labelButton->GetId()) { wxCommandEvent cevent(wxEVT_COMMAND_MENU_SELECTED, win_id); cevent.SetEventObject(this); cevent.SetId(win_id); GetParent()->GetEventHandler()->ProcessEvent(cevent); if (!m_menu) return; const wxMenuItemList &items = m_menu->GetMenuItems(); int first_radio_id = -1; int checked_id = -1; bool check_next = FALSE; // find the next available radio item to check for (wxMenuItemList::Node *node = items.GetFirst(); node; node = node->GetNext()) { wxMenuItem *mi = (wxMenuItem*)node->GetData(); if (mi && (mi->GetKind() == wxITEM_RADIO)) { if (first_radio_id == -1) first_radio_id = mi->GetId(); if (check_next) { check_next = FALSE; checked_id = mi->GetId(); break; } else if (mi->IsChecked()) check_next = TRUE; } } // the last item was checked, go back to the first if (check_next && (first_radio_id != -1)) checked_id = first_radio_id; if (checked_id != -1) { m_menu->Check(checked_id, TRUE); wxCommandEvent mevent( wxEVT_COMMAND_MENU_SELECTED, checked_id); mevent.SetEventObject( m_menu ); mevent.SetInt(1); GetEventHandler()->ProcessEvent(mevent); } }}int wxMenuButton::GetSelection() const{ wxCHECK_MSG(m_menu != NULL, wxNOT_FOUND, wxT("No attached menu in wxMenuButton::GetSelection")); const wxMenuItemList &items = m_menu->GetMenuItems(); for (wxMenuItemList::Node *node = items.GetFirst(); node; node = node->GetNext()) { wxMenuItem *mi = (wxMenuItem*)node->GetData(); if (mi && (mi->GetKind() == wxITEM_RADIO)) { if (mi->IsChecked()) return mi->GetId(); } } return wxNOT_FOUND; }void wxMenuButton::AssignMenu(wxMenu *menu, bool static_menu){ if (!m_menu_static && m_menu) delete m_menu; m_menu = menu; m_menu_static = static_menu;}void wxMenuButton::SetToolTip(const wxString &tip) { wxWindow::SetToolTip(tip); ((wxWindow*)m_labelButton)->SetToolTip(tip); ((wxWindow*)m_dropdownButton)->SetToolTip(tip);}void wxMenuButton::SetToolTip(wxToolTip *tip) { wxWindow::SetToolTip(tip); ((wxWindow*)m_labelButton)->SetToolTip(tip); ((wxWindow*)m_dropdownButton)->SetToolTip(tip);}void wxMenuButton::DoSetSize(int x, int y, int width, int height, int sizeFlags){ wxSize curSize( GetSize() ); wxSize bestSize( DoGetBestSize() ); if (width == -1) width = curSize.GetWidth(); if (width < 10) width = bestSize.GetWidth(); if (height == -1) height = curSize.GetHeight(); if (height < 5) height = bestSize.GetHeight(); wxWindow::DoSetSize(x, y, width, height, sizeFlags); if (m_labelButton) m_labelButton->SetSize(0, 0, width - wxMENUBUTTON_DROP_WIDTH, height); if (m_dropdownButton) m_dropdownButton->SetSize(width-wxMENUBUTTON_DROP_WIDTH, 0, wxMENUBUTTON_DROP_WIDTH, height); }wxSize wxMenuButton::DoGetBestSize(){ if (!m_labelButton || !m_dropdownButton) return wxSize(wxMENUBUTTON_DROP_WIDTH+wxMENUBUTTON_DROP_HEIGHT, wxMENUBUTTON_DROP_HEIGHT); wxSize size = m_labelButton->GetBestSize(); size.x += wxMENUBUTTON_DROP_WIDTH; return size;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -