<commit_before>/* See LICENSE file for copyright and license details. */

#include <QWheelEvent>
#include <QScrollBar>
#include <QResizeEvent>
#include <QGraphicsDropShadowEffect>
#include <QResizeEvent>
#include <QGraphicsItem>

#include <iostream>

#include "scene.hpp"
#include "graphicsnode.hpp"
#include "socket.hpp"
#include "graphicsnodedefs.hpp"
#include "edge.hpp"

#include "../node.hpp"

#include "view.hpp"

GraphicsNodeView::GraphicsNodeView(QWidget *parent)
    : GraphicsNodeView(nullptr, parent) {}

GraphicsNodeView::GraphicsNodeView(QGraphicsScene *scene, QWidget *parent)
    : QGraphicsView(scene, parent),
      _panning(false),
      _tmp_edge(nullptr),
      _sock_source(nullptr),
      _sock_sink(nullptr) {
    setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing |
                   QPainter::HighQualityAntialiasing |
                   QPainter::SmoothPixmapTransform);

    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    setResizeAnchor(NoAnchor);
    setTransformationAnchor(AnchorUnderMouse);
}

void GraphicsNodeView::resizeEvent(QResizeEvent *event) {
    // always have the origin in the top left corner
    static bool first_resize = true;
    if (first_resize) {
        // TODO: scale awareness
        centerOn(width() / 2 - 50, height() / 2 - 50);
        first_resize = false;
    }
    QGraphicsView::resizeEvent(event);
}

void GraphicsNodeView::wheelEvent(QWheelEvent *event) {
    if (event->modifiers() & Qt::ControlModifier) {
        setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
        double scaleFactor = 1.25;
        if (event->delta() > 0) {
            // zoom in
            scale(scaleFactor, scaleFactor);
        } else {
            // zoom out
            scale(1.0 / scaleFactor, 1.0 / scaleFactor);
        }
        event->accept();
    } else {
        QGraphicsView::wheelEvent(event);
    }
}

void GraphicsNodeView::mousePressEvent(QMouseEvent *event) {
    switch (event->button()) {
        case Qt::MiddleButton:
            middleMouseButtonPress(event);
            break;
        case Qt::LeftButton:
            leftMouseButtonPress(event);
            break;
        default:
            QGraphicsView::mousePressEvent(event);
    }
}

void GraphicsNodeView::middleMouseButtonRelease(QMouseEvent *event) {
    QMouseEvent fakeEvent(event->type(), event->localPos(), event->screenPos(),
                          event->windowPos(), Qt::LeftButton,
                          event->buttons() & ~Qt::LeftButton,
                          event->modifiers());
    QGraphicsView::mouseReleaseEvent(&fakeEvent);
    setDragMode(QGraphicsView::NoDrag);
}

void GraphicsNodeView::leftMouseButtonRelease(QMouseEvent *event) {
    if (_drag_event) {
        auto sock = socket_at(event->pos());
        if (!sock || !can_accept_edge(sock)) {
            _drag_event->e->disconnect();
        } else {
            switch (_drag_event->mode) {
                case EdgeDragEvent::move_to_source:
                case EdgeDragEvent::connect_to_source:
                    _drag_event->e->connect_source(sock);
                    break;

                case EdgeDragEvent::move_to_sink:
                case EdgeDragEvent::connect_to_sink:
                    _drag_event->e->connect_sink(sock);
                    break;
            }
        }
        delete _drag_event;
        _drag_event = nullptr;
    } else if (_resize_event) {
        // TODO: finally set the width/height of the node ?
        delete _resize_event;
        _resize_event = nullptr;
        setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
    }
    QGraphicsView::mouseReleaseEvent(event);
    setDragMode(QGraphicsView::NoDrag);
}

void GraphicsNodeView::mouseReleaseEvent(QMouseEvent *event) {
    viewport()->setCursor(Qt::ArrowCursor);

    switch (event->button()) {
        case Qt::MiddleButton:
            middleMouseButtonRelease(event);
            break;
        case Qt::LeftButton:
            leftMouseButtonRelease(event);
            break;
        default:
            QGraphicsView::mouseReleaseEvent(event);
    }
}

void GraphicsNodeView::mouseMoveEvent(QMouseEvent *event) {
    // if the left mouse button was pressed and we actually have a mode and
    // temporary edge already set
    if (_drag_event && (event->buttons() & Qt::LeftButton)) {
        // set start/stop depending on drag mode
        switch (_drag_event->mode) {
            case EdgeDragEvent::move_to_source:
            case EdgeDragEvent::connect_to_source:
                _drag_event->e->set_start(mapToScene(event->pos()));
                break;

            case EdgeDragEvent::move_to_sink:
            case EdgeDragEvent::connect_to_sink:
                _drag_event->e->set_stop(mapToScene(event->pos()));
                break;
        }

        // update visual feedback
        auto item = socket_at(event->pos());
        if (!item) {
            viewport()->setCursor(Qt::ClosedHandCursor);
        } else if (item->type() == GraphicsNodeItemTypes::TypeSocket) {
            GraphicsNodeSocket *sock = static_cast<GraphicsNodeSocket *>(item);
            if (!can_accept_edge(sock))
                viewport()->setCursor(Qt::ForbiddenCursor);
            else {
                viewport()->setCursor(Qt::DragMoveCursor);
            }
        }
    } else if (_resize_event && (event->buttons() & Qt::LeftButton)) {
        QPointF size =
            mapToScene(event->pos()) - _resize_event->node->mapToScene(0, 0);

        // snap to grid size
        auto width = round(size.x() / GRIDSIZE) * GRIDSIZE;
        auto height = round(size.y() / GRIDSIZE) * GRIDSIZE;
        _resize_event->node->setSize(width, height);
    } else {
        // no button is pressed, so indicate what the user can do with
        // the item by changing the cursor
        if (event->buttons() == 0) {
            auto item = socket_at(event->pos());
            if (item) {
                QPointF scenePos = mapToScene(event->pos());
                QPointF itemPos = item->mapFromScene(scenePos);
                if (item->isInSocketCircle(itemPos))
                    viewport()->setCursor(Qt::OpenHandCursor);
                else
                    viewport()->setCursor(Qt::ArrowCursor);
            } else
                viewport()->setCursor(Qt::ArrowCursor);
        }
        QGraphicsView::mouseMoveEvent(event);
    }
}

void GraphicsNodeView::leftMouseButtonPress(QMouseEvent *event) {
    QGraphicsView::mousePressEvent(event);
    // GUI logic: if we click on a socket, we need to handle
    // the event appropriately
    QGraphicsItem *item = itemAt(event->pos());
    if (!item) {
        setDragMode(QGraphicsView::RubberBandDrag);
        QGraphicsView::mousePressEvent(event);
        return;
    }

    switch (item->type()) {
        case GraphicsNodeItemTypes::TypeSocket: {
            QPointF scenePos = mapToScene(event->pos());
            QPointF itemPos = item->mapFromScene(scenePos);
            GraphicsNodeSocket *sock = static_cast<GraphicsNodeSocket *>(item);
            if (sock->isInSocketCircle(itemPos)) {<commit_msg>Show resize corner by changing cursor shape<commit_after>/* See LICENSE file for copyright and license details. */

#include <QWheelEvent>
#include <QScrollBar>
#include <QResizeEvent>
#include <QGraphicsDropShadowEffect>
#include <QResizeEvent>
#include <QGraphicsItem>

#include <iostream>

#include "scene.hpp"
#include "graphicsnode.hpp"
#include "socket.hpp"
#include "graphicsnodedefs.hpp"
#include "edge.hpp"

#include "../node.hpp"

#include "view.hpp"

GraphicsNodeView::GraphicsNodeView(QWidget *parent)
    : GraphicsNodeView(nullptr, parent) {}

GraphicsNodeView::GraphicsNodeView(QGraphicsScene *scene, QWidget *parent)
    : QGraphicsView(scene, parent),
      _panning(false),
      _tmp_edge(nullptr),
      _sock_source(nullptr),
      _sock_sink(nullptr) {
    setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing |
                   QPainter::HighQualityAntialiasing |
                   QPainter::SmoothPixmapTransform);

    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    setResizeAnchor(NoAnchor);
    setTransformationAnchor(AnchorUnderMouse);
}

void GraphicsNodeView::resizeEvent(QResizeEvent *event) {
    // always have the origin in the top left corner
    static bool first_resize = true;
    if (first_resize) {
        // TODO: scale awareness
        centerOn(width() / 2 - 50, height() / 2 - 50);
        first_resize = false;
    }
    QGraphicsView::resizeEvent(event);
}

void GraphicsNodeView::wheelEvent(QWheelEvent *event) {
    if (event->modifiers() & Qt::ControlModifier) {
        setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
        double scaleFactor = 1.25;
        if (event->delta() > 0) {
            // zoom in
            scale(scaleFactor, scaleFactor);
        } else {
            // zoom out
            scale(1.0 / scaleFactor, 1.0 / scaleFactor);
        }
        event->accept();
    } else {
        QGraphicsView::wheelEvent(event);
    }
}

void GraphicsNodeView::mousePressEvent(QMouseEvent *event) {
    switch (event->button()) {
        case Qt::MiddleButton:
            middleMouseButtonPress(event);
            break;
        case Qt::LeftButton:
            leftMouseButtonPress(event);
            break;
        default:
            QGraphicsView::mousePressEvent(event);
    }
}

void GraphicsNodeView::middleMouseButtonRelease(QMouseEvent *event) {
    QMouseEvent fakeEvent(event->type(), event->localPos(), event->screenPos(),
                          event->windowPos(), Qt::LeftButton,
                          event->buttons() & ~Qt::LeftButton,
                          event->modifiers());
    QGraphicsView::mouseReleaseEvent(&fakeEvent);
    setDragMode(QGraphicsView::NoDrag);
}

void GraphicsNodeView::leftMouseButtonRelease(QMouseEvent *event) {
    if (_drag_event) {
        auto sock = socket_at(event->pos());
        if (!sock || !can_accept_edge(sock)) {
            _drag_event->e->disconnect();
        } else {
            switch (_drag_event->mode) {
                case EdgeDragEvent::move_to_source:
                case EdgeDragEvent::connect_to_source:
                    _drag_event->e->connect_source(sock);
                    break;

                case EdgeDragEvent::move_to_sink:
                case EdgeDragEvent::connect_to_sink:
                    _drag_event->e->connect_sink(sock);
                    break;
            }
        }
        delete _drag_event;
        _drag_event = nullptr;
    } else if (_resize_event) {
        // TODO: finally set the width/height of the node ?
        delete _resize_event;
        _resize_event = nullptr;
        setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
    }
    QGraphicsView::mouseReleaseEvent(event);
    setDragMode(QGraphicsView::NoDrag);
}

void GraphicsNodeView::mouseReleaseEvent(QMouseEvent *event) {
    viewport()->setCursor(Qt::ArrowCursor);

    switch (event->button()) {
        case Qt::MiddleButton:
            middleMouseButtonRelease(event);
            break;
        case Qt::LeftButton:
            leftMouseButtonRelease(event);
            break;
        default:
            QGraphicsView::mouseReleaseEvent(event);
    }
}

void GraphicsNodeView::mouseMoveEvent(QMouseEvent *event) {
    // if the left mouse button was pressed and we actually have a mode and
    // temporary edge already set
    if (_drag_event && (event->buttons() & Qt::LeftButton)) {
        // set start/stop depending on drag mode
        switch (_drag_event->mode) {
            case EdgeDragEvent::move_to_source:
            case EdgeDragEvent::connect_to_source:
                _drag_event->e->set_start(mapToScene(event->pos()));
                break;

            case EdgeDragEvent::move_to_sink:
            case EdgeDragEvent::connect_to_sink:
                _drag_event->e->set_stop(mapToScene(event->pos()));
                break;
        }

        // update visual feedback
        auto item = socket_at(event->pos());
        if (!item) {
            viewport()->setCursor(Qt::ClosedHandCursor);
        } else if (item->type() == GraphicsNodeItemTypes::TypeSocket) {
            GraphicsNodeSocket *sock = static_cast<GraphicsNodeSocket *>(item);
            if (!can_accept_edge(sock))
                viewport()->setCursor(Qt::ForbiddenCursor);
            else {
                viewport()->setCursor(Qt::DragMoveCursor);
            }
        }
    } else if (_resize_event && (event->buttons() & Qt::LeftButton)) {
        QPointF size =
            mapToScene(event->pos()) - _resize_event->node->mapToScene(0, 0);

        // snap to grid size
        auto width = round(size.x() / GRIDSIZE) * GRIDSIZE;
        auto height = round(size.y() / GRIDSIZE) * GRIDSIZE;
        _resize_event->node->setSize(width, height);
    } else {
        // no button is pressed, so indicate what the user can do with
        // the item by changing the cursor
        if (event->buttons() == 0) {
            auto item = socket_at(event->pos());
            if (item) {
                QPointF scenePos = mapToScene(event->pos());
                QPointF itemPos = item->mapFromScene(scenePos);
                if (item->isInSocketCircle(itemPos))
                    viewport()->setCursor(Qt::OpenHandCursor);

                else
                    viewport()->setCursor(Qt::ArrowCursor);
            }
            else {

            QGraphicsItem *item = itemAt(event->pos());
            if(item && item->type() == GraphicsNodeItemTypes::TypeNode) {
                QPointF scenePos = mapToScene(event->pos());
                QPointF eventPos = item->mapFromScene(scenePos);
                GraphicsNode *node = static_cast<GraphicsNode *>(item);
                
                // resize corner?
                if (eventPos.x() > (node->width() - 10) && eventPos.y() > (node->height() - 10))
                    viewport()->setCursor(Qt::SizeFDiagCursor); 
                else
                    viewport()->setCursor(Qt::SizeAllCursor);
            }
            else
                viewport()->setCursor(Qt::ArrowCursor);
            }
        }
        QGraphicsView::mouseMoveEvent(event);
    }
}

void GraphicsNodeView::leftMouseButtonPress(QMouseEvent *event) {
    QGraphicsView::mousePressEvent(event);
    // GUI logic: if we click on a socket, we need to handle
    // the event appropriately
    QGraphicsItem *item = itemAt(event->pos());
    if (!item) {
        setDragMode(QGraphicsView::RubberBandDrag);
        QGraphicsView::mousePressEvent(event);
        return;
    }

    switch (item->type()) {
        case GraphicsNodeItemTypes::TypeSocket: {
            QPointF scenePos = mapToScene(event->pos());
            QPointF itemPos = item->mapFromScene(scenePos);
            GraphicsNodeSocket *sock = static_cast<GraphicsNodeSocket *>(item);
            if (sock->isInSocketCircle(itemPos)) {
{'fraction_non_alphanumeric': 0.11624677643324736, 'fraction_numerical': 0.0025127289558949943, 'mean_word_length': 2.3683741648106906, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 138, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '720098', 'n_tokens_mistral': 4315, 'n_tokens_neox': 4179, 'n_words': 809}