⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 captionbar.cpp

📁 很牛的GUI源码wxWidgets-2.8.0.zip 可在多种平台下运行.
💻 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 + -