/*
QAD - Qt ADvanced
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see .
*/
#ifndef BLOCKBUSITEM_H
#define BLOCKBUSITEM_H
#include "blockitem.h"
#include "qad_blockview_export.h"
class QAD_BLOCKVIEW_EXPORT BlockBusItem
: public QGraphicsObject
, public PropertyStorage {
Q_OBJECT
Q_INTERFACES(QGraphicsItem)
Q_PROPERTY(double pointSize READ pointSize WRITE setPointSize DESIGNABLE false SCRIPTABLE false)
friend class BlockView;
public:
BlockBusItem(bool temp = false);
BlockBusItem(const BlockBusItem & other);
~BlockBusItem() { ; }
struct QAD_BLOCKVIEW_EXPORT PointInfo {
enum class Type {
None,
Node, // point > 2 segments
Endpoint,
Segment
};
Type type = Type::None;
BlockItemPin * pin = nullptr; // if tEndpoint and pin connected
};
void setGridStep(double gs) { grid_step = gs; }
void setEndpointsNumber(int num) { max_ep = num; }
void setImages(const QImage & bus, const QImage & end = QImage()) {
im_bus = bus;
im_end = end;
update();
}
void setBusImageScale(double s) {
im_bus_scale = s;
update();
}
void setEndpointImageScale(double s) {
im_end_scale = s;
update();
}
void setBusType(int type_) { bus_type = type_; }
void setBusName(const QString & name) { bus_name = name; }
int busType() const { return bus_type; }
QString busName() const { return bus_name; }
double busImageScale() const { return im_bus_scale; }
double endpointImageScale() const { return im_end_scale; }
void appendPoint(const QPointF & p);
void appendPoint(qreal x, qreal y);
void movePolyline(const QPointF & dp);
void clear();
void setPen(const QPen & p) {
p_ = p;
update();
}
QPen pen() const { return p_; }
void setBrush(const QBrush & b) {
b_ = b;
update();
}
QBrush brush() const { return b_; }
double width() const { return pen_width; }
void setWidth(const double & w);
void setColor(const QColor & c);
void setSquareNodes(bool yes);
void markAsInput();
void markAsOutput();
void unmark();
void simplify(bool full = true);
bool hasNullSegment() const;
void adjustLine();
int endpointCount() const;
bool isBusSelected() const { return selSegment >= 0 || selPoint >= 0; }
QList connectedBlocks() const;
QList connectedPins() const;
PointInfo pointInfo(QPointF pos) const;
void setBusState(bool state);
bool busState() const { return state_ > 0; }
void clearBusState();
QByteArray save() const;
void load(const QByteArray & data);
BlockBusItem * copy() const;
void saveState();
void restoreState();
PIValueTree & values() { return value_tree; }
enum {
Type = UserType + 2
};
protected:
void _init();
void reconnect();
void updateGeometry();
bool checkDelete();
void emitAction(BlockItemBase::Action a);
void testPoint(QPointF pos, int * sel_point, int * sel_segment, bool for_trace = false) const;
int addPoint(const QPointF & point, bool update = true);
int segmentPointPair(int point, int * seg = 0) const;
int pointSegmentsCount(int point, QList * segs = 0) const;
void removePoint(int index);
void removeSegment(int index);
void movePoint(int index, const QPointF & dp);
QVector endpoints() const;
QVector endpointLine(int ep, double angle) const;
int neighborSegmentPoint(int point, int * seg) const;
int type() const { return Type; }
QRectF boundingRect() const;
bool sceneEvent(QEvent * e);
void hoverEnterEvent(QGraphicsSceneHoverEvent * e);
void hoverMoveEvent(QGraphicsSceneHoverEvent * e);
void hoverLeaveEvent(QGraphicsSceneHoverEvent * e);
void mousePressEvent(QGraphicsSceneMouseEvent * e);
void mouseMoveEvent(QGraphicsSceneMouseEvent * e);
void mouseReleaseEvent(QGraphicsSceneMouseEvent * e);
void paint(QPainter * p, const QStyleOptionGraphicsItem * o, QWidget * w = 0);
QPointF lp, new_start, new_end, press_pos, qp;
QPen p_, ph, pu, pa, pr, pn;
QBrush b_, bh, bu, ba, br;
QString tt, bus_name;
QList> segments, ends_ind, segments_s, ends_ind_s;
QMap connections_;
QVector ends, ends_s;
QImage im_bus, im_end;
QPolygonF pol, bpol, pol_s;
Qt::KeyboardModifiers mm_mods;
PIValueTree value_tree;
bool temp_, square_node;
double pen_width, grid_step, im_bus_scale, im_end_scale;
int selPoint, selSegment, max_ep, bus_type, state_;
bool moved, deleted, mark_in, mark_out, new_segment, mm_cancel, lm_point;
private:
double pointSize() const { return point_size; }
void setPointSize(double s);
double point_size;
QPropertyAnimation anim_point_size;
};
inline QDataStream & operator<<(QDataStream & s, const BlockBusItem * b) {
s << b->save();
return s;
}
inline QDataStream & operator>>(QDataStream & s, BlockBusItem *& b) {
QByteArray ba;
s >> ba;
b = new BlockBusItem();
b->load(ba);
return s;
}
#endif // BLOCKBUSITEM_H