📄 captionbar.cpp
字号:
/////////////////////////////////////////////////////////////////////////////// Name: captionbar.cpp// Purpose: wxCaptionBar class belonging to the wxFoldPanel (but can be used independent)// Author: Jorgen Bodde// Modified by: ABX - 19/12/2004 : possibility of horizontal orientation// : wxWidgets coding standards// Created: 18/06/2004// RCS-ID: $Id: captionbar.cpp,v 1.6 2005/09/23 12:47:46 MR Exp $// Copyright: (c) Jorgen Bodde// Licence: wxWindows licence/////////////////////////////////////////////////////////////////////////////// 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"#endif#include "wx/foldbar/foldpanelbar.h"/* * wxCaptionBar */BEGIN_EVENT_TABLE(wxCaptionBar, wxWindow) EVT_PAINT(wxCaptionBar::OnPaint) EVT_CHAR(wxCaptionBar::OnChar) EVT_MOUSE_EVENTS(wxCaptionBar::OnMouseEvent) EVT_SIZE(wxCaptionBar::OnSize)END_EVENT_TABLE()wxCaptionBar::wxCaptionBar(wxWindow* parent, const wxString &caption, wxImageList *images, wxWindowID id, const wxCaptionBarStyle &cbstyle, const wxPoint& pos, const wxSize& size, long style) : wxWindow(parent, id, pos, size, style) , m_caption(caption) , m_foldIcons(images) , m_rightIndent(wxFPB_BMP_RIGHTSPACE) , m_iconWidth(16) , m_iconHeight(16) , m_collapsed(false){ // do initialisy thingy stuff ApplyCaptionStyle(cbstyle, true); // set initial size if(m_foldIcons) { wxASSERT(m_foldIcons->GetImageCount() > 1); m_foldIcons->GetSize(0, m_iconWidth, m_iconHeight); }}wxCaptionBar::~wxCaptionBar(){}void wxCaptionBar::ApplyCaptionStyle(const wxCaptionBarStyle &cbstyle, bool applyDefault){ wxASSERT(GetParent()); wxCaptionBarStyle newstyle = cbstyle; // set defaults in newly created style copy if needed if(applyDefault) { // get first colour from style or make it default if(!newstyle.FirstColourUsed()) newstyle.SetFirstColour(*wxWHITE); // get second colour from style or make it default if(!newstyle.SecondColourUsed()) { // make the second colour slightly darker then the background wxColour col = GetParent()->GetBackgroundColour(); col.Set((unsigned char)((col.Red() >> 1) + 20), (unsigned char)((col.Green() >> 1) + 20), (unsigned char)((col.Blue() >> 1) + 20)); newstyle.SetSecondColour(col); } // get text colour if(!newstyle.CaptionColourUsed()) newstyle.SetCaptionColour(*wxBLACK); // get font colour if(!newstyle.CaptionFontUsed()) newstyle.SetCaptionFont(GetParent()->GetFont()); // apply caption style if(!newstyle.CaptionStyleUsed()) newstyle.SetCaptionStyle(wxCAPTIONBAR_GRADIENT_V); } // apply the style m_captionStyle = newstyle;}void wxCaptionBar::OnPaint(wxPaintEvent& WXUNUSED(event)){ wxPaintDC dc(this); wxRect wndRect = GetRect(); bool vertical = IsVertical(); // TODO: Maybe first a memory DC should draw all, and then paint it on the // caption. This way a flickering arrow during resize is not visible // draw basics FillCaptionBackground(dc); dc.SetFont(m_captionStyle.GetCaptionFont()); if(vertical) dc.DrawText(m_caption, 4, (wxFPB_EXTRA_Y / 2)); else dc.DrawRotatedText(m_caption, (wxFPB_EXTRA_Y / 2) , wndRect.GetBottom() - 4 , 90 ); // draw small icon, either collapsed or expanded // based on the state of the bar. If we have // any bmp's if(m_foldIcons) { wxCHECK2(m_foldIcons->GetImageCount() > 1, return); int index = 0; if(m_collapsed) index = 1; if(vertical) m_foldIcons->Draw(index, dc, wndRect.GetRight() - m_iconWidth - m_rightIndent, (wndRect.GetHeight() - m_iconHeight) / 2, wxIMAGELIST_DRAW_TRANSPARENT); else m_foldIcons->Draw(index, dc, (wndRect.GetWidth() - m_iconWidth) / 2, m_rightIndent, wxIMAGELIST_DRAW_TRANSPARENT); }}void wxCaptionBar::FillCaptionBackground(wxPaintDC &dc){ // dispatch right style for caption drawing switch(m_captionStyle.GetCaptionStyle()) { case wxCAPTIONBAR_GRADIENT_V: if (IsVertical()) DrawVerticalGradient(dc, GetRect()); else DrawHorizontalGradient(dc, GetRect()); break; case wxCAPTIONBAR_GRADIENT_H: if (IsVertical()) DrawHorizontalGradient(dc, GetRect()); else DrawVerticalGradient(dc, GetRect()); break; case wxCAPTIONBAR_SINGLE: DrawSingleColour(dc, GetRect()); break; case wxCAPTIONBAR_RECTANGLE: case wxCAPTIONBAR_FILLED_RECTANGLE: DrawSingleRectangle(dc, GetRect()); break; default: break; }}void wxCaptionBar::OnMouseEvent(wxMouseEvent& event){ // if clicked on the arrow (single) or double on the caption // we change state and an event must be fired to let this // panel collapse or expand bool send_event = false; if (event.LeftDown() && m_foldIcons) { wxPoint pt(event.GetPosition()); wxRect rect = GetRect(); bool vertical = IsVertical(); if((vertical && pt.x > (rect.GetWidth() - m_iconWidth - m_rightIndent))|| (!vertical && pt.y < m_iconHeight + m_rightIndent)) send_event = true; } else if(event.LeftDClick()) send_event = true; // send the collapse, expand event to the parent if(send_event) { wxCaptionBarEvent event(wxEVT_CAPTIONBAR); event.SetCaptionBar(this); ::wxPostEvent(this, event); }}void wxCaptionBar::OnChar(wxKeyEvent &event){ // TODO: Anything here? event.Skip();}wxSize wxCaptionBar::DoGetBestSize() const{ int x,y; if(IsVertical()) GetTextExtent(m_caption, &x, &y); else GetTextExtent(m_caption, &y, &x); if(x < m_iconWidth) x = m_iconWidth; if(y < m_iconHeight) y = m_iconHeight; // TODO: The extra wxFPB_EXTRA_X constants should be adjustable as well return wxSize(x + wxFPB_EXTRA_X, y + wxFPB_EXTRA_Y);}void wxCaptionBar::DrawVerticalGradient(wxDC &dc, const wxRect &rect ){ // gradient fill from colour 1 to colour 2 with top to bottom if(rect.height < 1 || rect.width < 1) return; int size = rect.height; dc.SetPen(*wxTRANSPARENT_PEN); // calculate gradient coefficients wxColour col2 = m_captionStyle.GetSecondColour(), col1 = m_captionStyle.GetFirstColour(); double rstep = double((col2.Red() - col1.Red())) / double(size), rf = 0, gstep = double((col2.Green() - col1.Green())) / double(size), gf = 0, bstep = double((col2.Blue() - col1.Blue())) / double(size), bf = 0; wxColour currCol; for(int y = rect.y; y < rect.y + size; y++) { currCol.Set( (unsigned char)(col1.Red() + rf), (unsigned char)(col1.Green() + gf), (unsigned char)(col1.Blue() + bf) ); dc.SetBrush( wxBrush( currCol, wxSOLID ) ); dc.DrawRectangle( rect.x, rect.y + (y - rect.y), rect.width, size ); //currCol.Set(currCol.Red() + rstep, currCol.Green() + gstep, currCol.Blue() + bstep); rf += rstep; gf += gstep; bf += bstep; }}void wxCaptionBar::DrawHorizontalGradient(wxDC &dc, const wxRect &rect ){ // gradient fill from colour 1 to colour 2 with left to right if(rect.height < 1 || rect.width < 1) return; int size = rect.width; dc.SetPen(*wxTRANSPARENT_PEN); // calculate gradient coefficients wxColour col2 = m_captionStyle.GetSecondColour(), col1 = m_captionStyle.GetFirstColour(); double rstep = double((col2.Red() - col1.Red())) / double(size), rf = 0, gstep = double((col2.Green() - col1.Green())) / double(size), gf = 0, bstep = double((col2.Blue() - col1.Blue())) / double(size), bf = 0; wxColour currCol; for(int x = rect.x; x < rect.x + size; x++) { currCol.Set( (unsigned char)(col1.Red() + rf), (unsigned char)(col1.Green() + gf), (unsigned char)(col1.Blue() + bf) ); dc.SetBrush( wxBrush( currCol, wxSOLID ) ); dc.DrawRectangle( rect.x + (x - rect.x), rect.y, 1, rect.height ); rf += rstep; gf += gstep; bf += bstep; }}void wxCaptionBar::DrawSingleColour(wxDC &dc, const wxRect &rect ){ // single colour fill. This is the most easy one to find if(rect.height < 1 || rect.width < 1) return; dc.SetPen(*wxTRANSPARENT_PEN); // draw simple rectangle dc.SetBrush( wxBrush( m_captionStyle.GetFirstColour(), wxSOLID ) ); dc.DrawRectangle( rect.x, rect.y, rect.width, rect.height );}void wxCaptionBar::DrawSingleRectangle(wxDC &dc, const wxRect &rect ){ wxASSERT(GetParent()); // single colour fill. This is the most easy one to find if(rect.height < 2 || rect.width < 1) return; // single frame, set up internal fill colour wxBrush br; br.SetStyle(wxSOLID); if(m_captionStyle.GetCaptionStyle() == wxCAPTIONBAR_RECTANGLE) br.SetColour(GetParent()->GetBackgroundColour()); else br.SetColour(m_captionStyle.GetFirstColour()); // setup the pen frame wxPen pen(m_captionStyle.GetSecondColour()); dc.SetPen(pen); dc.SetBrush( br ); dc.DrawRectangle( rect.x, rect.y, rect.width, rect.height - 1); wxPen bgpen(GetParent()->GetBackgroundColour()); dc.SetPen(bgpen); dc.DrawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width, rect.y + rect.height - 1);}void wxCaptionBar::OnSize(wxSizeEvent &event){ wxSize size = event.GetSize(); if(m_foldIcons) { // What I am doing here is simply invalidating the part of the window exposed. So when I // make a rect with as width the newly exposed part, and the x,y of the old window size origin, // I don't need a bitmap calulation in it, or do I ? The bitmap needs redrawing anyway. Leave it // like this until I figured it out // set rect to redraw as old bitmap area which is entitled to redraw wxRect rect(size.GetWidth() - m_iconWidth - m_rightIndent, 0, m_iconWidth + m_rightIndent, m_iconWidth + m_rightIndent); // adjust rectangle when more is slided so we need to redraw all // the old stuff but not all (ugly flickering) int diffX = size.GetWidth() - m_oldSize.GetWidth(); if(diffX > 1) { // adjust the rect with all the crap to redraw rect.SetWidth(rect.GetWidth() + diffX + 10); rect.SetX(rect.GetX() - diffX - 10); } RefreshRect(rect); } else { wxRect rect = GetRect(); RefreshRect(rect); } m_oldSize = size;}void wxCaptionBar::RedrawIconBitmap(){ if(m_foldIcons) { // invalidate the bitmap area and force a redraw wxRect rect = GetRect(); rect.SetX(rect.GetWidth() - m_iconWidth - m_rightIndent); rect.SetWidth(m_iconWidth + m_rightIndent); RefreshRect(rect); }}bool wxCaptionBar::IsVertical() const{ // parent of wxCaptionBar is wxFoldPanelItem // default is vertical wxFoldPanelItem *bar = wxDynamicCast(GetParent(), wxFoldPanelItem); wxCHECK_MSG( bar, true, _T("wrong parent") ); return bar->IsVertical();}/* * wxCaptionBarEvent */DEFINE_EVENT_TYPE(wxEVT_CAPTIONBAR)wxCaptionBarEvent::wxCaptionBarEvent(const wxCaptionBarEvent &event) : wxCommandEvent(event){ m_captionBar = event.m_captionBar;}//DEFINE_EVENT_TYPE(wxEVT_CAPTIONBAR)//IMPLEMENT_DYNAMIC_CLASS(wxCaptionBarEvent, wxEvent)IMPLEMENT_DYNAMIC_CLASS(wxCaptionBarEvent, wxCommandEvent)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -