seminar11 select, move, delete
This commit is contained in:
parent
4545683d17
commit
514012f0cb
4 changed files with 501 additions and 0 deletions
seminar11_events/01_select_move_delete
9
seminar11_events/01_select_move_delete/Makefile
Normal file
9
seminar11_events/01_select_move_delete/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#path = ../../../3rdparty/SFML-2.5.1
|
||||||
|
#select_move_delete:
|
||||||
|
# g++ ./select_move_delete.cpp -std=c++11 -o select_move_delete.exe -I $(path)/include -L $(path)/lib/ -lsfml-graphics -lsfml-window -lsfml-system
|
||||||
|
#select_move_delete:
|
||||||
|
# g++ ./select_move_delete.cpp -std=c++11 -o select_move_delete.exe -I $(path)/include -L $(path)/lib/ -lsfml-graphics -lsfml-window -lsfml-system
|
||||||
|
build:
|
||||||
|
g++ ./select_move_delete.cpp -std=c++11 -o select_move_delete -lsfml-graphics -lsfml-window -lsfml-system
|
||||||
|
build_debug:
|
||||||
|
g++ ./select_move_delete.cpp -std=c++11 -o select_move_delete -lsfml-graphics -lsfml-window -lsfml-system -D_DEBUG
|
BIN
seminar11_events/01_select_move_delete/consolas.ttf
Normal file
BIN
seminar11_events/01_select_move_delete/consolas.ttf
Normal file
Binary file not shown.
178
seminar11_events/01_select_move_delete/context_menu.hpp
Normal file
178
seminar11_events/01_select_move_delete/context_menu.hpp
Normal file
|
@ -0,0 +1,178 @@
|
||||||
|
#pragma once
|
||||||
|
#include <SFML/Window.hpp>
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Класс ContextMenu - контекстное меню
|
||||||
|
При нажатии правой кнопки мыши на экране появляется контекстное меню
|
||||||
|
|
||||||
|
Публичные методы:
|
||||||
|
ContextMenu(sf::RenderWindow&, const sf::Font&)
|
||||||
|
Конструктор принимает окно для отрисовки и шрифт
|
||||||
|
|
||||||
|
void addButton(const sf::String& name)
|
||||||
|
Добавить новый элемент в контекстное меню по имени name
|
||||||
|
|
||||||
|
void draw()
|
||||||
|
Нарисовать контекстное меню в окне, которое было передано в конструктор
|
||||||
|
|
||||||
|
int handleEvent(const sf::Event& event)
|
||||||
|
Обрабатывает событие event и возвращает целое число
|
||||||
|
Если это событие MousePressed и был выбран один из вариантов
|
||||||
|
контекстного меню, то вернёт номер этого варианта
|
||||||
|
Нумерация начинается с нуля
|
||||||
|
В ином случае вернёт -1
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
class ContextMenu
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
inline static const sf::Color kDefaultColor {sf::Color(190, 210, 190)};
|
||||||
|
inline static const sf::Color kHoverColor {sf::Color(150, 170, 150)};
|
||||||
|
inline static const sf::Color kTextColor {sf::Color::Black};
|
||||||
|
inline static const int kButtonHeight = 20;
|
||||||
|
inline static const int kCharacterSize = 16;
|
||||||
|
inline static const float kMenuWidthMultiplier = 1.2;
|
||||||
|
|
||||||
|
sf::RenderWindow& mRenderWindow;
|
||||||
|
sf::RectangleShape mShape;
|
||||||
|
sf::RectangleShape mHoverShape;
|
||||||
|
sf::Text mText;
|
||||||
|
std::vector<sf::String> mButtons;
|
||||||
|
|
||||||
|
bool mIsOpened = false;
|
||||||
|
bool mIsUpdated = false;
|
||||||
|
int mHoverPosition = -1;
|
||||||
|
|
||||||
|
int onMousePressed(const sf::Event& event)
|
||||||
|
{
|
||||||
|
if (event.mouseButton.button == sf::Mouse::Right) {
|
||||||
|
mIsOpened = true;
|
||||||
|
sf::Vector2f mousePosition = mRenderWindow.mapPixelToCoords({event.mouseButton.x, event.mouseButton.y});
|
||||||
|
mShape.setPosition(mousePosition);
|
||||||
|
}
|
||||||
|
if (event.mouseButton.button == sf::Mouse::Left && mIsOpened) {
|
||||||
|
mIsOpened = false;
|
||||||
|
return mHoverPosition;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onMouseMove(const sf::Event& event)
|
||||||
|
{
|
||||||
|
if (!mIsOpened) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sf::Vector2f mousePosition = mRenderWindow.mapPixelToCoords({event.mouseMove.x, event.mouseMove.y});
|
||||||
|
if (mShape.getGlobalBounds().contains(mousePosition)) {
|
||||||
|
mHoverPosition = (mousePosition.y - mShape.getPosition().y) / kButtonHeight;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mHoverPosition = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ContextMenu(sf::RenderWindow& window, const sf::Font& font) : mRenderWindow(window)
|
||||||
|
{
|
||||||
|
mText.setFont(font);
|
||||||
|
mText.setCharacterSize(kCharacterSize);
|
||||||
|
mText.setFillColor(kTextColor);
|
||||||
|
mShape.setFillColor(kDefaultColor);
|
||||||
|
mHoverShape.setFillColor(kHoverColor);
|
||||||
|
|
||||||
|
mIsOpened = false;
|
||||||
|
mIsUpdated = false;
|
||||||
|
mHoverPosition = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addButton(const sf::String& name)
|
||||||
|
{
|
||||||
|
mButtons.push_back(name);
|
||||||
|
mIsUpdated = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw()
|
||||||
|
{
|
||||||
|
if (!mIsOpened) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Если добавили новый вариант, то её текст может быть длиннее
|
||||||
|
// чем у других. Нужно расширить прямоугольники.
|
||||||
|
if (!mIsUpdated) {
|
||||||
|
int maxSizeX = 0;
|
||||||
|
for (int i = 0; i < mButtons.size(); i++) {
|
||||||
|
mText.setString(mButtons[i]);
|
||||||
|
if (mText.getLocalBounds().width > maxSizeX) {
|
||||||
|
maxSizeX = mText.getLocalBounds().width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maxSizeX *= kMenuWidthMultiplier;
|
||||||
|
mShape.setSize({(float)maxSizeX, (float)(kButtonHeight * mButtons.size())});
|
||||||
|
mHoverShape.setSize({(float)maxSizeX, (float)(kButtonHeight)});
|
||||||
|
mIsUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mRenderWindow.draw(mShape);
|
||||||
|
if (mHoverPosition >= 0){
|
||||||
|
mHoverShape.setPosition(mShape.getPosition().x, mShape.getPosition().y + mHoverPosition * kButtonHeight);
|
||||||
|
mRenderWindow.draw(mHoverShape);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < mButtons.size(); i++) {
|
||||||
|
mText.setString(mButtons[i]);
|
||||||
|
mText.setPosition(mShape.getPosition().x, mShape.getPosition().y + i * kButtonHeight);
|
||||||
|
mRenderWindow.draw(mText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int handleEvent(const sf::Event& event) {
|
||||||
|
if (event.type == sf::Event::MouseMoved) {
|
||||||
|
onMouseMove(event);
|
||||||
|
}
|
||||||
|
else if (event.type == sf::Event::MouseButtonPressed) {
|
||||||
|
return onMousePressed(event);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
sf::RenderWindow window(sf::VideoMode(500, 500), "Slider!");
|
||||||
|
window.setFramerateLimit(60);
|
||||||
|
|
||||||
|
SliderSFML slider1(100, 100);
|
||||||
|
SliderSFML slider2(100, 200);
|
||||||
|
SliderSFML slider3(100, 300);
|
||||||
|
|
||||||
|
slider1.create(20, 450);
|
||||||
|
slider2.create(0, 200);
|
||||||
|
slider3.create(0, 100);
|
||||||
|
|
||||||
|
slider1.setSliderValue(235);
|
||||||
|
|
||||||
|
while (window.isOpen())
|
||||||
|
{
|
||||||
|
sf::Event event;
|
||||||
|
while (window.pollEvent(event))
|
||||||
|
{
|
||||||
|
if (event.type == sf::Event::Closed)
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.clear(sf::Color(25,29,33));
|
||||||
|
|
||||||
|
slider1.draw(window);
|
||||||
|
slider2.draw(window);
|
||||||
|
slider3.draw(window);
|
||||||
|
|
||||||
|
window.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}};
|
314
seminar11_events/01_select_move_delete/select_move_delete.cpp
Normal file
314
seminar11_events/01_select_move_delete/select_move_delete.cpp
Normal file
|
@ -0,0 +1,314 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <cmath>
|
||||||
|
#include <list>
|
||||||
|
#include <SFML/Window.hpp>
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
#include "context_menu.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void meow() {;}
|
||||||
|
|
||||||
|
// Вспомогательные функции, вычисляет расстояние между двумя точками
|
||||||
|
float distance(sf::Vector2f start, sf::Vector2f finish)
|
||||||
|
{
|
||||||
|
return sqrtf((start.x - finish.x)*(start.x - finish.x) + (start.y - finish.y)*(start.y - finish.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вспомогательные функции, рисует линию на холсте окна window
|
||||||
|
void drawLine(sf::RenderWindow& window, sf::Vector2f start, sf::Vector2f finish, sf::Color color = sf::Color::White)
|
||||||
|
{
|
||||||
|
sf::Vertex line_vertices[2] = {sf::Vertex(start, color), sf::Vertex(finish, color)};
|
||||||
|
window.draw(line_vertices, 2, sf::Lines);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вспомагательный класс, описывет шарик
|
||||||
|
// position - положение шарика; radius - радиус
|
||||||
|
// is_chosen - говорит о том, выбран ли шарик или нет
|
||||||
|
struct Ball
|
||||||
|
{
|
||||||
|
sf::Vector2f position;
|
||||||
|
float radius;
|
||||||
|
bool isChoosen;
|
||||||
|
sf::Color color;
|
||||||
|
|
||||||
|
Ball(sf::Vector2f position, float radius, sf::Color color = sf::Color::White) : position(position), radius(radius), color(color)
|
||||||
|
{
|
||||||
|
isChoosen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Метод, который рисует шарик на холстек окна window
|
||||||
|
void draw(sf::RenderWindow& window) const
|
||||||
|
{
|
||||||
|
// Тут рисуем белый кружочек
|
||||||
|
sf::CircleShape circle(radius);
|
||||||
|
circle.setFillColor(color);
|
||||||
|
circle.setOrigin({radius, radius});
|
||||||
|
circle.setPosition(position);
|
||||||
|
window.draw(circle);
|
||||||
|
|
||||||
|
// Если шарик выбран
|
||||||
|
if (isChoosen) {
|
||||||
|
// То рисуем "уголки"
|
||||||
|
const float fraction = 0.7;
|
||||||
|
drawLine(window, {position.x - radius, position.y + radius}, {position.x - radius, position.y + radius*fraction});
|
||||||
|
drawLine(window, {position.x - radius, position.y + radius}, {position.x - fraction * radius, position.y + radius});
|
||||||
|
|
||||||
|
drawLine(window, {position.x + radius, position.y + radius}, {position.x + radius, position.y + radius*fraction});
|
||||||
|
drawLine(window, {position.x + radius, position.y + radius}, {position.x + radius*fraction, position.y + radius});
|
||||||
|
|
||||||
|
drawLine(window, {position.x + radius, position.y - radius}, {position.x + radius*fraction, position.y - radius});
|
||||||
|
drawLine(window, {position.x + radius, position.y - radius}, {position.x + radius, position.y - radius*fraction});
|
||||||
|
|
||||||
|
drawLine(window, {position.x - radius, position.y - radius}, {position.x - radius*fraction, position.y - radius});
|
||||||
|
drawLine(window, {position.x - radius, position.y - radius}, {position.x - radius, position.y - radius*fraction});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void setColor(sf::Uint8 r, sf::Uint8 g, sf::Uint8 b, sf::Uint8 a = 255) {
|
||||||
|
color.r = r;
|
||||||
|
color.g = g;
|
||||||
|
color.b = b;
|
||||||
|
color.a = a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void deleteChoosen(list<Ball>& balls) {
|
||||||
|
for (list<Ball>::const_iterator it = balls.begin(); it != balls.end();) {
|
||||||
|
if (it->isChoosen)
|
||||||
|
it = balls.erase(it);
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
#ifdef _DEBUG
|
||||||
|
for (list<Ball>::iterator it = balls.begin(); it != balls.end(); ++it)
|
||||||
|
cout << it->position.x <<" " << it->position.y<< endl;
|
||||||
|
cout << "###" << endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyBalls(list<Ball>& balls, list<Ball>& buffer) {
|
||||||
|
buffer.clear();
|
||||||
|
for (list<Ball>::iterator it = balls.begin(); it != balls.end(); ++it)
|
||||||
|
if (it->isChoosen)
|
||||||
|
buffer.push_back(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pasteBalls(list<Ball>& balls, list<Ball>& buffer) {
|
||||||
|
for (list<Ball>::iterator it = buffer.begin(); it != buffer.end(); ++it)
|
||||||
|
balls.push_back(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
void recolorChoosen(list<Ball>& balls) {
|
||||||
|
for (Ball& b : balls)
|
||||||
|
if (b.isChoosen)
|
||||||
|
b.setColor(rand() % 255, rand() % 255, rand() % 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resizeChoosen(list<Ball>& balls, double scaling) {
|
||||||
|
for (list<Ball>::iterator it = balls.begin(); it != balls.end(); ++it) {
|
||||||
|
if (it->isChoosen)
|
||||||
|
it->radius += it->radius * scaling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
sf::ContextSettings settings;
|
||||||
|
settings.antialiasingLevel = 8;
|
||||||
|
sf::RenderWindow window(sf::VideoMode(800, 600), "Select, Move, Delete!", sf::Style::Default, settings);
|
||||||
|
window.setFramerateLimit(60);
|
||||||
|
|
||||||
|
|
||||||
|
// Создаём связный список из шариков
|
||||||
|
// Связный список -- потому что нам нужно будет постоянно удалять и добавлять в этот список
|
||||||
|
std::list<Ball> balls;
|
||||||
|
balls.push_back(Ball({200, 200}, 26));
|
||||||
|
balls.push_back(Ball({400, 300}, 20));
|
||||||
|
balls.push_back(Ball({500, 100}, 16));
|
||||||
|
balls.push_back(Ball({200, 400}, 18));
|
||||||
|
balls.push_back(Ball({350, 150}, 22));
|
||||||
|
balls.push_back(Ball({750, 400}, 21));
|
||||||
|
|
||||||
|
list<Ball> buffer{};
|
||||||
|
|
||||||
|
// Создаём прямоугольник выделения
|
||||||
|
// Обратите внимание на четвёртый параметр sf::Color(150, 150, 240, 50)
|
||||||
|
// Это alpha - прозрачность 0 = полностью прозрачный 255 = непрозрачный
|
||||||
|
sf::RectangleShape selectionRect;
|
||||||
|
selectionRect.setFillColor(sf::Color(150, 150, 240, 50));
|
||||||
|
selectionRect.setOutlineColor(sf::Color(200, 200, 255));
|
||||||
|
selectionRect.setOutlineThickness(1);
|
||||||
|
|
||||||
|
// Специальная переменная, которая будет показывать, что мы находимся в режиме выделения
|
||||||
|
bool isSelecting = false;
|
||||||
|
// "Режим выделения"
|
||||||
|
bool isMovingMode = false;
|
||||||
|
// Необходимо, чтоб в режиме выделения считать смещение
|
||||||
|
Ball* selected_ball = nullptr;
|
||||||
|
|
||||||
|
bool isContextMenu = false;
|
||||||
|
|
||||||
|
sf::Vector2f mousePosition{};
|
||||||
|
|
||||||
|
sf::Font font;
|
||||||
|
if (!font.loadFromFile("consolas.ttf")) {
|
||||||
|
std::cout << "Can't load button font" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<sf::String> contextMenuStrings {"Delete", "Create", "Random Color", "Increase", "Decrease", "Copy", "Cut", "Paste"};
|
||||||
|
ContextMenu contextMenu(window, font);
|
||||||
|
for (const auto& el : contextMenuStrings) {
|
||||||
|
contextMenu.addButton(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (window.isOpen()) {
|
||||||
|
sf::Event event;
|
||||||
|
while (window.pollEvent(event)) {
|
||||||
|
if (event.type == sf::Event::Closed) {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
int result = contextMenu.handleEvent(event);
|
||||||
|
switch(result) {
|
||||||
|
case 0:
|
||||||
|
deleteChoosen(balls);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mousePosition = window.mapPixelToCoords({event.mouseButton.x, event.mouseButton.y});
|
||||||
|
balls.push_back(Ball(mousePosition, 5 + rand() % 40));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
recolorChoosen(balls);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
resizeChoosen(balls, 0.25);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
resizeChoosen(balls, -0.25);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
copyBalls(balls, buffer);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
copyBalls(balls, buffer);
|
||||||
|
deleteChoosen(balls);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
pasteBalls(balls, buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (event.type == sf::Event::MouseMoved) {
|
||||||
|
mousePosition = window.mapPixelToCoords({event.mouseMove.x, event.mouseMove.y});
|
||||||
|
|
||||||
|
// Если мы находимся в режиме выделения и не попали в уже выделенный шарик, то меняем прямоугольник выделения
|
||||||
|
if (isSelecting & !isMovingMode) {
|
||||||
|
selectionRect.setSize(mousePosition - selectionRect.getPosition());
|
||||||
|
}
|
||||||
|
// Если в режиме перемещения, то двигаем все выделенные шарики
|
||||||
|
if (isMovingMode) {
|
||||||
|
sf::Vector2f direction = selected_ball->position - mousePosition;
|
||||||
|
for (Ball& b : balls) {
|
||||||
|
if (b.isChoosen) {
|
||||||
|
b.position -= direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.type == sf::Event::MouseButtonPressed) {
|
||||||
|
mousePosition = window.mapPixelToCoords({event.mouseButton.x, event.mouseButton.y});
|
||||||
|
if (event.mouseButton.button == sf::Mouse::Left) {
|
||||||
|
for (Ball& b : balls) {
|
||||||
|
/* Если попали в какой-то шарик */
|
||||||
|
if (distance(mousePosition, b.position) < b.radius) {
|
||||||
|
selected_ball = &b;
|
||||||
|
// Если попали в еще не выбранный шарик и не зажат левый Ctrl, то снимаем выделение со всех остальных
|
||||||
|
if(!b.isChoosen && !sf::Keyboard::isKeyPressed(sf::Keyboard::LControl)) {
|
||||||
|
for (Ball& ball : balls) {
|
||||||
|
ball.isChoosen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.isChoosen = true; //
|
||||||
|
isMovingMode = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ЛКМ + левый Alt - добавляем новый случайный шарик
|
||||||
|
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt)) {
|
||||||
|
balls.push_back(Ball(mousePosition, 5 + rand() % 40));
|
||||||
|
}
|
||||||
|
// Задаём новое положения прямоугольника выделения
|
||||||
|
if (!isMovingMode) {
|
||||||
|
isSelecting = true;
|
||||||
|
selectionRect.setPosition(mousePosition);
|
||||||
|
selectionRect.setSize({0, 0});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (event.mouseButton.button == sf::Mouse::Right) {
|
||||||
|
isContextMenu = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// При отпускании кнопки мыши выходим из режима выделения
|
||||||
|
if (event.type == sf::Event::MouseButtonReleased) {
|
||||||
|
// Если не зажат левый Ctrl и не в режиме перемещения шариков, то все выделения снимаются
|
||||||
|
if (!sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) && !isMovingMode && !isContextMenu) {
|
||||||
|
for (Ball& b : balls) {
|
||||||
|
b.isChoosen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isSelecting) {
|
||||||
|
sf::Vector2f size = selectionRect.getSize();
|
||||||
|
sf::Vector2f position = selectionRect.getPosition();
|
||||||
|
for (Ball& b : balls) {
|
||||||
|
if ( ((b.position.x - b.radius > position.x) && (b.position.x + b.radius < position.x + size.x)) ||
|
||||||
|
((b.position.x + b.radius < position.x) && (b.position.x - b.radius > position.x + size.x))
|
||||||
|
)
|
||||||
|
if (((b.position.y - b.radius > position.y) && (b.position.y + b.radius < position.y + size.y)) ||
|
||||||
|
((b.position.y + b.radius < position.y) && (b.position.y - b.radius > position.y + size.y))
|
||||||
|
)
|
||||||
|
b.isChoosen = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isSelecting = false;
|
||||||
|
isMovingMode = false;
|
||||||
|
isContextMenu = false;
|
||||||
|
}
|
||||||
|
/*2check*/
|
||||||
|
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
|
||||||
|
recolorChoosen(balls);
|
||||||
|
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Delete)) {
|
||||||
|
deleteChoosen(balls);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**/
|
||||||
|
if (event.type == sf::Event::KeyPressed)
|
||||||
|
if (event.key.code == sf::Keyboard::C)
|
||||||
|
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LControl)) {
|
||||||
|
copyBalls(balls, buffer);
|
||||||
|
}
|
||||||
|
if (event.type == sf::Event::KeyPressed)
|
||||||
|
if (event.key.code == sf::Keyboard::V)
|
||||||
|
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LControl))
|
||||||
|
pasteBalls(balls, buffer);
|
||||||
|
if (event.type == sf::Event::KeyPressed)
|
||||||
|
if (event.key.code == sf::Keyboard::X)
|
||||||
|
if (sf::Keyboard::isKeyPressed(sf::Keyboard::LControl)) {
|
||||||
|
copyBalls(balls, buffer);
|
||||||
|
deleteChoosen(balls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.clear(sf::Color::Black);
|
||||||
|
// Рисуем все шарики
|
||||||
|
for (Ball& b : balls) {
|
||||||
|
b.draw(window);
|
||||||
|
}
|
||||||
|
// Рисуем прямоугольник выделения
|
||||||
|
if (isSelecting) {
|
||||||
|
window.draw(selectionRect);
|
||||||
|
}
|
||||||
|
contextMenu.draw();
|
||||||
|
window.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in a new issue