This is Raylib C++ GUI Library I have made Button, Slider, Image Slider You can use this library as you wish. Example is [[raylib:slider_gui_만들기|Making Slider in Raylib Game]]. Example project is {{ :raylib:flappybird_11.zip |Using Image Slider and Image Check Box}} {{:raylib:raylibslider_checkbox.png?600|Raylib Image Slider and CheckBox}} ===== 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 #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 ===== #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