[wxWidgets]_[初级]_[自定义按钮]


场景:

1.现在的软件上的按钮都不是标准的按钮了,因为基本上是贴图上去的,正常情况下一种图片,鼠标移上去之后按钮显示另一种效果,按下去之后又是另一种效果。

2.wx的做法其实和mfc的按钮原理是一样的,就是给按钮贴图和重绘背景。


以下是源文件.

dh_bitmap_button.h


/*
 * File:   dh_bitmap_button.h
 * Author: Sai
 *
 * Created on 2009年12月29日, 下午4:08
 */

#ifndef _DH_BITMAP_BUTTON_H
#define	_DH_BITMAP_BUTTON_H

#include "wx/wx.h"

enum DhBitmapButtonStatus
{
    kDhBitmapButtonNormal,
    kDhBitmapButtonEnter,
    kDhBitmapButtonDown,
    kDhBitmapButtonUp,
    kDhBitmapButtonLeave,
    kDhBitmapButtonDClick,
    kDhBitmapButtonDisable
};

class DhBitmapButton : public wxControl
{
    DECLARE_DYNAMIC_CLASS(DhBitmapButton)
    DECLARE_EVENT_TABLE()
public:
    DhBitmapButton();
    virtual ~DhBitmapButton();

    DhBitmapButton(wxWindow* parent, wxWindowID id,
            const wxPoint& pos = wxDefaultPosition,
            const wxSize& size = wxDefaultSize,
            long style = wxBORDER_NONE,
            const wxValidator& validator = wxDefaultValidator);
    bool Create(wxWindow* parent, wxWindowID id,
            const wxPoint& pos = wxDefaultPosition,
            const wxSize& size = wxDefaultSize,
            long style = wxSUNKEN_BORDER,
            const wxValidator& validator = wxDefaultValidator);

    wxSize DoGetBestSize() const;
    void OnPaint(wxPaintEvent& event);
    virtual void OnEnter(wxMouseEvent& event);
    virtual void OnLeave(wxMouseEvent& event);
    virtual void OnDown(wxMouseEvent& event);
    virtual void OnDClick(wxMouseEvent& event);
    virtual void OnUp(wxMouseEvent& event);
    virtual bool Enable(bool enable = true);
    virtual bool Disable();
    /**
     * 设置正常图片
     *
     * @param bitmap
     */
    DhBitmapButton* set_normal_bitmap(wxBitmap* bitmap);

    /**
     * 1.设置按钮按下时的切换图片
     */
    DhBitmapButton* set_down_bitmap(wxBitmap* bitmap);

    /**
     * 1.设置按钮按经过时的切换图片
     */
    DhBitmapButton* set_enter_bitmap(wxBitmap* bitmap);

    /**
     * 1.设置Disable图片.
     *
     * @param bitmap
     * @return this
     */
    DhBitmapButton* set_disable_bitmap(wxBitmap* bitmap);

    DhBitmapButton* set_background(const wxBitmap& bitmap);

    bool SetBackgroundColour(const wxColour& colour);

protected:
    void DrawExistBitmap(wxDC* dc,wxBitmap* image1,wxBitmap* exist_image);

private:
    wxBitmap background_;
    bool is_used_bg_;

    wxBitmap* normal_bitmap_;
    wxBitmap* down_bitmap_;
    wxBitmap* enter_bitmap_;
    wxBitmap* disable_bitmap_;

    int button_status_;
    wxString text_;
    wxFont text_font_;

    void DrawBackground(wxDC* dc);

};
#endif	/* _DH_BITMAP_BUTTON_H */

dh_bitmap_button.cpp

/*
 * File:   DhBitmapButton.cpp
 * Author: Sai
 *
 * Created on 2009年12月29日, 下午4:08
 */

#include "dh_bitmap_button.h"

BEGIN_EVENT_TABLE(DhBitmapButton, wxControl)
EVT_PAINT(DhBitmapButton::OnPaint)
EVT_ENTER_WINDOW(DhBitmapButton::OnEnter)
EVT_LEAVE_WINDOW(DhBitmapButton::OnLeave)
EVT_LEFT_DOWN(DhBitmapButton::OnDown)
EVT_LEFT_DCLICK(DhBitmapButton::OnDClick)
EVT_LEFT_UP(DhBitmapButton::OnUp)
END_EVENT_TABLE()

IMPLEMENT_DYNAMIC_CLASS(DhBitmapButton, wxControl)

DhBitmapButton::DhBitmapButton()
{
}

DhBitmapButton::DhBitmapButton(wxWindow* parent, wxWindowID id,
        const wxPoint& pos,
        const wxSize& size,
        long style,
        const wxValidator& validator)
: normal_bitmap_(NULL), down_bitmap_(NULL), enter_bitmap_(NULL)
{
    Create(parent, id, pos, size, style, validator);
}

DhBitmapButton::~DhBitmapButton()
{
    wxDELETE(normal_bitmap_);
    wxDELETE(enter_bitmap_);
    wxDELETE(down_bitmap_);
}

bool DhBitmapButton::Create(wxWindow* parent, wxWindowID id,
        const wxPoint& pos,
        const wxSize& size,
        long style,
        const wxValidator& validator)
{
    normal_bitmap_ = NULL;
    down_bitmap_ = NULL;
    enter_bitmap_ = NULL;
    disable_bitmap_ = NULL;

    if (!wxControl::Create(parent, id, pos, size, style, validator))
    {
        return false;
    }
    SetBackgroundStyle(wxBG_STYLE_PAINT);
    is_used_bg_ = false;
    return true;
}

wxSize DhBitmapButton::DoGetBestSize() const
{
    return GetSize();
}

void DhBitmapButton::DrawExistBitmap(wxDC* dc, wxBitmap* image1,
        wxBitmap* exist_image)
{
    if (image1)
    {
        dc->DrawBitmap(*image1, 0, 0, true);

    } else
    {
        dc->DrawBitmap(*exist_image, 0, 0, true);
    }
}

void DhBitmapButton::OnPaint(wxPaintEvent& event)
{
    wxPaintDC dc(this);
    DrawBackground(&dc);
    //1.状态控制绘画,好处就是可以调用Refresh连背景一起刷新.
    switch (button_status_)
    {
        case kDhBitmapButtonNormal:
            dc.DrawBitmap(*normal_bitmap_, 0, 0, true);
            break;
        case kDhBitmapButtonEnter:
            if (!enter_bitmap_)
            {
                int width = DoGetBestSize().GetWidth();
                int height = DoGetBestSize().GetHeight();
                wxClientDC dc(this);
                dc.SetPen(*wxRED_PEN);
                dc.SetBrush(*wxTRANSPARENT_BRUSH);

                dc.DrawRectangle(0, 0, width, height);
                break;
            }
            dc.DrawBitmap(*enter_bitmap_, 0, 0, true);
            break;
        case kDhBitmapButtonDown:
            DrawExistBitmap(&dc,down_bitmap_,normal_bitmap_);
            break;
        case kDhBitmapButtonUp:
        	dc.DrawBitmap(*normal_bitmap_, 0, 0, true);
            break;
        case kDhBitmapButtonLeave:
            dc.DrawBitmap(*normal_bitmap_, 0, 0, true);
            break;
        case kDhBitmapButtonDClick:
            DrawExistBitmap(&dc,down_bitmap_,normal_bitmap_);
            break;
        case kDhBitmapButtonDisable:
            DrawExistBitmap(&dc,disable_bitmap_,normal_bitmap_);
            break;
        default:
            dc.DrawBitmap(*normal_bitmap_, 0, 0, true);
            break;
    }

}

void DhBitmapButton::DrawBackground(wxDC* dc)
{
    if (is_used_bg_)
    {
        dc->DrawBitmap(background_, 0, 0, true);
    } else
    {
        wxBrush brush(GetBackgroundColour());
        wxPen pen(GetBackgroundColour());
        dc->SetBrush(brush);
        dc->SetPen(pen);
        dc->DrawRectangle(0, 0, GetSize().x, GetSize().y);
    }
}

void DhBitmapButton::OnEnter(wxMouseEvent& event)
{
    button_status_ = kDhBitmapButtonEnter;
    Refresh();
    Update();
}

void DhBitmapButton::OnLeave(wxMouseEvent& event)
{
    if (!IsEnabled())
    {
        return;
    }
    button_status_ = kDhBitmapButtonLeave;
    Refresh();
    Update();
}

void DhBitmapButton::OnDClick(wxMouseEvent& event)
{
    button_status_ = kDhBitmapButtonDown;
    Refresh(false);
    Update();
}

void DhBitmapButton::OnDown(wxMouseEvent& event)
{
    button_status_ = kDhBitmapButtonDown;
    Refresh();
    Update();
}

void DhBitmapButton::OnUp(wxMouseEvent& event)
{
    if (kDhBitmapButtonDown != button_status_)
    {
        return;
    }
    button_status_ = kDhBitmapButtonUp;
    Refresh();
    Update();
    wxCommandEvent myEvent(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
    myEvent.SetEventObject(this);
    GetEventHandler()->ProcessEvent(myEvent);
}

DhBitmapButton* DhBitmapButton::set_normal_bitmap(wxBitmap* bitmap)
{
    normal_bitmap_ = bitmap;
    return this;
}

DhBitmapButton* DhBitmapButton::set_down_bitmap(wxBitmap* bitmap)
{
    down_bitmap_ = bitmap;
    return this;
}

DhBitmapButton* DhBitmapButton::set_enter_bitmap(wxBitmap* bitmap)
{
    enter_bitmap_ = bitmap;
    return this;
}

bool DhBitmapButton::Enable(bool enable)
{
    if (enable)
    {
        button_status_ = kDhBitmapButtonNormal;
    } else
    {
        button_status_ = kDhBitmapButtonDisable;
    }

    Refresh(false);
    Update();
    return wxControl::Enable(enable);
}

bool DhBitmapButton::Disable()
{
    return Enable(false);
}

DhBitmapButton* DhBitmapButton::set_disable_bitmap(wxBitmap* bitmap)
{
    disable_bitmap_ = bitmap;
    return this;
}

DhBitmapButton* DhBitmapButton::set_background(const wxBitmap& bitmap)
{
    is_used_bg_ = true;
    background_ = bitmap;
    return this;
}

bool DhBitmapButton::SetBackgroundColour(const wxColour& colour)
{
    is_used_bg_ = false;
    return wxControl::SetBackgroundColour(colour);
}

调用方式和wxButton一样.

1.先注册事件映射宏.

EVT_BUTTON(Minimal_StartSimplePopup, MyFrame::OnStartSimplePopup)

2.调用代码.

 wxBitmap* normal = new wxBitmap("./resources/start/start_normal.png",
        wxBITMAP_TYPE_PNG);
    wxBitmap* down = new wxBitmap("./resources/start/start_pressed.png",
        wxBITMAP_TYPE_PNG);
    wxBitmap* enter = new wxBitmap("./resources/start/start_current.png",
        wxBITMAP_TYPE_PNG);
    wxBitmap* disable = new wxBitmap("./resources/start/stop_normal.png",
        wxBITMAP_TYPE_PNG);
    wxBitmap bg = GetPositionBackgroundBitmap(0,0,normal->GetWidth(),normal->GetHeight());
    start = new DhBitmapButton(page,Minimal_StartSimplePopup,wxPoint(0,0),
        normal->GetSize());
    start->set_normal_bitmap(normal)->set_down_bitmap(down)->set_enter_bitmap(enter);
    start->set_disable_bitmap(disable);
    start->set_background(bg);


wxBitmap MyFrame::GetPositionBackgroundBitmap(int x, int y,
        int width,int height)
{
    wxRect rect;
    rect.x = x;
    rect.y = y;
    rect.width = width;
    rect.height = height;
    wxBitmap temp = this->bg.GetSubBitmap(rect);
    return temp;
}


3.当然我觉得有更好的方式.

比如重载这个类.wxBitmapButton





你可能感兴趣的:(C++,wxwidgets,自定义按钮)