Make skeleton UI more fluent
parent
5b597b0f0c
commit
0ee18d41a8
|
@ -13,7 +13,8 @@ SkeletonEditGraphicsView::SkeletonEditGraphicsView(QWidget *parent) :
|
|||
m_inAddNodeMode(true),
|
||||
m_nextStartNodeItem(NULL),
|
||||
m_lastHoverNodeItem(NULL),
|
||||
m_lastMousePos(0, 0)
|
||||
m_lastMousePos(0, 0),
|
||||
m_isMovingNodeItem(false)
|
||||
{
|
||||
setScene(new QGraphicsScene());
|
||||
|
||||
|
@ -111,6 +112,7 @@ void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event)
|
|||
setNextStartNodeItem(masterNode);
|
||||
emit nodesChanged();
|
||||
}
|
||||
m_isMovingNodeItem = false;
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
if (m_inAddNodeMode) {
|
||||
toggleAddNodeMode();
|
||||
|
@ -118,6 +120,19 @@ void SkeletonEditGraphicsView::mouseReleaseEvent(QMouseEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
bool SkeletonEditGraphicsView::canNodeItemMoveTo(SkeletonEditNodeItem *item, QPointF moveTo)
|
||||
{
|
||||
if (moveTo.x() < 0)
|
||||
return false;
|
||||
if (moveTo.y() < 0)
|
||||
return false;
|
||||
if (moveTo.x() + item->rect().width() >= m_backgroundItem->boundingRect().width())
|
||||
return false;
|
||||
if (moveTo.y() + item->rect().height() >= m_backgroundItem->boundingRect().height())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkeletonEditGraphicsView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mouseMoveEvent(event);
|
||||
|
@ -139,57 +154,64 @@ void SkeletonEditGraphicsView::mouseMoveEvent(QMouseEvent *event)
|
|||
m_pendingEdgeItem->setLine(QLineF(m_nextStartNodeItem->origin(), QPointF(moveTo.x() + m_pendingNodeItem->rect().width() / 2,
|
||||
moveTo.y() + m_pendingNodeItem->rect().height() / 2)));
|
||||
}
|
||||
if (!m_inAddNodeMode) {
|
||||
SkeletonEditNodeItem *hoverNodeItem = findNodeItemByPos(pos);
|
||||
if (hoverNodeItem) {
|
||||
hoverNodeItem->setHighlighted(true);
|
||||
}
|
||||
if (hoverNodeItem != m_lastHoverNodeItem) {
|
||||
if (m_lastHoverNodeItem)
|
||||
if (!m_isMovingNodeItem) {
|
||||
if (!m_inAddNodeMode) {
|
||||
SkeletonEditNodeItem *hoverNodeItem = findNodeItemByPos(pos);
|
||||
if (hoverNodeItem) {
|
||||
hoverNodeItem->setHighlighted(true);
|
||||
}
|
||||
if (hoverNodeItem != m_lastHoverNodeItem) {
|
||||
if (m_lastHoverNodeItem)
|
||||
m_lastHoverNodeItem->setHighlighted(false);
|
||||
m_lastHoverNodeItem = hoverNodeItem;
|
||||
}
|
||||
} else {
|
||||
if (m_lastHoverNodeItem) {
|
||||
m_lastHoverNodeItem->setHighlighted(false);
|
||||
m_lastHoverNodeItem = hoverNodeItem;
|
||||
}
|
||||
} else {
|
||||
if (m_lastHoverNodeItem) {
|
||||
m_lastHoverNodeItem->setHighlighted(false);
|
||||
m_lastHoverNodeItem = NULL;
|
||||
m_lastHoverNodeItem = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
QPointF curMousePos = pos;
|
||||
if (m_lastHoverNodeItem) {
|
||||
if (event->buttons() & Qt::LeftButton) {
|
||||
if ((event->buttons() & Qt::LeftButton) &&
|
||||
(curMousePos != m_lastMousePos || m_isMovingNodeItem)) {
|
||||
m_isMovingNodeItem = true;
|
||||
QRectF rect = m_lastHoverNodeItem->rect();
|
||||
QRectF slaveRect;
|
||||
if (m_lastHoverNodeItem->isMaster()) {
|
||||
rect.translate(curMousePos.x() - m_lastMousePos.x(), curMousePos.y() - m_lastMousePos.y());
|
||||
QRectF slaveRect = m_lastHoverNodeItem->slave()->rect();
|
||||
slaveRect = m_lastHoverNodeItem->slave()->rect();
|
||||
slaveRect.translate(0, curMousePos.y() - m_lastMousePos.y());
|
||||
m_lastHoverNodeItem->slave()->setRect(slaveRect);
|
||||
} else {
|
||||
rect.translate(curMousePos.x() - m_lastMousePos.x(), 0);
|
||||
}
|
||||
m_lastHoverNodeItem->setRect(rect);
|
||||
QList<QGraphicsItem *>::iterator it;
|
||||
QList<QGraphicsItem *> list = scene()->items();
|
||||
for (it = list.begin(); it != list.end(); ++it) {
|
||||
if ((*it)->data(0).toString() == "edge") {
|
||||
SkeletonEditEdgeItem *edgeItem = static_cast<SkeletonEditEdgeItem *>(*it);
|
||||
if (edgeItem->connects(m_lastHoverNodeItem))
|
||||
edgeItem->updatePosition();
|
||||
if (canNodeItemMoveTo(m_lastHoverNodeItem, QPointF(rect.x(), rect.y()))) {
|
||||
if (m_lastHoverNodeItem->isMaster()) {
|
||||
m_lastHoverNodeItem->slave()->setRect(slaveRect);
|
||||
}
|
||||
m_lastHoverNodeItem->setRect(rect);
|
||||
QList<QGraphicsItem *>::iterator it;
|
||||
QList<QGraphicsItem *> list = scene()->items();
|
||||
for (it = list.begin(); it != list.end(); ++it) {
|
||||
if ((*it)->data(0).toString() == "edge") {
|
||||
SkeletonEditEdgeItem *edgeItem = static_cast<SkeletonEditEdgeItem *>(*it);
|
||||
if (edgeItem->connects(m_lastHoverNodeItem))
|
||||
edgeItem->updatePosition();
|
||||
}
|
||||
}
|
||||
emit nodesChanged();
|
||||
}
|
||||
emit nodesChanged();
|
||||
}
|
||||
}
|
||||
m_lastMousePos = curMousePos;
|
||||
}
|
||||
|
||||
void SkeletonEditGraphicsView::wheelEvent(QWheelEvent *event)
|
||||
void SkeletonEditGraphicsView::AddItemRadius(QGraphicsEllipseItem *item, float delta)
|
||||
{
|
||||
QWidget::wheelEvent(event);
|
||||
qreal delta = event->delta();
|
||||
QSizeF oldSize = m_pendingNodeItem->rect().size();
|
||||
QPointF originPt = QPointF(m_pendingNodeItem->rect().left() + oldSize.width() / 2,
|
||||
m_pendingNodeItem->rect().top() + oldSize.height() / 2);
|
||||
QSizeF oldSize = item->rect().size();
|
||||
QPointF originPt = QPointF(item->rect().left() + oldSize.width() / 2,
|
||||
item->rect().top() + oldSize.height() / 2);
|
||||
QSizeF newSize = QSizeF(oldSize.width() + delta, oldSize.height() + delta);
|
||||
if (newSize.width() < m_minimalNodeSize || newSize.height() < m_minimalNodeSize) {
|
||||
newSize.setWidth(m_minimalNodeSize);
|
||||
|
@ -201,12 +223,46 @@ void SkeletonEditGraphicsView::wheelEvent(QWheelEvent *event)
|
|||
return;
|
||||
if (newLeftTop.y() < 0 || newLeftTop.y() + newSize.height() >= m_backgroundItem->boundingRect().height())
|
||||
return;
|
||||
m_pendingNodeItem->setRect(newLeftTop.x(),
|
||||
item->setRect(newLeftTop.x(),
|
||||
newLeftTop.y(),
|
||||
newSize.width(),
|
||||
newSize.height());
|
||||
}
|
||||
|
||||
bool SkeletonEditGraphicsView::canAddItemRadius(QGraphicsEllipseItem *item, float delta)
|
||||
{
|
||||
QSizeF oldSize = item->rect().size();
|
||||
QPointF originPt = QPointF(item->rect().left() + oldSize.width() / 2,
|
||||
item->rect().top() + oldSize.height() / 2);
|
||||
QSizeF newSize = QSizeF(oldSize.width() + delta, oldSize.height() + delta);
|
||||
if (newSize.width() < m_minimalNodeSize || newSize.height() < m_minimalNodeSize) {
|
||||
newSize.setWidth(m_minimalNodeSize);
|
||||
newSize.setHeight(m_minimalNodeSize);
|
||||
}
|
||||
QPointF newLeftTop = QPointF(originPt.x() - newSize.width() / 2,
|
||||
originPt.y() - newSize.height() / 2);
|
||||
if (newLeftTop.x() < 0 || newLeftTop.x() + newSize.width() >= m_backgroundItem->boundingRect().width())
|
||||
return false;
|
||||
if (newLeftTop.y() < 0 || newLeftTop.y() + newSize.height() >= m_backgroundItem->boundingRect().height())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkeletonEditGraphicsView::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
QWidget::wheelEvent(event);
|
||||
qreal delta = event->delta();
|
||||
AddItemRadius(m_pendingNodeItem, delta);
|
||||
if (!m_inAddNodeMode && m_lastHoverNodeItem) {
|
||||
if (canAddItemRadius(m_lastHoverNodeItem, delta) &&
|
||||
canAddItemRadius(m_lastHoverNodeItem->pair(), delta)) {
|
||||
AddItemRadius(m_lastHoverNodeItem, delta);
|
||||
AddItemRadius(m_lastHoverNodeItem->pair(), delta);
|
||||
}
|
||||
emit nodesChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void SkeletonEditGraphicsView::setNextStartNodeItem(SkeletonEditNodeItem *item)
|
||||
{
|
||||
if (m_nextStartNodeItem != item) {
|
||||
|
|
|
@ -30,12 +30,15 @@ private:
|
|||
SkeletonEditNodeItem *m_nextStartNodeItem;
|
||||
SkeletonEditNodeItem *m_lastHoverNodeItem;
|
||||
QPointF m_lastMousePos;
|
||||
bool m_isMovingNodeItem;
|
||||
void toggleAddNodeMode();
|
||||
void applyAddNodeMode();
|
||||
SkeletonEditNodeItem *findNodeItemByPos(QPointF pos);
|
||||
void setNextStartNodeItem(SkeletonEditNodeItem *item);
|
||||
float findXForSlave(float x);
|
||||
|
||||
bool canNodeItemMoveTo(SkeletonEditNodeItem *item, QPointF moveTo);
|
||||
void AddItemRadius(QGraphicsEllipseItem *item, float delta);
|
||||
bool canAddItemRadius(QGraphicsEllipseItem *item, float delta);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,11 @@ void SkeletonEditNodeItem::setSlave(SkeletonEditNodeItem *nodeItem)
|
|||
m_slave = nodeItem;
|
||||
}
|
||||
|
||||
SkeletonEditNodeItem *SkeletonEditNodeItem::pair()
|
||||
{
|
||||
return m_master ? m_master : m_slave;
|
||||
}
|
||||
|
||||
SkeletonEditNodeItem *SkeletonEditNodeItem::slave()
|
||||
{
|
||||
return m_slave;
|
||||
|
|
|
@ -18,6 +18,7 @@ public:
|
|||
void setSlave(SkeletonEditNodeItem *nodeItem);
|
||||
SkeletonEditNodeItem *master();
|
||||
SkeletonEditNodeItem *slave();
|
||||
SkeletonEditNodeItem *pair();
|
||||
private:
|
||||
bool m_highlighted;
|
||||
bool m_isNextStartNode;
|
||||
|
|
|
@ -83,6 +83,7 @@ void SkeletonToMesh::process()
|
|||
float top = -1;
|
||||
float bottom = -1;
|
||||
float zLeft = -1;
|
||||
float zRight = -1;
|
||||
for (size_t i = 0; i < m_nodes.size(); i++) {
|
||||
SkeletonNode *node = &m_nodes[i];
|
||||
if (left < 0 || node->originX < left) {
|
||||
|
@ -100,19 +101,23 @@ void SkeletonToMesh::process()
|
|||
if (zLeft < 0 || node->originZ < zLeft) {
|
||||
zLeft = node->originZ;
|
||||
}
|
||||
if (node->originZ > zRight) {
|
||||
zRight = node->originZ;
|
||||
}
|
||||
}
|
||||
float height = bottom - top;
|
||||
if (height <= 0) {
|
||||
emit finished();
|
||||
return;
|
||||
}
|
||||
float zWidth = right - left;
|
||||
void *context = meshlite_create_context();
|
||||
int bmesh = meshlite_bmesh_create(context);
|
||||
for (size_t i = 0; i < m_nodes.size(); i++) {
|
||||
SkeletonNode *node = &m_nodes[i];
|
||||
float x = (node->originX - left - height / 2) / height;
|
||||
float y = (node->originY - top - height / 2) / height;
|
||||
float z = (node->originZ - zLeft - height / 2) / height;
|
||||
float z = (node->originZ - zLeft - zWidth / 2) / height;
|
||||
float r = node->radius / height;
|
||||
node->bmeshNodeId = meshlite_bmesh_add_node(context, bmesh, x, y, z, r);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue