Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 78 additions & 56 deletions src/qtitchescontrols/qtitchesblockdroparea.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,16 @@ QString mimeTypeForTypeCategory(Core::Block::TypeCategory typeCategory)
return {};
}

QString mimeTypeForAction(BlockDropArea::DropAction dropAction)
BlockDropArea::DropActions actionsForMimeType(const QString &mimeType)
{
switch (dropAction) {
case BlockDropArea::PrependBlock:
case BlockDropArea::AppendBlock:
return s_mimeTypeBlockType;

case BlockDropArea::ApplyBooleanExpression:
return s_mimeTypeBooleanExpression;

case BlockDropArea::ApplyNumberExpression:
return s_mimeTypeNumberExpression;

case BlockDropArea::ApplyStringExpression:
return s_mimeTypeStringExpression;
}
if (mimeType == s_mimeTypeBlockType)
return BlockDropArea::PrependBlock | BlockDropArea::AppendBlock;
if (mimeType == s_mimeTypeBooleanExpression)
return BlockDropArea::ApplyBooleanExpression;
if (mimeType == s_mimeTypeNumberExpression)
return BlockDropArea::ApplyNumberExpression;
if (mimeType == s_mimeTypeStringExpression)
return BlockDropArea::ApplyStringExpression;

return {};
}
Expand All @@ -78,14 +72,14 @@ BlockDropArea::DropActions BlockDropArea::acceptedDropActions() const
return m_acceptedDropActions;
}

BlockDropArea::DropAction BlockDropArea::pendingDropAction() const
BlockDropArea::DropActions BlockDropArea::floatingDropActions() const
{
return m_pendingDropSuspended ? DropAction{} : m_pendingDropAction;
return m_floatingDropActions;
}

QByteArray BlockDropArea::typeInfo() const
BlockDropArea::DropAction BlockDropArea::pendingDropAction() const
{
return m_typeInfo;
return m_pendingDropAction;
}

QVariantMap BlockDropArea::createMimeData(const QJsonObject &typeInfo) const
Expand All @@ -102,76 +96,104 @@ QVariantMap BlockDropArea::createMimeData(const QJsonObject &typeInfo) const
void BlockDropArea::dragEnterEvent(QDragEnterEvent *event)
{
const auto mimeData = event->mimeData();
for (const auto &member: QMetaEnum::fromType<DropAction>()) {
const auto action = member.value<DropAction>();
if (!mimeData)
return;

if (eventViolatesAction(event, action))
continue;
m_typeInfo.clear();
m_floatingDropActions = {};

if ((m_acceptedDropActions & action) == action) {
m_typeInfo = mimeData->data(mimeTypeForAction(action));
for (const auto &format: mimeData->formats()) {
if (const auto actions = (actionsForMimeType(format) & m_acceptedDropActions)) {
if (m_typeInfo.isEmpty())
m_typeInfo = mimeData->data(format);

if (!m_typeInfo.isEmpty()) {
event->accept();
m_pendingDropAction = action;
emit pendingDropActionChanged(m_pendingDropAction);
return;
}
m_floatingDropActions |= actions;
}
}

cancelDrop();
if ((m_pendingDropAction = findActionForEvent(event)) != 0) {
event->accept(answerRect(m_pendingDropAction));
emit pendingDropActionChanged(m_pendingDropAction);
}

QQuickItem::dragEnterEvent(event);
}

void BlockDropArea::dragMoveEvent(QDragMoveEvent *event)
{
if (m_pendingDropAction) {
const auto suspendRequired = eventViolatesAction(event, m_pendingDropAction);
if (m_pendingDropSuspended != suspendRequired) {
m_pendingDropSuspended = suspendRequired;
emit pendingDropActionChanged(pendingDropAction());
}
const auto action = findActionForEvent(event);

if (m_pendingDropAction != action) {
m_pendingDropAction = action;

if (m_pendingDropAction)
event->accept(answerRect(m_pendingDropAction));
else
event->ignore();

emit pendingDropActionChanged(m_pendingDropAction);
}

QQuickItem::dragMoveEvent(event);
}

void BlockDropArea::dragLeaveEvent(QDragLeaveEvent *event)
{
if (m_pendingDropAction) {
cancelDrop();
} else {
QQuickItem::dragLeaveEvent(event);
}
resetDropActionState();
QQuickItem::dragLeaveEvent(event);
}

void BlockDropArea::dropEvent(QDropEvent *event)
{
if (m_pendingDropAction) {
event->accept();
emit typeInfoDropped(m_pendingDropAction, m_typeInfo);
cancelDrop();
} else {
QQuickItem::dropEvent(event);
}

resetDropActionState();
QQuickItem::dropEvent(event);
}

void BlockDropArea::cancelDrop()
QRect BlockDropArea::answerRect(BlockDropArea::DropAction action) const
{
m_typeInfo.clear();
m_pendingDropAction = {};
emit pendingDropActionChanged(m_pendingDropAction);
const auto center = height()/2;

switch(action) {
case PrependBlock:
return {0, 0, qRound(width()), qRound(center)};

case AppendBlock:
return {0, qRound(height() - center), qRound(width()), qRound(center)};

case ApplyBooleanExpression:
case ApplyNumberExpression:
case ApplyStringExpression:
break;
}

return {};
}

bool BlockDropArea::eventViolatesAction(QDropEvent *event, BlockDropArea::DropAction action) const
BlockDropArea::DropAction BlockDropArea::findActionForEvent(QDropEvent *event) const
{
if (action == PrependBlock && event->pos().y() >= height()/2)
return true;
if (action == AppendBlock && event->pos().y() < height()/2)
return true;
for (const auto &member: QMetaEnum::fromType<DropAction>()) {
const auto action = member.value<DropAction>();

if ((m_floatingDropActions & action) == action
&& answerRect(action).contains(event->pos()))
return action;
}

return {};
}

void BlockDropArea::resetDropActionState()
{
m_typeInfo.clear();
m_floatingDropActions = {};

return false;
if (std::exchange(m_pendingDropAction, {}))
emit pendingDropActionChanged(m_pendingDropAction);
}

} // namespace Controls
Expand Down
13 changes: 7 additions & 6 deletions src/qtitchescontrols/qtitchesblockdroparea.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ class QTITCHES_CONTROLS_EXPORT BlockDropArea : public QQuickItem

void setAcceptedDropActions(DropActions acceptedDropActions);
DropActions acceptedDropActions() const;

DropActions floatingDropActions() const;
DropAction pendingDropAction() const;
QByteArray typeInfo() const;

Q_INVOKABLE virtual QVariantMap createMimeData(const QJsonObject &typeInfo) const;

Expand All @@ -49,21 +48,23 @@ class QTITCHES_CONTROLS_EXPORT BlockDropArea : public QQuickItem
void dragLeaveEvent(QDragLeaveEvent *event) override;
void dropEvent(QDropEvent *event) override;

private:
void setAcceptedDropActions(int acceptedDropActions) { setAcceptedDropActions(static_cast<DropActions>(acceptedDropActions)); }

private:
void cancelDrop();
bool eventViolatesAction(QDropEvent *event, DropAction action) const;
QRect answerRect(DropAction action) const;
DropAction findActionForEvent(QDropEvent *event) const;
void resetDropActionState();

DropActions m_acceptedDropActions;
DropActions m_floatingDropActions;
DropAction m_pendingDropAction = {};
bool m_pendingDropSuspended = false;
QByteArray m_typeInfo;
};

} // namespace Controls
} // namespace QtItches

Q_DECLARE_METATYPE(QtItches::Controls::BlockDropArea::DropActions)
Q_DECLARE_OPERATORS_FOR_FLAGS(QtItches::Controls::BlockDropArea::DropActions)

#endif // QTITCHESBLOCKDROPAREA_H
17 changes: 16 additions & 1 deletion src/qtitchescore/qtitchesblocklibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class BlockLibrary::Private
return type.module() + ' ' + QString::number(type.majorVersion()) + '.' + QString::number(type.majorVersion());
}

QJsonObject createTypeInfo()
QJsonObject createTypeInfo() const
{
return {
{s_typeId, type.index()},
Expand Down Expand Up @@ -150,6 +150,21 @@ Block::TypeCategory BlockLibrary::typeCategory(const QJsonObject &typeInfo)
return static_cast<Block::TypeCategory>(typeInfo.value(s_typeCategory).toInt());
}

QJsonObject BlockLibrary::typeInfo(const QString &uri, int majorVersion, int minorVersion, const QString &name)
{
const QHashedString hashedUri{uri};

for (const auto &row: d->m_rows) {
if (row.type.module() == hashedUri
&& row.type.majorVersion() == majorVersion
&& row.type.minorVersion() == minorVersion
&& row.type.elementName() == name)
return row.createTypeInfo();
}

return {};
}

Block *BlockLibrary::Private::createBlock(QQmlEngine *engine, const QQmlType &type) const
{
if (type.metaObject() && type.metaObject()->inherits(&Block::staticMetaObject)) {
Expand Down
1 change: 1 addition & 0 deletions src/qtitchescore/qtitchesblocklibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class QTITCHES_CORE_EXPORT BlockLibrary : public QAbstractListModel, public QQml
void componentComplete() override;

static Block::TypeCategory typeCategory(const QJsonObject &typeInfo);
QJsonObject typeInfo(const QString &uri, int majorVersion, int minorVersion, const QString &name);

Q_INVOKABLE QtItches::Core::Block *createBlock(const QByteArray &typeInfo, QObject *parent) const;

Expand Down
6 changes: 6 additions & 0 deletions src/qtitchescore/qtitchesexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ namespace Core {

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Expression::Expression(QObject *parent)
: Block{parent}
{
setConnectors(Connectors{});
}

void Expression::setParameterType(Parameter::Type parameterType)
{
if (m_parameterType == parameterType)
Expand Down
2 changes: 1 addition & 1 deletion src/qtitchescore/qtitchesexpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class QTITCHES_CORE_EXPORT Expression : public Block
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged FINAL)

public:
using Block::Block;
explicit Expression(QObject *parent = {});

void setParameterType(Parameter::Type parameterType);
Parameter::Type parameterType() const { return m_parameterType; }
Expand Down
4 changes: 1 addition & 3 deletions tests/auto/auto.pro
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
TEMPLATE = subdirs

SUBDIRS = \
tst_expressions.pro
SUBDIRS = $$files(tst_*.pro)
Loading