101 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C++
		
	
	
	
// Example of how UIFrame would implement unified click handling
 | 
						|
//
 | 
						|
// Click Priority Example:
 | 
						|
// - Dialog Frame (has click handler to drag window)
 | 
						|
//   - Title Caption (no click handler)
 | 
						|
//   - Button Frame (has click handler)
 | 
						|
//     - Button Caption "OK" (no click handler)
 | 
						|
//   - Close X Sprite (has click handler)
 | 
						|
//
 | 
						|
// Clicking on:
 | 
						|
// - "OK" text -> Button Frame gets the click (deepest parent with handler)
 | 
						|
// - Close X -> Close sprite gets the click 
 | 
						|
// - Title bar -> Dialog Frame gets the click (no child has handler there)
 | 
						|
// - Outside dialog -> nullptr (bounds check fails)
 | 
						|
 | 
						|
class UIFrame : public UIDrawable, protected RectangularContainer {
 | 
						|
private:
 | 
						|
    // Implementation of container interface
 | 
						|
    sf::Vector2f toChildCoordinates(sf::Vector2f localPoint, int childIndex) const override {
 | 
						|
        // Children use same coordinate system as frame's local coordinates
 | 
						|
        return localPoint;
 | 
						|
    }
 | 
						|
    
 | 
						|
    UIDrawable* getClickHandler() override {
 | 
						|
        return click_callable ? this : nullptr;
 | 
						|
    }
 | 
						|
    
 | 
						|
    std::vector<UIDrawable*> getClickableChildren() override {
 | 
						|
        std::vector<UIDrawable*> result;
 | 
						|
        for (auto& child : *children) {
 | 
						|
            result.push_back(child.get());
 | 
						|
        }
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
    
 | 
						|
public:
 | 
						|
    UIDrawable* click_at(sf::Vector2f point) override {
 | 
						|
        // Update bounds from box
 | 
						|
        bounds = sf::FloatRect(box.getPosition().x, box.getPosition().y, 
 | 
						|
                              box.getSize().x, box.getSize().y);
 | 
						|
        
 | 
						|
        // Use unified handler
 | 
						|
        return handleClick(point);
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
// Example for UIGrid with entity coordinate transformation
 | 
						|
class UIGrid : public UIDrawable, protected RectangularContainer {
 | 
						|
private:
 | 
						|
    sf::Vector2f toChildCoordinates(sf::Vector2f localPoint, int childIndex) const override {
 | 
						|
        // For entities, we need to transform from pixel coordinates to grid coordinates
 | 
						|
        // This is where the grid's special coordinate system is handled
 | 
						|
        
 | 
						|
        // Assuming entity positions are in grid cells, not pixels
 | 
						|
        // We pass pixel coordinates relative to the grid's rendering area
 | 
						|
        return localPoint; // Entities will handle their own sprite positioning
 | 
						|
    }
 | 
						|
    
 | 
						|
    std::vector<UIDrawable*> getClickableChildren() override {
 | 
						|
        std::vector<UIDrawable*> result;
 | 
						|
        
 | 
						|
        // Only check entities that are visible on screen
 | 
						|
        float left_edge = center_x - (box.getSize().x / 2.0f) / (grid_size * zoom);
 | 
						|
        float top_edge = center_y - (box.getSize().y / 2.0f) / (grid_size * zoom);
 | 
						|
        float right_edge = left_edge + (box.getSize().x / (grid_size * zoom));
 | 
						|
        float bottom_edge = top_edge + (box.getSize().y / (grid_size * zoom));
 | 
						|
        
 | 
						|
        for (auto& entity : entities) {
 | 
						|
            // Check if entity is within visible bounds
 | 
						|
            if (entity->position.x >= left_edge - 1 && entity->position.x < right_edge + 1 &&
 | 
						|
                entity->position.y >= top_edge - 1 && entity->position.y < bottom_edge + 1) {
 | 
						|
                result.push_back(&entity->sprite);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return result;
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
// For Scene, which has no coordinate transformation
 | 
						|
class PyScene : protected UIContainerBase {
 | 
						|
private:
 | 
						|
    sf::Vector2f toLocalCoordinates(sf::Vector2f point) const override {
 | 
						|
        // Scene uses window coordinates directly
 | 
						|
        return point;
 | 
						|
    }
 | 
						|
    
 | 
						|
    sf::Vector2f toChildCoordinates(sf::Vector2f localPoint, int childIndex) const override {
 | 
						|
        // Top-level drawables use window coordinates
 | 
						|
        return localPoint;
 | 
						|
    }
 | 
						|
    
 | 
						|
    bool containsPoint(sf::Vector2f localPoint) const override {
 | 
						|
        // Scene contains all points (full window)
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
    
 | 
						|
    UIDrawable* getClickHandler() override {
 | 
						|
        // Scene itself doesn't handle clicks
 | 
						|
        return nullptr;
 | 
						|
    }
 | 
						|
}; |