diff --git a/seminar11_events/02_slider/Makefile b/seminar11_events/02_slider/Makefile new file mode 100644 index 0000000..579a8f1 --- /dev/null +++ b/seminar11_events/02_slider/Makefile @@ -0,0 +1,6 @@ +build: + g++ ./slider.cpp -std=c++11 -o slider -lsfml-graphics -lsfml-window -lsfml-system +build_debug: + g++ ./slider.cpp -std=c++11 -o slider -lsfml-graphics -lsfml-window -lsfml-system -D_DEBUG +build_circle: + g++ ./circle.cpp -std=c++11 -o circle -lsfml-graphics -lsfml-window -lsfml-system diff --git a/seminar11_events/02_slider/circle.cpp b/seminar11_events/02_slider/circle.cpp new file mode 100644 index 0000000..9d7b609 --- /dev/null +++ b/seminar11_events/02_slider/circle.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include "slider.hpp" + +int main() +{ + int result; + unsigned char r, g, b; + + sf::RenderWindow window(sf::VideoMode(800, 600), "Slider"); + window.setFramerateLimit(60); + + sf::Font font; + if (!font.loadFromFile("consolas.ttf")) { + std::cout << "Can't load button font" << std::endl; + } + + Slider slider(window, font, sf::Vector2f{200, 100}, 10, 250); + + Slider slider_r(window, font, sf::Vector2f{800, 200}, 0, 255); + Slider slider_g(window, font, sf::Vector2f{800, 300}, 0, 255); + Slider slider_b(window, font, sf::Vector2f{800, 400}, 0, 255); + + sf::CircleShape circle(10); + circle.setPosition(sf::Vector2f{400, 400}); + + while (window.isOpen()) { + sf::Event event; + while (window.pollEvent(event)) { + if (event.type == sf::Event::Closed) { + window.close(); + } + + result = slider.handleEvent(event); + + /* Centering of the circle */ + circle.setPosition(circle.getPosition() + sf::Vector2f{circle.getRadius() - result, circle.getRadius() - result}); + circle.setRadius(result); + + r = slider_r.handleEvent(event); + g = slider_g.handleEvent(event); + b = slider_b.handleEvent(event); + circle.setFillColor(sf::Color{r, g, b}); + } + window.clear(sf::Color::Black); + + slider.draw(); + slider_r.draw(); + slider_g.draw(); + slider_b.draw(); + + window.draw(circle); + window.display(); + } + return 0; +} diff --git a/seminar11_events/02_slider/consolas.ttf b/seminar11_events/02_slider/consolas.ttf new file mode 100644 index 0000000..a79deb5 Binary files /dev/null and b/seminar11_events/02_slider/consolas.ttf differ diff --git a/seminar11_events/02_slider/slider.cpp b/seminar11_events/02_slider/slider.cpp new file mode 100644 index 0000000..792be9b --- /dev/null +++ b/seminar11_events/02_slider/slider.cpp @@ -0,0 +1,36 @@ +#include +#include +#include +#include "slider.hpp" + +int main() +{ + int result; + + sf::RenderWindow window(sf::VideoMode(800, 600), "Slider"); + window.setFramerateLimit(60); + + sf::Font font; + if (!font.loadFromFile("consolas.ttf")) { + std::cout << "Can't load button font" << std::endl; + } + + Slider slider(window, font); + + while (window.isOpen()) { + sf::Event event; + while (window.pollEvent(event)) { + if (event.type == sf::Event::Closed) { + window.close(); + } + + result = slider.handleEvent(event); + std::cout << result << std::endl; + } + window.clear(sf::Color::Black); + + slider.draw(); + window.display(); + } + return 0; +} diff --git a/seminar11_events/02_slider/slider.hpp b/seminar11_events/02_slider/slider.hpp new file mode 100644 index 0000000..f72c090 --- /dev/null +++ b/seminar11_events/02_slider/slider.hpp @@ -0,0 +1,119 @@ +#pragma once +#include +#include +#include + +class Slider +{ +private: + inline static const sf::Color defaultColor {sf::Color(190, 210, 190)}; + inline static const sf::Color pressedColor {sf::Color(150, 170, 150)}; + inline static const sf::Color textColor {sf::Color::Black}; + inline static const int kCharacterSize = 14; + + int mMinValue; + int mMaxValue; + float mSliderPosition = 0; + + sf::RenderWindow& mRenderWindow; + sf::RectangleShape mSlider; + sf::RectangleShape mAxis; + sf::Text mText; + + /* Is slider pressed at the moment */ + bool mIsPressed = false; + + int onMousePressed(const sf::Event& event) + { + if (event.mouseButton.button == sf::Mouse::Left) { + sf::Vector2f mousePosition = mRenderWindow.mapPixelToCoords({event.mouseButton.x, event.mouseButton.y}); + if (mSlider.getGlobalBounds().contains(mousePosition)) + mIsPressed = true; + else if (mAxis.getGlobalBounds().contains(mousePosition)) + { + mIsPressed = true; + if (mousePosition.x + mSlider.getSize().x <= mAxis.getPosition().x + mAxis.getSize().x) { + mSlider.setPosition({mousePosition.x, mSlider.getPosition().y}); + mSliderPosition = (mSlider.getPosition().x - mAxis.getPosition().x) / (mAxis.getSize().x - mSlider.getSize().x); + } + else { + mSlider.setPosition({mAxis.getPosition().x + mAxis.getSize().x - mSlider.getSize().x, mSlider.getPosition().y}); + mSliderPosition = 1; + } + } + } + return mMinValue + (mMaxValue - mMinValue) * mSliderPosition; + } + + int onMouseMove(const sf::Event& event) + { + if (!mIsPressed) { + return mMinValue + (mMaxValue - mMinValue) * mSliderPosition; + } + sf::Vector2f mousePosition = mRenderWindow.mapPixelToCoords({event.mouseMove.x, event.mouseMove.y}); + if ((mousePosition.x >= mAxis.getPosition().x) && (mousePosition.x + mSlider.getSize().x <= mAxis.getPosition().x + mAxis.getSize().x)) { + mSlider.setPosition({mousePosition.x, mSlider.getPosition().y}); + } + else if (mousePosition.x < mAxis.getPosition().x) { + mSlider.setPosition({mAxis.getPosition().x, mSlider.getPosition().y}); + } + else if (mousePosition.x + mSlider.getSize().x > mAxis.getPosition().x + mAxis.getSize().x) { + mSlider.setPosition({mAxis.getPosition().x + mAxis.getSize().x - mSlider.getSize().x, mSlider.getPosition().y}); + } + + mSliderPosition = (mSlider.getPosition().x - mAxis.getPosition().x) / (mAxis.getSize().x - mSlider.getSize().x); + + return mMinValue + (mMaxValue - mMinValue) * mSliderPosition; + } + +public: + + Slider(sf::RenderWindow& window, const sf::Font& font, sf::Vector2f position = {100,200},int min = 0, int max = 100) : mRenderWindow(window) + { + mSlider.setFillColor(sf::Color::Red); + mSlider.setSize({10,30}); + mSlider.setPosition(position - sf::Vector2f{0, 10}); + mSlider.setOutlineColor(sf::Color::Black); + mSlider.setOutlineThickness(2); + + mAxis.setFillColor(defaultColor); + mAxis.setSize({500,10}); + mAxis.setPosition(position); + + std::stringstream ss; + ss << mMinValue; + mText.setString(ss.str()); + mText.setFont(font); + mText.setCharacterSize(kCharacterSize); + mText.setFillColor(sf::Color::White); + mText.setPosition(position + sf::Vector2f{mAxis.getSize().x + 10, -4}); + + mMinValue = min; + mMaxValue = max; + mIsPressed = false; + } + + void draw() + { + std::stringstream ss; + ss << mMinValue + (mMaxValue - mMinValue) * mSliderPosition; + mText.setString(ss.str()); + + mRenderWindow.draw(mAxis); + mRenderWindow.draw(mSlider); + mRenderWindow.draw(mText); + } + + int handleEvent(const sf::Event& event) { + if (event.type == sf::Event::MouseMoved) { + return onMouseMove(event); + } + else if (event.type == sf::Event::MouseButtonPressed) { + return onMousePressed(event); + } + else if (event.type == sf::Event::MouseButtonReleased) { + mIsPressed = false; + } + return mMinValue + (mMaxValue - mMinValue) * mSliderPosition; + } +};