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

Relatywne Pozycjonowanie Elementów

Ostatnio zmodyfikowano 2026-01-24 16:40
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
» 2026-01-24 16:03:21
Wierzę w siebie, ale skille mam słabe :P
W prototypie tym są cztery prostokąty po lewej stronie i jedna sekcja po prawej stronie. Prostokąty można za pomocą drag&drop przenieść na sekcję i tam są pozycjonowane. Gdy występuje możliwość przeniesienia prostokąta na sekcje to zmienia on kolor z zielonego na czerwony. Podrzucam kod jakby ktoś kiedyś coś podobnego chciał robić :-)

C/C++
#include <SFML/Graphics.hpp>

class Rect {
public:
   
const static int rectWidth = 128;
   
const static int rectHeight = 64;
   
   
// rect
   
sf::IntRect _rect;
   
sf::Color _color;
   
   
// to move
   
bool _isMoved;
   
sf::Vector2i _offset;
   
   
Rect() {
       
_rect.size.x = rectWidth;
       
_rect.size.y = rectHeight;
       
_color = sf::Color::Green;
       
       
_isMoved = false;
       
_offset = sf::Vector2i( 0, 0 );
   
}
   
   
void setColor( sf::Color color ) {
       
_color = color;
   
}
   
   
void setColor( bool isIntersected ) {
       
_color =( isIntersected ) ? sf::Color::Red
            : sf::Color::Green;
   
}
   
   
void setPosition( sf::Vector2i position ) {
       
_rect.position = position;
   
}
   
   
void draw( sf::RenderWindow & window ) {
       
sf::RectangleShape rect;
       
rect.setSize( sf::Vector2f( _rect.size ) );
       
rect.setFillColor( _color );
       
rect.setPosition( sf::Vector2f( _rect.position ) );
       
window.draw( rect );
   
}
}
;

class SectionRight {
public:
   
const static int margin = 16;
   
const static int intersectPercent = 90;
   
   
sf::IntRect _rect;
   
std::vector < std::shared_ptr < Rect >> _relativeRects;
   
   
SectionRight() {
       
_rect.size.x = Rect::rectWidth + 2 * margin;
       
_rect.size.y = 600; // window.getSize().y;
       
_rect.position.x = 800 - _rect.size.x; // window.getSize().x - _rect.size.x;
       
_rect.position.y = 0;
   
}
   
   
bool contains( std::shared_ptr < Rect > rect ) {
       
return std::find( _relativeRects.begin(), _relativeRects.end(), rect ) != _relativeRects.end();
   
}
   
   
bool intersect( std::shared_ptr < Rect > rect ) {
       
       
       
// rect to test intersection
       
sf::IntRect intRect;
       
intRect.position = rect->_rect.position;
       
       
// 90 %
       
intRect.position.x = rect->_rect.position.x + rect->_rect.size.x *( 100 - intersectPercent ) / 100;
       
intRect.position.y = rect->_rect.position.y + rect->_rect.size.y *( 100 - intersectPercent ) / 100;
       
intRect.size.x = rect->_rect.size.x * intersectPercent / 100;
       
intRect.size.y = rect->_rect.size.y * intersectPercent / 100;
       
       
// section rect
       
sf::IntRect sectionIntRect;
       
sectionIntRect.position = _rect.position;
       
if( _relativeRects.empty() ) {
           
sectionIntRect.size = sf::Vector2i( _rect.size.x, margin * 2 + Rect::rectHeight );
       
}
       
else {
           
sectionIntRect.size = sf::Vector2i( _rect.size.x, _relativeRects.back()->_rect.position.y + 2 *( Rect::rectHeight + margin ) );
       
}
       
       
       
       
if( intRect.position.x + intRect.size.x * 2 / 8 > sectionIntRect.position.x ) {
           
if( intRect.position.y + intRect.size.y < sectionIntRect.position.y ) {
               
return true;
           
}
           
           
else {
               
bool condition = sectionIntRect.findIntersection( intRect ).has_value();
               
return condition;
           
}
           
        }
       
       
return false;
   
}
   
   
void positionRects() {
       
for( int i = 0; i < _relativeRects.size(); ++i ) {
           
sf::Vector2i newPosition( _rect.position.x + margin, _rect.position.y + margin + i *( Rect::rectHeight + margin ) );
           
_relativeRects[ i ]->setPosition( newPosition );
       
}
    }
   
   
void insertRect( std::shared_ptr < Rect > rect )
   
{
       
auto it = std::find( _relativeRects.begin(), _relativeRects.end(), rect );
       
if( it != _relativeRects.end() ) {
           
_relativeRects.erase( it );
       
}
       
       
int i = 0;
       
int mouseY = rect->_rect.position.y;
       
       
while( i < _relativeRects.size() && mouseY > _relativeRects[ i ]->_rect.position.y ) { i++; }
       
       
_relativeRects.insert( _relativeRects.begin() + i, rect );
       
       
positionRects();
   
}
   
   
   
void addRect( std::shared_ptr < Rect > rect )
   
{
       
if( contains( rect ) ) {
           
insertRect( rect );
           
return;
       
}
       
       
int i = 0;
       
while( i < _relativeRects.size() && rect->_rect.position.y > _relativeRects[ i ]->_rect.position.y ) {
           
i += 1;
       
}
       
       
_relativeRects.insert( _relativeRects.begin() + i, rect );
       
       
positionRects();
   
}
   
   
void removeRect( std::shared_ptr < Rect > rect ) {
       
auto it = std::find( _relativeRects.begin(), _relativeRects.end(), rect );
       
if( it != _relativeRects.end() ) {
           
_relativeRects.erase( it );
       
}
       
       
positionRects();
   
}
   
   
void draw( sf::RenderWindow & window ) {
       
sf::RectangleShape rect;
       
rect.setSize( sf::Vector2f( _rect.size ) );
       
rect.setFillColor( sf::Color::Color( 47, 47, 47 ) );
       
rect.setPosition( sf::Vector2f( _rect.position ) );
       
window.draw( rect );
   
}
   
}
;

std::vector < std::shared_ptr < Rect >> relativeRects;

std::shared_ptr < Rect > pressedRect( sf::Vector2i cursorPosition ) {
   
   
for( auto & rect: relativeRects ) {
       
if( rect->_rect.contains( cursorPosition ) ) {
           
return rect;
       
}
    }
   
   
return nullptr;
}

int main() {
   
   
sf::RenderWindow window( sf::VideoMode( sf::Vector2u( 800, 600 ), 32 ), "Relative Rects" );
   
   
// create Rects
   
relativeRects.push_back( std::make_shared < Rect >() );
   
relativeRects.push_back( std::make_shared < Rect >() );
   
relativeRects.push_back( std::make_shared < Rect >() );
   
relativeRects.push_back( std::make_shared < Rect >() );
   
   
// positioning Rects
   
for( int i = 0; i < relativeRects.size(); i += 1 ) {
       
sf::Vector2i position( 32,( Rect::rectHeight + 16 ) * i );
       
relativeRects[ i ]->setPosition( position );
   
}
   
   
std::shared_ptr < SectionRight > sectionRight = std::make_shared < SectionRight >();
   
sf::Vector2i cursorPosition( 0, 0 );
   
   
while( window.isOpen() ) {
       
       
// handle Events
       
while( const std::optional event = window.pollEvent() ) {
           
           
cursorPosition = sf::Mouse::getPosition( window );
           
           
if( event->is < sf::Event::Closed >() )
               
 window.close();
           
           
// mouse release event
           
if( const auto mouseRelease = event->getIf < sf::Event::MouseButtonReleased >() ) {
               
for( auto & rect: relativeRects ) {
                   
                   
if( rect->_isMoved ) {
                       
                       
( sectionRight->intersect( rect ) ) ? sectionRight->addRect( rect )
                            :
sectionRight->removeRect( rect );
                       
rect->_isMoved = false;
                       
rect->_offset = sf::Vector2i( 0, 0 );
                   
}
                }
            }
           
           
// mouse press event
           
if( const auto mousePress = event->getIf < sf::Event::MouseButtonPressed >() ) {
               
sf::Vector2i cursorPosition = mousePress->position;
               
auto rect = pressedRect( cursorPosition );
               
               
if( rect ) {
                   
rect->_isMoved = true;
                   
rect->_offset = cursorPosition - sf::Vector2i( rect->_rect.position );
               
}
            }
        }
       
       
// update Rects positions
       
for( auto & rect: relativeRects ) {
           
if( rect->_isMoved ) rect->setPosition( cursorPosition - rect->_offset );
           
           
rect->setColor( sectionRight->intersect( rect ) );
       
}
       
       
       
       
window.clear();
       
       
sectionRight->draw( window );
       
       
for( auto & rect: relativeRects ) {
           
rect->draw( window );
       
}
       
window.display();
   
}
   
return 0;
}
P-183870
1 « 2 »
Poprzednia strona Strona 2 z 2