Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML 2.X] Narzędzie Lasso w programie do edycji grafiki

Ostatnio zmodyfikowano 2025-09-06 17:18
Autor Wiadomość
DejaVu
» 2025-09-03 11:59:59
Przetestuj na boku w małym programie jeżeli masz takie podejrzenie.
P-182965
tBane
Temat założony przez niniejszego użytkownika
» 2025-09-03 12:15:03
Znalazłem kilka błędów z obsługą eventów lasso i je naprawiłem ale bug i tak występuje:
Poniżej zamieszczam testowy program jak radził DejaVu. Kod można śmiało uruchomić - jest kompletny



C/C++
#include <iostream>
#include <string>
#include <functional>
#define NOMINMAX
#include <Windows.h>
#include <SFML/Graphics.hpp>

sf::RenderWindow * window;
sf::Vector2i mousePosition;
sf::Vector2f worldMousePosition;

float zoom = 2;
float zoom_delta = 2;
sf::Vector2i canvasSize;
sf::Vector2f canvasPosition;
sf::Sprite canvasSprite;
sf::Color lasso_color = sf::Color( 255, 127, 127, 255 );

sf::Vector2i worldToTile( sf::Vector2f p, sf::Vector2f canvasPosition, sf::Vector2i size, float zoom, float zoom_delta ) {
   
float scale = zoom * zoom_delta;
   
sf::Vector2f local = p - canvasPosition;
   
int tx = std::clamp( int( std::floor( local.x / scale ) ), 0, size.x - 1 );
   
int ty = std::clamp( int( std::floor( local.y / scale ) ), 0, size.y - 1 );
   
   
//std::cout << "tx = " << tx << ", ty = " << ty << "\n";
   
return sf::Vector2i( tx, ty );
}

sf::Vector2i selectionToTile( sf::Vector2f p, sf::Vector2f canvasPosition, sf::Vector2i canvas_size, sf::Vector2i selection_size, sf::Vector2i selection_offset, float zoom, float zoom_delta ) {
   
float scale = zoom * zoom_delta;
   
sf::Vector2f local = p - canvasPosition;
   
int tx = std::clamp( int( std::floor( local.x / scale ) ), - selection_size.x + selection_offset.x, canvas_size.x + selection_offset.x );
   
int ty = std::clamp( int( std::floor( local.y / scale ) ), - selection_size.y + selection_offset.y, canvas_size.y + selection_offset.y );
   
   
//std::cout << "tx = " << tx << ", ty = " << ty << "\n";
   
return sf::Vector2i( tx, ty );
}

sf::Vector2i worldToTile( sf::Vector2f p, sf::Vector2f canvasPosition, float zoom, float zoom_delta ) {
   
float scale = zoom * zoom_delta;
   
sf::Vector2f local = p - canvasPosition;
   
int tx = int( std::floor( local.x / scale ) );
   
int ty = int( std::floor( local.y / scale ) );
   
   
//std::cout << "tx = " << tx << ", ty = " << ty << "\n";
   
return sf::Vector2i( tx, ty );
}

enum class LassoState { None, Selecting, Selected, Moving };

class Lasso {
public:
   
LassoState state;
   
   
std::vector < sf::Vector2i > points;
   
   
//
   
sf::Vector2i offset; // to move
   
    // image
   
sf::Image * image;
   
sf::Texture texture;
   
sf::Sprite sprite;
   
   
// mask
   
sf::RenderTexture mask;
   
sf::Sprite maskSprite;
   
sf::Vector2i maskOffset; // to draw a mask
   
    // outside rect and offset
   
sf::IntRect rect;
   
   
Lasso() {
       
state = LassoState::None;
       
       
points.clear();
       
       
offset = sf::Vector2i( 0, 0 );
       
       
image = nullptr;
       
rect = sf::IntRect( 0, 0, 0, 0 );
       
maskOffset = sf::Vector2i( 0, 0 );
   
}
   
   
~Lasso() { }
   
   
void shiftOriginIfNeeded( sf::Vector2i & point )
   
{
       
sf::Vector2i shift( 0, 0 );
       
if( point.x < 0 ) { shift.x = point.x; point.x = 0; }
       
if( point.y < 0 ) { shift.y = point.y; point.y = 0; }
       
       
if( shift.x != 0 || shift.y != 0 ) {
           
           
maskOffset += shift;
           
           
for( auto & p: points )
               
 p -= shift;
           
       
}
    }
   
   
void addPoint( sf::Vector2i point ) // tile = globalny punkt w kafelkach
   
{
       
point = point - maskOffset;
       
       
shiftOriginIfNeeded( point );
       
       
if( points.empty() || std::hypot( float( points.back().x - point.x ), float( points.back().y - point.y ) ) >= 1.0f )
       
{
           
points.push_back( point );
           
// std::cout << "add point local: " << point.x << ", " << point.y << "\n";
       
}
    }
   
   
void unselect() {
       
points.clear();
       
generateRect();
       
//image = nullptr;
   
}
   
   
void generateRect() {
       
if( points.size() > 2 ) {
           
int minX = std::numeric_limits < int >::max();
           
int maxX = std::numeric_limits < int >::lowest();
           
int minY = std::numeric_limits < int >::max();
           
int maxY = std::numeric_limits < int >::lowest();
           
           
for( auto & p: points ) {
               
minX = std::min( minX, p.x );
               
maxX = std::max( maxX, p.x );
               
minY = std::min( minY, p.y );
               
maxY = std::max( maxY, p.y );
           
}
           
           
int left = minX + maskOffset.x;
           
int top = minY + maskOffset.y;
           
int width =( maxX - minX + 1 );
           
int height =( maxY - minY + 1 );
           
           
if( width > 0 && height > 0 )
               
 rect = sf::IntRect( left, top, width, height );
           
else
               
 rect = sf::IntRect( 0, 0, 0, 0 );
           
       
}
       
else {
           
rect = sf::IntRect( 0, 0, 0, 0 );
       
}
    }
   
   
bool clickOnSelection( sf::Vector2i point ) {
       
       
return rect.contains( point );
   
}
   
   
   
   
void generateOutline( float scale ) {
       
if( points.size() < 3 ) return;
       
       
sf::VertexArray lines( sf::LineStrip );
       
       
for( auto & p: points )
           
 lines.append( sf::Vertex( sf::Vector2f( p ), lasso_color ) );
       
       
//lines.append(sf::Vertex(sf::Vector2f(points.front()), lasso_color));
       
       
if( image != nullptr ) {
           
/*
   int left = std::numeric_limits<int>::max();
   int right = std::numeric_limits<int>::lowest();
   int top = std::numeric_limits<int>::max();
   int bottom = std::numeric_limits<int>::lowest();

   for (int i = 0; i < lines.getVertexCount();i++) {
    left = std::min(left, int(lines[i].position.x));
    right = std::max(right, int(lines[i].position.x));
    top = std::min(top, int(lines[i].position.y));
    bottom = std::max(bottom, int(lines[i].position.y));
   }

   int width = right - left;
   int height = bottom - top;

   rect = sf::IntRect(left, top, width, height);
   */
           
           
texture = sf::Texture();
           
texture.setSmooth( false );
           
texture.setRepeated( false );
           
texture.create( rect.getSize().x, rect.getSize().y );
           
texture.loadFromImage( * image );
           
           
           
mask.create( texture.getSize().x, texture.getSize().y );
           
mask.clear( sf::Color( 127, 47, 47, 127 ) );
           
sf::RenderStates rs;
           
rs.blendMode = sf::BlendNone;
           
rs.transform.translate( 0.5f, 0.5f ); // <<— kluczowe (tak twierdzi ChatGPT)
           
mask.draw( lines, rs );
           
mask.display();
       
}
    }
   
   
void drawOutline( sf::Vector2f canvasPosition, float scale ) {
       
maskSprite = sf::Sprite( mask.getTexture() );
       
maskSprite.setScale( scale, scale );
       
maskSprite.setPosition( canvasPosition + sf::Vector2f( maskOffset ) * scale );
       
window->draw( maskSprite );
       
   
}
   
   
   
void draw( sf::Vector2f canvasPosition, float scale ) {
       
       
if( points.size() >= 3 ) {
           
if( true ) { //state == LassoState::Selecting || state == LassoState::Selected) {
               
generateOutline( scale );
               
drawOutline( canvasPosition, scale );
           
}
        }
       
    }
}
;

Lasso * lasso = nullptr;

int main() {
   
   
window = new sf::RenderWindow( sf::VideoMode( 800, 600 ), "test program lasso", sf::Style::Titlebar | sf::Style::Resize | sf::Style::Close );
   
   
canvasSize = sf::Vector2i( 64, 64 );
   
canvasPosition =( sf::Vector2f( window->getSize() ) / 2.0f - sf::Vector2f( canvasSize / 2 ) * zoom * zoom_delta );
   
lasso = new Lasso();
   
   
while( window->isOpen() ) {
       
       
mousePosition = sf::Mouse::getPosition( * window ); // get the mouse position about window
       
worldMousePosition = window->mapPixelToCoords( mousePosition ); // get global mouse position
       
       
       
        // handle events
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::Closed )
               
 window->close();
           
           
if( event.type == sf::Event::MouseMoved && sf::Mouse::isButtonPressed( sf::Mouse::Left ) ) {
               
if( lasso->state == LassoState::Moving ) {
                   
sf::Vector2i tile = selectionToTile( worldMousePosition, canvasPosition, canvasSize, lasso->rect.getSize(), lasso->offset, zoom, zoom_delta );
                   
sf::Vector2i dst = tile - lasso->offset;
                   
lasso->maskOffset.x = dst.x;
                   
lasso->maskOffset.y = dst.y;
                   
lasso->generateRect();
               
}
               
else if( lasso->state == LassoState::Selecting ) {
                   
sf::Vector2i tile = worldToTile( worldMousePosition, canvasPosition, canvasSize, zoom, zoom_delta );
                   
                   
if( lasso->image != nullptr ) {
                       
//paste(&layers_dialog->getCurrentLayer()->image, lasso->image, lasso->rect.left, lasso->rect.top);
                       
lasso->image = nullptr;
                   
}
                   
                   
lasso->addPoint( tile );
                   
lasso->generateRect();
                   
                   
lasso->image = new sf::Image();
                   
lasso->image->create( lasso->rect.width, lasso->rect.height, sf::Color::Transparent );
                   
//copy(lasso->image, &layers_dialog->getCurrentLayer()->image, lasso->rect);
                    //remove(layers_dialog->getCurrentLayer()->image, lasso->rect);
               
}
            }
           
if( event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left ) {
               
if( lasso->state == LassoState::Selecting ) {
                   
lasso->state = LassoState::Selected;
               
}
               
else if( lasso->state == LassoState::Moving ) {
                   
lasso->state = LassoState::Selected;
               
}
            }
           
           
if( event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left ) {
               
               
sf::Vector2i tile = worldToTile( worldMousePosition, canvasPosition, zoom, zoom_delta );
               
               
if( lasso->clickOnSelection( tile ) ) {
                   
                   
lasso->state = LassoState::Moving;
                   
lasso->offset = tile - lasso->maskOffset;
                   
                   
if( lasso->image == nullptr ) {
                       
lasso->image = new sf::Image();
                       
lasso->generateRect();
                       
lasso->image->create( lasso->rect.width, lasso->rect.height, sf::Color::Transparent );
                       
//copy(lasso->image, &layers_dialog->getCurrentLayer()->image, lasso->rect);
                        //remove(layers_dialog->getCurrentLayer()->image, lasso->rect);
                   
}
                }
               
else if( canvasSprite.getGlobalBounds().contains( worldMousePosition ) ) {
                   
if( lasso->image != nullptr ) {
                       
lasso->generateRect();
                       
//paste(&layers_dialog->getCurrentLayer()->image, lasso->image, lasso->rect.left, lasso->rect.top);
                       
lasso->image = nullptr;
                       
                   
}
                   
                   
                   
lasso->state = LassoState::Selecting;
                   
lasso->unselect();
                   
lasso->maskOffset = tile;
               
}
               
else {
                   
if( lasso->image != nullptr ) {
                       
lasso->generateRect();
                       
//paste(&layers_dialog->getCurrentLayer()->image, lasso->image, lasso->rect.left, lasso->rect.top);
                       
lasso->image = nullptr;
                   
}
                   
                   
lasso->state = LassoState::None;
                   
lasso->unselect();
               
}
               
               
            }
           
           
        }
       
       
// update
       
        // render
       
window->clear( sf::Color( 56, 56, 56 ) );
       
sf::Image empty_image;
       
empty_image.create( canvasSize.x, canvasSize.y, sf::Color( 127, 127, 127 ) );
       
sf::Texture empty_tex = sf::Texture();
       
empty_tex.loadFromImage( empty_image );
       
canvasSprite = sf::Sprite( empty_tex );
       
canvasSprite.setPosition( canvasPosition );
       
canvasSprite.setScale( zoom * zoom_delta, zoom * zoom_delta );
       
window->draw( canvasSprite );
       
       
lasso->draw( canvasPosition, zoom * zoom_delta );
       
       
window->display();
       
       
   
}
   
   
   
return 0;
}
P-182966
pekfos
» 2025-09-03 23:34:43
U mnie działa
C/C++
rs.transform.translate( 0.5f, 0.5f ); // <<— kluczowe (tak twierdzi ChatGPT)
Możesz pokombinować z tymi wartościami, np zmniejszyć je do 0.25f czy czegoś takiego. Problem jest w tym że chcesz użyć karty graficznej do generowania obrazu dokładnego co do piksela, a ta nie jest do tego przystosowana. Renderowanie robisz w koordynatach "świata" i chcesz wylądować w bardzo konkretne piksele na "ekranie", ta translacja o ułamek piksela ma na celu sprawienie by współrzędne celowały w środki pikseli, a nie ich rogi, żeby błędy obliczeń nie sprawiły że zapalą się piksele obok.
P-182968
tBane
Temat założony przez niniejszego użytkownika
» 2025-09-03 23:36:28
U mnie zazwyczaj też działa, ale co jakiś czas występuje bug
P-182969
pekfos
» 2025-09-03 23:40:39
To podaj jak zreprodukować problem.
P-182970
tBane
Temat założony przez niniejszego użytkownika
» 2025-09-03 23:49:04
Aby wystąpił bug należy zaznaczyć kształt kolisty w kierunku przeciwnym do ruchu wskazówek zegara. Należy to zrobić w miarę powoli, żeby bug wystąpił. Ruch powinien trwać 0.5-1 sekundy. Gdy bug nie wystąpi należy ponowić działanie aż do wystąpienia buga.
P-182971
pekfos
» 2025-09-04 00:07:06
C/C++
int left = minX + maskOffset.x;
int top = minY + maskOffset.y;
int width =( maxX - minX + 1 );
int height =( maxY - minY + 1 );
Jeżeli tekstura ma tak określony wymiar, minX i minY muszą być zerowe. Bug występuje gdy nie są. maskOffset powinno być równe minimalnym współrzędnym, nie wiem po co masz to cały czas utrzymywane osobno.
P-182972
tBane
Temat założony przez niniejszego użytkownika
» 2025-09-04 13:52:32
Dobra, już usunąłem minX, minY.

poprawiony fragment kodu:
C/C++
void generateRect() {
   
if( points.size() < 3 ) {
       
rect = sf::IntRect( 0, 0, 0, 0 );
       
return;
   
}
   
   
   
int maxX = std::numeric_limits < int >::lowest();
   
int maxY = std::numeric_limits < int >::lowest();
   
   
for( auto & p: points ) {
       
maxX = std::max( maxX, p.x );
       
maxY = std::max( maxY, p.y );
   
}
   
   
int left = maskOffset.x;
   
int top = maskOffset.y;
   
int width = maxX;
   
int height = maxY;
   
   
if( width > 0 && height > 0 ) {
       
rect = sf::IntRect( left, top, width, height );
   
}
   
else {
       
rect = sf::IntRect( 0, 0, 0, 0 );
   
}
   
}



cały kod:
C/C++
#include <iostream>
#include <string>
#include <functional>
#define NOMINMAX
#include <Windows.h>
#include <SFML/Graphics.hpp>

sf::RenderWindow * window;
sf::Vector2i mousePosition;
sf::Vector2f worldMousePosition;

float zoom = 2;
float zoom_delta = 2;
sf::Vector2i canvasSize;
sf::Vector2f canvasPosition;
sf::Sprite canvasSprite;
sf::Color lasso_color = sf::Color( 255, 127, 127, 255 );

sf::Vector2i worldToTile( sf::Vector2f cursorPosition, sf::Vector2f canvasPosition, sf::Vector2i size, float zoom, float zoom_delta ) {
   
float scale = zoom * zoom_delta;
   
sf::Vector2f local = cursorPosition - canvasPosition;
   
int tx = std::clamp( int( std::floor( local.x / scale ) ), 0, size.x - 1 );
   
int ty = std::clamp( int( std::floor( local.y / scale ) ), 0, size.y - 1 );
   
   
//std::cout << "tx = " << tx << ", ty = " << ty << "\n";
   
return sf::Vector2i( tx, ty );
}

sf::Vector2i selectionToTile( sf::Vector2f cursorPosition, sf::Vector2f canvasPosition, sf::Vector2i canvas_size, sf::Vector2i selection_size, sf::Vector2i selection_offset, float zoom, float zoom_delta ) {
   
float scale = zoom * zoom_delta;
   
sf::Vector2f local = cursorPosition - canvasPosition;
   
int tx = std::clamp( int( std::floor( local.x / scale ) ), - selection_size.x + selection_offset.x, canvas_size.x + selection_offset.x );
   
int ty = std::clamp( int( std::floor( local.y / scale ) ), - selection_size.y + selection_offset.y, canvas_size.y + selection_offset.y );
   
   
//std::cout << "tx = " << tx << ", ty = " << ty << "\n";
   
return sf::Vector2i( tx, ty );
}

sf::Vector2i worldToTile( sf::Vector2f cursorPosition, sf::Vector2f canvasPosition, float zoom, float zoom_delta ) {
   
float scale = zoom * zoom_delta;
   
sf::Vector2f local = cursorPosition - canvasPosition;
   
int tx = int( std::floor( local.x / scale ) );
   
int ty = int( std::floor( local.y / scale ) );
   
   
//std::cout << "tx = " << tx << ", ty = " << ty << "\n";
   
return sf::Vector2i( tx, ty );
}

enum class LassoState { None, Selecting, Selected, Moving };

class Lasso {
public:
   
LassoState state;
   
   
std::vector < sf::Vector2i > points;
   
   
//
   
sf::Vector2i offset; // to move
   
    // image
   
sf::Image * image;
   
sf::Texture texture;
   
sf::Sprite sprite;
   
   
// mask
   
sf::RenderTexture mask;
   
sf::Sprite maskSprite;
   
sf::Vector2i maskOffset; // to draw a mask
   
    // outside rect and offset
   
sf::IntRect rect;
   
   
Lasso() {
       
state = LassoState::None;
       
       
points.clear();
       
       
offset = sf::Vector2i( 0, 0 );
       
       
image = nullptr;
       
rect = sf::IntRect( 0, 0, 0, 0 );
       
maskOffset = sf::Vector2i( 0, 0 );
   
}
   
   
~Lasso() { }
   
   
void shiftOriginIfNeeded( sf::Vector2i & point )
   
{
       
sf::Vector2i shift( 0, 0 );
       
if( point.x < 0 ) { shift.x = point.x; point.x = 0; }
       
if( point.y < 0 ) { shift.y = point.y; point.y = 0; }
       
       
if( shift.x != 0 || shift.y != 0 ) {
           
           
maskOffset += shift;
           
           
for( auto & p: points )
               
 p -= shift;
           
       
}
    }
   
   
void addPoint( sf::Vector2i point ) // tile = globalny punkt w kafelkach
   
{
       
point = point - maskOffset;
       
       
shiftOriginIfNeeded( point );
       
       
if( points.empty() || std::hypot( float( points.back().x - point.x ), float( points.back().y - point.y ) ) >= 1.0f )
       
{
           
points.push_back( point );
           
// std::cout << "add point local: " << point.x << ", " << point.y << "\n";
       
}
    }
   
   
void unselect() {
       
points.clear();
       
generateRect();
       
//image = nullptr;
   
}
   
   
void generateRect() {
       
if( points.size() < 3 ) {
           
rect = sf::IntRect( 0, 0, 0, 0 );
           
return;
       
}
       
       
       
int maxX = std::numeric_limits < int >::lowest();
       
int maxY = std::numeric_limits < int >::lowest();
       
       
for( auto & p: points ) {
           
maxX = std::max( maxX, p.x );
           
maxY = std::max( maxY, p.y );
       
}
       
       
int left = maskOffset.x;
       
int top = maskOffset.y;
       
int width = maxX;
       
int height = maxY;
       
       
if( width > 0 && height > 0 ) {
           
rect = sf::IntRect( left, top, width, height );
       
}
       
else {
           
rect = sf::IntRect( 0, 0, 0, 0 );
       
}
       
    }
   
   
bool clickOnSelection( sf::Vector2i point ) {
       
       
return rect.contains( point );
   
}
   
   
   
   
void generateOutline( float scale ) {
       
if( points.size() < 3 ) return;
       
       
sf::VertexArray lines( sf::LineStrip );
       
       
for( auto & p: points )
           
 lines.append( sf::Vertex( sf::Vector2f( p ), lasso_color ) );
       
       
//lines.append(sf::Vertex(sf::Vector2f(points.front()), lasso_color));
       
       
if( image != nullptr ) {
           
/*
   int left = std::numeric_limits<int>::max();
   int right = std::numeric_limits<int>::lowest();
   int top = std::numeric_limits<int>::max();
   int bottom = std::numeric_limits<int>::lowest();

   for (int i = 0; i < lines.getVertexCount();i++) {
    left = std::min(left, int(lines[i].position.x));
    right = std::max(right, int(lines[i].position.x));
    top = std::min(top, int(lines[i].position.y));
    bottom = std::max(bottom, int(lines[i].position.y));
   }

   int width = right - left;
   int height = bottom - top;

   rect = sf::IntRect(left, top, width, height);
   */
           
           
texture = sf::Texture();
           
texture.setSmooth( false );
           
texture.setRepeated( false );
           
texture.create( rect.getSize().x, rect.getSize().y );
           
texture.loadFromImage( * image );
           
           
           
mask.create( texture.getSize().x, texture.getSize().y );
           
mask.clear( sf::Color( 127, 47, 47, 127 ) );
           
sf::RenderStates rs;
           
rs.blendMode = sf::BlendNone;
           
rs.transform.translate( 0.5f, 0.5f ); // <<— kluczowe (tak twierdzi ChatGPT)
           
mask.draw( lines, rs );
           
mask.display();
       
}
    }
   
   
void drawOutline( sf::Vector2f canvasPosition, float scale ) {
       
maskSprite = sf::Sprite( mask.getTexture() );
       
maskSprite.setScale( scale, scale );
       
maskSprite.setPosition( canvasPosition + sf::Vector2f( maskOffset ) * scale );
       
window->draw( maskSprite );
       
   
}
   
   
   
void draw( sf::Vector2f canvasPosition, float scale ) {
       
       
if( points.size() >= 3 ) {
           
if( true ) { //state == LassoState::Selecting || state == LassoState::Selected) {
               
generateOutline( scale );
               
drawOutline( canvasPosition, scale );
           
}
        }
       
    }
}
;

Lasso * lasso = nullptr;

int main() {
   
   
window = new sf::RenderWindow( sf::VideoMode( 800, 600 ), "test program lasso", sf::Style::Titlebar | sf::Style::Resize | sf::Style::Close );
   
   
canvasSize = sf::Vector2i( 64, 64 );
   
canvasPosition =( sf::Vector2f( window->getSize() ) / 2.0f - sf::Vector2f( canvasSize / 2 ) * zoom * zoom_delta );
   
lasso = new Lasso();
   
   
while( window->isOpen() ) {
       
       
mousePosition = sf::Mouse::getPosition( * window ); // get the mouse position about window
       
worldMousePosition = window->mapPixelToCoords( mousePosition ); // get global mouse position
       
       
       
        // handle events
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::Closed )
               
 window->close();
           
           
           
if( event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left ) {
               
if( lasso->state == LassoState::Selecting ) {
                   
lasso->state = LassoState::Selected;
               
}
               
else if( lasso->state == LassoState::Moving ) {
                   
lasso->state = LassoState::Selected;
               
}
            }
           
           
if( event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left ) {
               
               
sf::Vector2i tile = worldToTile( worldMousePosition, canvasPosition, zoom, zoom_delta );
               
               
if( lasso->clickOnSelection( tile ) ) {
                   
                   
lasso->state = LassoState::Moving;
                   
lasso->offset = tile - lasso->maskOffset;
                   
                   
if( lasso->image == nullptr ) {
                       
lasso->image = new sf::Image();
                       
lasso->generateRect();
                       
lasso->image->create( lasso->rect.width, lasso->rect.height, sf::Color::Transparent );
                       
//copy(lasso->image, &layers_dialog->getCurrentLayer()->image, lasso->rect);
                        //remove(layers_dialog->getCurrentLayer()->image, lasso->rect);
                   
}
                }
               
else if( canvasSprite.getGlobalBounds().contains( worldMousePosition ) ) {
                   
if( lasso->image != nullptr ) {
                       
lasso->generateRect();
                       
//paste(&layers_dialog->getCurrentLayer()->image, lasso->image, lasso->rect.left, lasso->rect.top);
                       
lasso->image = nullptr;
                       
                   
}
                   
                   
                   
lasso->state = LassoState::Selecting;
                   
lasso->unselect();
                   
lasso->maskOffset = tile;
               
}
               
else {
                   
if( lasso->image != nullptr ) {
                       
lasso->generateRect();
                       
//paste(&layers_dialog->getCurrentLayer()->image, lasso->image, lasso->rect.left, lasso->rect.top);
                       
lasso->image = nullptr;
                   
}
                   
                   
lasso->state = LassoState::None;
                   
lasso->unselect();
               
}
            }
        }
       
       
if( sf::Mouse::isButtonPressed( sf::Mouse::Left ) ) {
           
if( lasso->state == LassoState::Moving ) {
               
sf::Vector2i tile = selectionToTile( worldMousePosition, canvasPosition, canvasSize, lasso->rect.getSize(), lasso->offset, zoom, zoom_delta );
               
sf::Vector2i dst = tile - lasso->offset;
               
lasso->maskOffset.x = dst.x;
               
lasso->maskOffset.y = dst.y;
               
lasso->generateRect();
           
}
           
else if( lasso->state == LassoState::Selecting ) {
               
sf::Vector2i tile = worldToTile( worldMousePosition, canvasPosition, canvasSize, zoom, zoom_delta );
               
               
if( lasso->image != nullptr ) {
                   
//paste(&layers_dialog->getCurrentLayer()->image, lasso->image, lasso->rect.left, lasso->rect.top);
                   
lasso->image = nullptr;
               
}
               
               
lasso->addPoint( tile );
               
lasso->generateRect();
               
               
lasso->image = new sf::Image();
               
lasso->image->create( lasso->rect.width, lasso->rect.height, sf::Color::Transparent );
               
//copy(lasso->image, &layers_dialog->getCurrentLayer()->image, lasso->rect);
                //remove(layers_dialog->getCurrentLayer()->image, lasso->rect);
           
}
        }
       
       
// update
       
        // render
       
window->clear( sf::Color( 56, 56, 56 ) );
       
sf::Image empty_image;
       
empty_image.create( canvasSize.x, canvasSize.y, sf::Color( 127, 127, 127 ) );
       
sf::Texture empty_tex = sf::Texture();
       
empty_tex.loadFromImage( empty_image );
       
canvasSprite = sf::Sprite( empty_tex );
       
canvasSprite.setPosition( canvasPosition );
       
canvasSprite.setScale( zoom * zoom_delta, zoom * zoom_delta );
       
window->draw( canvasSprite );
       
       
lasso->draw( canvasPosition, zoom * zoom_delta );
       
       
window->display();
       
       
   
}
   
   
   
return 0;
}
P-182974
1 2 3 « 4 » 5
Poprzednia strona Strona 4 z 5 Następna strona