自己封装了一个SDL按钮类,主要是实现了三种状态的切换(鼠标移入,移出,左键单击)和左键单击消息的响应(回调函数)
头文件代码
#ifndef BRBUTTON_H_
#define BRBUTTON_H_
#include "SDL.h"
typedef enum _BrButtonStatus {
BR_BUTTON_STATUS_OUT = 1,
BR_BUTTON_STATUS_IN = 2,
BR_BUTTON_STATUS_PRESSED = 3,
} BrButtonStatus;
class CBrButton{
public:
/**按钮的显示区域**/
SDL_Rect m_rcButton;
/**按钮是否显示**/
bool m_bShow;
/**按钮是否监听事件**/
bool m_bListen;
/**按钮标识**/
int m_iId;
CBrButton();
~CBrButton();
void CreateTexture(SDL_Surface* effectIn, SDL_Surface* effectOut,
SDL_Surface* effectPressed);
//处理事件
bool handleEvent(SDL_Event & stEvent);
/**回调函数**/
void setFuncPressed(void (*func_pressed)(const CBrButton *));
void SetRect(const SDL_Rect &rc);
SDL_Rect GetRect();
void SetRenderer(SDL_Renderer* renderer);
void Draw();
private:
/**鼠标在按钮内的显示**/
SDL_Texture* m_pTextureIn;
/**鼠标在按钮外的显示**/
SDL_Texture* m_pTextureOut;
/**鼠标在按钮按下的显示**/
SDL_Texture* m_pTexturePressed;
/**鼠标当前状态**/
BrButtonStatus m_status;
SDL_Renderer* m_pRenderer;
bool bPointIn(int x, int y);
void (*m_func_pressed)(const CBrButton * pButton);
SDL_Texture * GetShowTexture();
};
#endif /* BRBUTTON_H_ */
实现文件代码
#include "BrButton.h"
CBrButton::CBrButton() {
m_bShow = true;
m_bListen = true;
m_status = BR_BUTTON_STATUS_OUT;
m_func_pressed = NULL;
m_iId = 0;
m_rcButton.x = 0;
m_rcButton.y = 0;
m_rcButton.w = 0;
m_rcButton.h = 0;
m_pTextureIn = NULL;
m_pTextureOut = NULL;
m_pTexturePressed = NULL;
m_pRenderer = NULL;
}
CBrButton::~CBrButton() {
if (NULL != m_pTextureIn)
{
SDL_DestroyTexture(m_pTextureIn);
}
if (NULL != m_pTextureOut)
{
SDL_DestroyTexture(m_pTextureOut);
}
if (NULL != m_pTexturePressed)
{
SDL_DestroyTexture(m_pTexturePressed);
}
}
void CBrButton::setFuncPressed(void (*func_pressed)(const CBrButton *)) {
m_func_pressed = func_pressed;
}
void CBrButton::CreateTexture(SDL_Surface* surfaceIn, SDL_Surface* surfaceOut,
SDL_Surface* surfacePressed) {
if (NULL != m_pRenderer)
{
if (NULL == m_pTextureIn)
{
m_pTextureIn = SDL_CreateTextureFromSurface(m_pRenderer, surfaceIn);
}
if (NULL == m_pTextureOut)
{
m_pTextureOut = SDL_CreateTextureFromSurface(m_pRenderer, surfaceOut);
}
if (NULL == m_pTexturePressed)
{
m_pTexturePressed = SDL_CreateTextureFromSurface(m_pRenderer, surfacePressed);
}
}
}
bool CBrButton::bPointIn(int x, int y) {
if (x >= m_rcButton.x && x <= (m_rcButton.x+m_rcButton.w) && y >= m_rcButton.y && y <= (m_rcButton.y+m_rcButton.h))
{
return true;
}
else
{
return false;
}
}
bool CBrButton::handleEvent(SDL_Event & stEvent) {
if (!m_bListen) {
return false;
}
bool bRet = false;
if (stEvent.type == SDL_MOUSEMOTION) {
if (m_status == BR_BUTTON_STATUS_IN
|| m_status == BR_BUTTON_STATUS_OUT) {
if (bPointIn(stEvent.motion.x, stEvent.motion.y)) {
m_status = BR_BUTTON_STATUS_IN;
bRet = true;
} else {
m_status = BR_BUTTON_STATUS_OUT;
}
} else if (m_status == BR_BUTTON_STATUS_PRESSED) {
if (!bPointIn(stEvent.motion.x, stEvent.motion.y)) {
m_status = BR_BUTTON_STATUS_OUT;
}
}
} else if (stEvent.type == SDL_MOUSEBUTTONDOWN) {
if (bPointIn(stEvent.button.x, stEvent.button.y)) {
m_status = BR_BUTTON_STATUS_PRESSED;
bRet = true;
}
} else if (stEvent.type == SDL_MOUSEBUTTONUP) {
BrButtonStatus oldStatus = m_status;
if (bPointIn(stEvent.button.x, stEvent.button.y)) {
m_status = BR_BUTTON_STATUS_IN;
bRet = true;
} else {
m_status = BR_BUTTON_STATUS_OUT;
}
if (oldStatus == BR_BUTTON_STATUS_PRESSED) {
if (m_func_pressed != NULL) {
m_func_pressed(this);
bRet = true;
}
}
}
return bRet;
}
SDL_Texture * CBrButton::GetShowTexture() {
if (m_status == BR_BUTTON_STATUS_IN) {
return m_pTextureIn;
} else if (m_status == BR_BUTTON_STATUS_PRESSED) {
return m_pTexturePressed;
} else {
return m_pTextureOut;
}
}
void CBrButton::SetRect(const SDL_Rect &rc)
{
m_rcButton = rc;
}
SDL_Rect CBrButton::GetRect()
{
return m_rcButton;
}
void CBrButton::SetRenderer(SDL_Renderer* renderer)
{
if (NULL != renderer)
{
m_pRenderer = renderer;
}
}
void CBrButton::Draw()
{
if (NULL != m_pRenderer)
{
SDL_RenderCopy(m_pRenderer, GetShowTexture(), NULL, &m_rcButton);//将pTexture绘制到Render
}
}
使用步骤
1、生成一个按钮对象并设置按钮显示区域
CBrButton brBtn;
SDL_Rect rc;
rc.x = 50;
rc.y = 50;
rc.w = 50;
rc.h = 50;
brBtn.SetRect(rc);
SDL_Rect rc;
rc.x = 50;
rc.y = 50;
rc.w = 50;
rc.h = 50;
brBtn.SetRect(rc);
2、为按钮设置渲染器
brBtn.SetRenderer(pRenderer);
3、分别创建三态Texture
SDL_Surface *pSurfaceIn = SDL_LoadBMP("C:\\in.bmp");
SDL_Surface *pSurfaceOut = SDL_LoadBMP("C:\\out.bmp");
SDL_Surface *pSurfacePre = SDL_LoadBMP("C:\\pre.bmp");
brBtn.CreateTexture(pSurfaceIn, pSurfaceOut, pSurfacePre);
SDL_FreeSurface(pSurfaceIn);
SDL_FreeSurface(pSurfaceOut);
SDL_FreeSurface(pSurfacePre);
SDL_Surface *pSurfaceIn = SDL_LoadBMP("C:\\in.bmp");
SDL_Surface *pSurfaceOut = SDL_LoadBMP("C:\\out.bmp");
SDL_Surface *pSurfacePre = SDL_LoadBMP("C:\\pre.bmp");
brBtn.CreateTexture(pSurfaceIn, pSurfaceOut, pSurfacePre);
SDL_FreeSurface(pSurfaceIn);
SDL_FreeSurface(pSurfaceOut);
SDL_FreeSurface(pSurfacePre);
4、设置左键单击回调函数(如果需要响应左键单击)
brBtn.setFuncPressed(func_BRClick);
brBtn.setFuncPressed(func_BRClick);
5、在消息循环中响应消息
brBtn.handleEvent(sdl_event);
6、在合适的位置进行绘制
brBtn.Draw();
效果
蝴蝶是背景图,中间外字是按钮区域