목차

This is Raylib C++ GUI Library

I have made Button, Slider, Image Slider

You can use this library as you wish.

Example is Making Slider in Raylib Game.

Example project is Using Image Slider and Image Check Box

Raylib Image Slider and CheckBox

gui.h

gui.h
/*  =========================================
Raylib GUI Libary 
2023. 10. 30. 
Created by Dongkun Lee. 
Button, Slider, Image Slider 
Image Slider need 6 images 
    imgSlider = &_img[0];
    imgSliderBar = &_img[1];
    imgSliderLeftEnabled = &_img[2];
    imgSliderRightEnabled = &_img[3];
    imgSliderLeftDisabled = &_img[4];
    imgSliderRightDisabled = &_img[5];
*/
 
#pragma once
#include <string>
#include "raylib.h" 
#include "config.h"
#include "buttonActionMap.h"
 
class GUI
{
    public:
        GUI();
        GUI(int button_x, int button_y, int button_width, int button_height, std::string button_title, Font*  _font);
        virtual bool Update(); 
        virtual void Draw();
        void Tick();
        bool GetChecked();
        void Checked();
        void UnChecked();
 
    protected:
        int x, y, width, height;
        std::string title;
        bool isChecked = false;
        Rectangle rect;
        Font* font;
};
 
/*===============================
    boxenabled = _box[0]; 
    boxdisabled = _box[1];
    boxenalbedChecked = _box[2];
    boxdisabledChecked = _box[3];
    ===============================
*/
 
class GUICheckBox : public GUI
{
    private : 
        bool* isHasValue; 
 
        Texture2D* boxenabled;
        Texture2D* boxenalbedChecked;
        Texture2D* boxdisabled; 
        Texture2D* boxdisabledChecked;
 
    public :
        GUICheckBox();
        GUICheckBox(int box_x, int box_y, bool *isValue, Texture2D _box[]);
        virtual bool Update();
        virtual void Draw();
};
 
 
class GUISlider : public GUI
{
    protected:
        float padding;
        Rectangle leftButton;
        Rectangle rightButton;
 
        float *sliderValue;
        bool changeValueMode = false;
        void ValueUp();
        void ValueDown();
 
    public:
        enum class arrowCheck {
            none = 0, left, right, slider
        }; 
        GUISlider();
 
        GUISlider(int slider_x, int slider_y, int slider_width, int slider_height, std::string slider_title, Font *_font, float *value);
        virtual bool Update(); 
        virtual void Draw();
        bool MouseSliding();
 
        arrowCheck arrow = arrowCheck::none;
};
 
class GUISliderImg : public GUISlider
{
    private : 
        Texture2D* imgSlider;
        Texture2D* imgSliderBar;
        Texture2D* imgSliderLeftEnabled;
        Texture2D* imgSliderRightEnabled;
        Texture2D* imgSliderLeftDisabled;
        Texture2D* imgSliderRightDisabled;
 
    public : 
        GUISliderImg();
        GUISliderImg(int slider_x, int slider_y, int slider_width, int slider_height, std::string slider_title, Font *_font, float *value, Texture2D _img[]);
        virtual void Draw();
};

gui.cpp

gui.cpp
#include "gui.h"
 
Vector2 mousePoint = { 0.0f, 0.0f };
 
GUI::GUI()
{}
 
GUI::GUI(int button_x, int button_y, int button_width, int button_height, std::string button_title, Font*  _font)
{
    x = button_x;
    y = button_y;
    width = button_width;
    height = button_height;
    title = button_title;
    rect = Rectangle{float(x), float(y), float(width), float(height)};
    font = _font;
}
 
bool GUI::GetChecked()   
{
    return isChecked;
}
 
void GUI::Checked()    // 현재 버튼이 체크된 상태로 하기 
{
    isChecked = true;
    SetMousePosition(x + width / 2, y+height/2);  // 마우스 커서를 현재 버튼의 정중앙에 넣기 
}
 
void GUI::UnChecked()  // 현재 버튼이 체크 해제된 상태로 하기 
{
    isChecked = false;
}
 
bool GUI::Update()  // 마우스가 버튼 위에 위치해 있는지를 체크
{
    mousePoint = GetMousePosition();
 
    if (CheckCollisionPointRec(mousePoint, rect)) isChecked = true;
     else isChecked = false; 
 
    return false;
}
 
void GUI::Draw()  // 버튼 그리기
{
    DrawRectangle(x, y, width, height, DARKGREEN);   // 버튼을 그린다. 
 
    Vector2 length = MeasureTextEx(*font, title.c_str(), 32, 5); // 글자의 포인트는 32으로 가정할 것이다.  32으로 가정한 글자의 가로 픽셀 크기를 구한다. 
 
    // 텍스트 출력
    Vector2 pos = {(float)x  + (width / 2) - (length.x / 2), (float)y + (height /2) - (length.y / 2)};     // 글자를 가로 및 세로 가운데 정렬한다. 
    DrawTextEx(*font, title.c_str(), pos, 32, 5, DARKBROWN);  
 
    if (isChecked)
    {
        DrawRectangle(x, y, width, height, Color{255, 255, 255, 85});   // 버튼을 그린다. 
        DrawRectangleLinesEx(rect, 4, Fade(BLACK, 0.3f));         // 버튼 꾸미기
    }
}
 
void GUI::Tick()
{
    BeginDrawing();    
    Update();
    Draw();
    EndDrawing(); 
}
 
/* =========================================
    GUI CheckBox   made by Dongkun Lee  
    2023. 10. 30. 
    ========================================= */
GUICheckBox::GUICheckBox() {} 
 
GUICheckBox::GUICheckBox(int box_x, int box_y, bool *isValue, Texture2D _box[])
{
    boxenabled = &_box[0]; 
    boxdisabled = &_box[1];
    boxenalbedChecked = &_box[2];
    boxdisabledChecked = &_box[3];
 
    x = box_x;
    y = box_y;
    width = boxenabled->width;
    height = boxenabled->height;
    rect = Rectangle{float(x), float(y), float(width), float(height)}; 
 
    isHasValue = isValue;
}
 
bool GUICheckBox::Update()
{
    mousePoint = GetMousePosition();
 
    if (CheckCollisionPointRec(mousePoint, rect)) isChecked = true;
     else isChecked = false; 
 
    if (isChecked && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) *isHasValue = !*isHasValue;
 
    if (isChecked && IsButtonPressed("Jump")) *isHasValue = !*isHasValue;
 
 
    return false;
}
 
void GUICheckBox::Draw()
{
    if(isChecked)  //  마우스가 위에 있어서 활성화된 상태 
    {
        if (*isHasValue)  //  체크박스가 선택된 상태
            DrawTexture(*boxenalbedChecked, x, y, WHITE);
        else DrawTexture(*boxenabled, x, y, WHITE);  //  체크박스 선택 없음 
    }else //  마우스가 없어서  GUI가 비활성화된 상태 
    {
        if (*isHasValue) // 체크박스가 선택된 상태 
            DrawTexture(*boxdisabledChecked, x, y, WHITE);
        else DrawTexture(*boxdisabled, x, y, WHITE);
    }
}
 
 
/* =========================================
    GUI Slider   made by Dongkun Lee 
    2023. 10. 29. 
    ========================================= */
 
GUISlider::GUISlider() {}
 
GUISlider::GUISlider(int slider_x, int slider_y, int slider_width, int slider_height, std::string slider_title, Font* _font, float *value)
{
    x = slider_x;
    y = slider_y;
    width = slider_width;
    height = slider_height;
    title = slider_title;
    rect = Rectangle{float(x), float(y), float(width), float(height)};
    font = _font; 
    padding = 20.0f;
    leftButton = Rectangle{float(x) - padding -float(height), float(y), float(height), float(height) };
    rightButton = Rectangle{float(x) + float(width) + padding, float(y), float(height), float(height)};
    sliderValue = value;  // 슬라이더 값은 주소로 가져온다. 호출하는 쪽에서 값이 바뀌면 슬라이더 내부의 값도 바뀐다. 
}
 
bool GUISlider::Update()   // 슬라이더 조절 로직
{
    mousePoint = GetMousePosition();
 
    if (CheckCollisionPointRec(mousePoint, leftButton)) arrow = arrowCheck::left;  // 슬라이더의 왼쪽 버튼 체크 상태 확인
     else if (CheckCollisionPointRec(mousePoint, rightButton)) arrow = arrowCheck::right;  // 슬라이더의 오른쪽 버튼 체크 상태 확인
     else if (CheckCollisionPointRec(mousePoint, rect)) arrow = arrowCheck::slider;  // 마우스가 슬라이더를 가리키는지 확인
     else arrow = arrowCheck::none; 
 
    // 슬라이더의 왼쪽 버튼 
    if (arrow == arrowCheck::left && IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
    {
        ValueDown();
        return true;
    }
 
    // 슬라이더의 오른쪽 버튼 
    if (arrow == arrowCheck::right && IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
    {
        ValueUp();
        return true;
    }
 
    // 슬라이더가 선택된 상태에서는  좌우 키 조작이 가능하게 한다
    if (isChecked)
    {
        if (IsLeftAxisLeftChecked()) {ValueDown(); return true; } 
 
        if (IsLeftAxisRightChecked()) {ValueUp(); return true; }
    }
 
    return MouseSliding();
}
 
// 슬라이더의 값을 올리는 함수 
void GUISlider::ValueUp()
{
    *sliderValue += 0.1;
    if (*sliderValue >= 1.0f) *sliderValue = 1.0f;
}
 
// 슬라이더의 값을 내리는 함수
void GUISlider::ValueDown()
{
    *sliderValue -= 0.1;
    if (*sliderValue <= 0.0f) *sliderValue = 0.0f;
}
 
// 슬라이더 그리기
void GUISlider::Draw()
{
   // DrawRectangle(x, y, width, height, DARKGREEN);   // 버튼을 그린다. 
 
    // 슬라이더 그리기 
    if (isChecked)
    {
        DrawRectangle(x, y, width, height, Color{255, 255, 255, 85});   // 버튼을 그린다. 
        DrawRectangleLinesEx(rect, 4, Fade(BLACK, 0.3f));         // 버튼 꾸미기
    }else 
    {
        DrawRectangle(x, y, width, height, Color{255, 255, 255, 85});   // 버튼을 그린다. 
    }
 
    // 양옆에 화살표
    DrawRectangleRec(leftButton,  ORANGE );
    DrawRectangleRec(rightButton, ORANGE );
    DrawRectangle(x, y, width *  *(sliderValue), height, RAYWHITE);   // 버튼을 그린다. 슬라이더 값이 포인터형이므로 역참조로 해야 한다. 
 
    // 텍스트 출력
    // Vector2 length = MeasureTextEx(*font, title.c_str(), 32, 5); // 글자의 포인트는 32으로 가정할 것이다.  32으로 가정한 글자의 가로 픽셀 크기를 구한다. 
    // Vector2 pos = {(float)x  + (width / 2) - (length.x / 2), (float)y + (height /2) - (length.y / 2)};     // 글자를 가로 및 세로 가운데 정렬한다. 
    // DrawTextEx(*font, title.c_str(), pos, 32, 5, DARKBROWN);  
    DrawText(TextFormat("%.2f", *sliderValue),  x + width/2 - 16,  y + height/2 - 16, 32, WHITE); // 글자를 가로 및 세로 가운데 정렬한다. 
 
    // 화살표 선택했는지 여부 
    if (arrow == arrowCheck::left)
    {
        DrawRectangleLinesEx(leftButton, 4, Fade(BLACK, 0.3f));
    }else if (arrow == arrowCheck::right)
    {
        DrawRectangleLinesEx(rightButton, 4, Fade(BLACK, 0.3f));
    }else if (arrow == arrowCheck::slider)
    {
        DrawRectangleLinesEx(rect, 4, Fade(BLACK, 0.3f));
    }
}
 
// 마우스로 슬라이딩
bool GUISlider::MouseSliding()
{
        // 슬라이더의 가운데를 누른 상태 체크 
    if (arrow == arrowCheck::slider && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) changeValueMode = true;  // 마우스로 슬라이더 값을 조절 할 수 있음
 
    // 슬라이더 값을 조절할 수 있는 상태에서
    if (changeValueMode)
    {
        if (GetMousePosition().x >= rect.x + rect.width) SetMousePosition(rect.x + rect.width, rect.y + rect.height / 2);  // 마우스 범위 제한
        if (GetMousePosition().x <= rect.x) SetMousePosition(rect.x, rect.y + rect.height / 2);  // 마우스 범위 제한 
 
        float rawValue = GetMousePosition().x - rect.x;   // 현재 마우스의 위치를 통해 가로 값을 정하기
 
        if (rawValue <= 0) rawValue = 0;    // 슬라이더 가로 값의 좌측 한계 
        if (rawValue >= rect.width) rawValue = rect.width;  // 슬라이더 가로 값의 우측 한계 
 
        float perValue = rawValue / rect.width;  // 슬라이더 가로 값을 퍼센트로 만들기 
        *sliderValue = perValue;  // 슬라이더 값으로 넘겨주기
 
        if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT))   // 마우스 왼쪽 버튼을 떼면 볼륨 설정하고, 변환 모드를 해제함
        {
            changeValueMode = false;
            return true;   // 볼륨이 바뀌면 호출한 쪽에 true를 리턴해 준다
        }
 
        return false;
    }
    return false;
}
 
/* =========================================
    GUI SliderImg   made by Dongkun Lee 
    2023. 10. 30.
    Image Slider need 6 images 
    imgSlider = &_img[0];
    imgSliderBar = &_img[1];
    imgSliderLeftEnabled = &_img[2];
    imgSliderRightEnabled = &_img[3];
    imgSliderLeftDisabled = &_img[4];
    imgSliderRightDisabled = &_img[5];
     ========================================= */
 
GUISliderImg::GUISliderImg() {}
 
GUISliderImg::GUISliderImg(int slider_x, int slider_y, int slider_width, int slider_height, std::string slider_title, Font *_font, float *value, Texture2D _img[])
{
    x = slider_x;
    y = slider_y;
    width = slider_width;
    height = slider_height;
    title = slider_title;
    rect = Rectangle{float(x), float(y), float(width), float(height)};
    font = _font; 
    padding = 20.0f;
 
    sliderValue = value;  // 슬라이더 값은 주소로 가져온다. 호출하는 쪽에서 값이 바뀌면 슬라이더 내부의 값도 바뀐다.     
    imgSlider = &_img[0];
    imgSliderBar = &_img[1];
    imgSliderLeftEnabled = &_img[2];
    imgSliderRightEnabled = &_img[3];
    imgSliderLeftDisabled = &_img[4];
    imgSliderRightDisabled = &_img[5];
 
    leftButton = Rectangle{float(x) - padding -float(imgSliderLeftEnabled->width), float(y), float(imgSliderLeftEnabled->width), float(height) };
    rightButton = Rectangle{float(x) + float(width) + padding, float(y), float(imgSliderRightEnabled->width), float(height)};
 
}
 
void GUISliderImg::Draw()
{
    // 슬라이더 그리기 
    DrawTextureV(*imgSlider, Vector2{rect.x, rect.y}, WHITE); 
    if (isChecked) DrawRectangleLinesEx(rect, 4, Fade(RAYWHITE, 0.3f));         // 슬라이더 활성화 상태 그리기
 
    // 양옆에 화살표 그리기
    if (arrow == arrowCheck::left)
    {
        DrawTextureV(*imgSliderLeftEnabled, Vector2{leftButton.x, leftButton.y}, WHITE);
        DrawTextureV(*imgSliderRightDisabled, Vector2{rightButton.x, rightButton.y}, WHITE);
    }else if (arrow == arrowCheck::right)
    {
        DrawTextureV(*imgSliderLeftDisabled, Vector2{leftButton.x, leftButton.y}, WHITE);
        DrawTextureV(*imgSliderRightEnabled, Vector2{rightButton.x, rightButton.y}, WHITE);
    }else 
    {
        DrawTextureV(*imgSliderLeftDisabled, Vector2{leftButton.x, leftButton.y}, WHITE);
        DrawTextureV(*imgSliderRightDisabled, Vector2{rightButton.x, rightButton.y}, WHITE);
    }
 
    DrawTextureV(*imgSliderBar, Vector2{rect.x + rect.width * *(sliderValue) - imgSliderBar->width / 2 ,rect.y}, WHITE);
  //  DrawRectangle(x, y, width *  *(sliderValue), height, RAYWHITE);   // 슬라이더를 그린다. 슬라이더 값이 포인터형이므로 역참조로 해야 한다. 
 
    // 텍스트 출력
    DrawText(TextFormat("%.2f", *sliderValue),  x + width/2 - 16,  y + height/2 - 16, 32, WHITE); // 글자를 가로 및 세로 가운데 정렬한다.  
}

History

2023. 10. 28. GUI Slier 2023. 10. 29. GUI Image Slider(GUISliderImg) 2023. 10. 30. GUI CheckBox