【raylib】绘制button

#ifndef BUTTON_HPP
#define BUTTON_HPP
#include<raylib.h>
#include<string>
#include"EventBus.hpp"

class Button
{
public:
	Button(float posX, float posY, float width, float height, float roundness=0.0f, Color boundColor = Color{ BLACK }, Color contentColor = Color{ GRAY },float boundThick=1.0f) 
		:posX_(posX), posY_(posY), width_(width), height_(height), roundness_(roundness)
	{
		boundColor_ = boundColor;
		contentColor_ = contentColor;
		boundThick_ = boundThick;
	}

	Button(Rectangle rec, float roundness=0.0f, Color boundColor = Color{ BLACK }, Color contentColor = Color{ GRAY }, float boundThick=1.0f)
		:Button(rec.x, rec.y, rec.width, rec.height, roundness, boundColor, contentColor, boundThick)
	{
		boundColor_ = boundColor;
		contentColor_ = contentColor;
		boundThick_ = boundThick;
	}

	void setText(std::string text, int textFont=20)
	{
		textFont_ = textFont;
		text_ = std::move(text);
	}

	int registerEvent(EventType eventType, EventHandler eventHandler)
	{
		return eventBus_.subscribe(eventType, eventHandler);
	}
	
	bool unRegisterEvent(EventType eventType, int handlerId)
	{
		return eventBus_.unSubscribe(eventType, handlerId);
	}

	void update()
	{
		if (isMouseHover() && (!IsMouseButtonDown(MOUSE_BUTTON_LEFT)))
		{
			state_ = State::Hover;
			//TraceLog(LOG_INFO, "Hover");
		}
		else if (isMouseHover() && IsMouseButtonDown(MOUSE_BUTTON_LEFT))
		{
			state_ = State::Pressed;
			//TraceLog(LOG_INFO, "Presssed");
		}
		else 
		{
			state_ = State::Normal;
			//TraceLog(LOG_INFO, "Normal");
		}

		Draw();
		eventBus_.pollEvents();
	}


private:
	float posX_;
	float posY_;
	float width_=100;
	float height_=50;
	float roundness_ = 0.0f;
	Color boundColor_;
	Color contentColor_;
	float boundThick_ = 5.0f;
	bool visible = true;
	int textFont_ = 20;
	std::string text_{};
	enum class State
	{
		Normal,
		Hover,
		Pressed
	};
	State state_;

	EventBus eventBus_;

	bool isMouseHover()
	{
		Vector2 posMouseCur = GetMousePosition();
		if ((posMouseCur.x - posX_) >= 0 && (posMouseCur.x - posX_) <= width_ && (posMouseCur.y - posY_) >= 0 && (posMouseCur.y - posY_) <= height_)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	void virtual Draw()
	{
		if (!visible)
			return;

		int tw = MeasureText(text_.c_str(), textFont_);
		switch (state_)
		{
		case State::Normal:
			contentColor_ = { GRAY };
			break;
		case State::Hover:
			contentColor_ = { SKYBLUE };
			//TraceLog(LOG_INFO, "Hover");
			break;
		case State::Pressed:
			contentColor_ = { DARKBLUE };
			break;
		default:
			break;
		}
		if (roundness_ == 0.0f)
		{
			//绘制矩形边框
			DrawRectangleLinesEx(Rectangle{ posX_, posY_, width_, height_ }, boundThick_, boundColor_);
			//绘制矩形
			DrawRectangle(posX_ + boundThick_, posY_ + boundThick_, width_- boundThick_*2, height_- boundThick_*2, contentColor_);
		}
		else
		{
			DrawRectangleRoundedLinesEx(Rectangle{ posX_, posY_, width_, height_ }, roundness_, 10, boundThick_, boundColor_);
			/*DrawRectangleRounded(Rectangle{ posX_ + boundThick_, posY_ + boundThick_, width_ - boundThick_ * 2, height_ - boundThick_ * 2 },
				roundness_, 100, contentColor_);*/
			DrawRectangleRounded(Rectangle{ posX_, posY_, width_, height_ },
				roundness_, 10, contentColor_);
		}
		//绘制文字
		DrawText(text_.c_str(), posX_+(width_-tw)*0.5f, posY_+(height_-textFont_)*0.5f, textFont_, Color{BLACK});
	}
	
};

#endif // !BUTTON_HPP
#include<iostream>
#include<raylib.h>
#include "Control/Button.hpp"


int main()
{
    //加载资源
    Image img = LoadImage("./res/BingWallpaper.jpg");
    InitAudioDevice();
    Music bgm = LoadMusicStream("./res/bgm.mp3");
    Sound se = LoadSound("./res/se.mp3");
    int circle_x = img.width*0.5f;
    int circle_y = img.height*0.5f;
	bool isBgmStop = false;

    //创建窗口
    SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);
    InitWindow(800, 600, "title");
    //Texture2D texture = LoadTextureFromImage(img);
    SetTargetFPS(120);
    PlayMusicStream(bgm);

	Button btn(300, 300, 100, 50, 0.4f);
	//Button btn(300, 300, 100, 50);
   
    for (int i = 0;i < 10;i++)
    {
		int id = btn.registerEvent(EventType::MouseButtonPressed, [i](std::shared_ptr<Event> event) {
			TraceLog(LOG_INFO, std::to_string((int)event->type).c_str());
			});
    }

    for (int i = 0;i < 10;i++)
    {
		int id = btn.registerEvent(EventType::KeyPressed, [i](std::shared_ptr<Event> event) {
            auto ev = dynamic_cast<KeyEvent*>(event.get());
			TraceLog(LOG_INFO, std::to_string((int)ev->key).c_str());
			});
    }

    btn.unRegisterEvent(EventType::MouseButtonPressed, 0);

    while (!WindowShouldClose())
    {
        //绘图
        BeginDrawing();
        ClearBackground(WHITE); 
        
        //DrawTextureEx(texture, Vector2{0,0}, 0, 1, WHITE);
        //绘制元素
        //DrawCircle(circle_x, circle_y, 10, RED);
        //DrawCircleGradient(circle_x, circle_y, 10.0f, WHITE, RED);  // 中心白,边缘红
        btn.setText("click me", 10);
        btn.update();
        
        EndDrawing();
    }
    CloseWindow();
    CloseAudioDevice();
	return 0;
}

posted @ 2026-01-19 16:56  仰望星河Leon  阅读(1)  评论(0)    收藏  举报