This commit is contained in:
jaseg 2020-12-17 15:43:37 +01:00
parent c6713d0876
commit 6a484c615a
17 changed files with 175 additions and 7 deletions

9
Icons.qrc Normal file
View file

@ -0,0 +1,9 @@
<RCC>
<qresource prefix="/icons">
<file>tag.png</file>
<file>tags.png</file>
<file>selection_tool.png</file>
<file>move_tool.png</file>
<file>edit_tool.png</file>
</qresource>
</RCC>

BIN
edit_tool.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

BIN
move_tool.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

View file

@ -3,6 +3,7 @@
#include "ui_TagListDock.h" #include "ui_TagListDock.h"
#include <QMessageBox> #include <QMessageBox>
#include <QToolbar>
Numberator::Numberator(QWidget *parent) Numberator::Numberator(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
@ -88,6 +89,30 @@ Numberator::Numberator(QWidget *parent)
} }
}); });
QToolBar *tools_tb = new QToolBar("Tools", this);
struct tool_def {
ToolType type;
QString filename;
QString name;
};
std::initializer_list<struct tool_def> tool_defs = {
{SELECTION_TOOL, ":/icons/selection_tool.png", "Select"},
{TAG_TOOL, ":/icons/tag.png", "Add Tag"},
{MOVE_TOOL, ":/icons/move_tool.png", "Move Tag"},
{EDIT_TOOL, ":/icons/edit_tool.png", "Edit Tag"},
};
QActionGroup toolsActionGroup(this);
for (auto tool : tool_defs) {
auto action = tools_tb->addAction(QIcon(tool.filename), tool.name, [=](){
setTool(tool.type);
});
action->setCheckable(true);
toolsActionGroup.addAction(action);
}
toolsActionGroup.actions().first()->setChecked(true);
this->addToolBar(Qt::TopToolBarArea, tools_tb);
ui->menuView->addAction(dock->toggleViewAction()); ui->menuView->addAction(dock->toggleViewAction());
connect(ui->actionReload_Image, &QAction::triggered, &proj, &SQLiteSaveFile::reloadImageFromDisk); connect(ui->actionReload_Image, &QAction::triggered, &proj, &SQLiteSaveFile::reloadImageFromDisk);
@ -151,6 +176,11 @@ Numberator::~Numberator()
delete ui; delete ui;
} }
void Numberator::setTool(Numberator::ToolType tool)
{
ui->graphicsView->scene()->setTool(tool);
}
bool Numberator::showConfirmDiscardDialog() bool Numberator::showConfirmDiscardDialog()
{ {
if (!proj.isMemory() || !proj.isDirty()) if (!proj.isMemory() || !proj.isDirty())

View file

@ -18,6 +18,14 @@ namespace Ui {
} }
QT_END_NAMESPACE QT_END_NAMESPACE
enum ToolType {
SELECTION_TOOL,
TAG_TOOL,
MOVE_TOOL,
EDIT_TOOL,
NUM_TOOLS
};
class Numberator : public QMainWindow class Numberator : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
@ -26,6 +34,8 @@ public:
Numberator(QWidget *parent = nullptr); Numberator(QWidget *parent = nullptr);
~Numberator(); ~Numberator();
void setTool(ToolType tool);
bool showConfirmDiscardDialog(); bool showConfirmDiscardDialog();
public slots: public slots:
@ -45,5 +55,7 @@ private:
TagListModel tagListModel; TagListModel tagListModel;
TagPropTableModel tagPropTableModel, dialogTagPropTableModel; TagPropTableModel tagPropTableModel, dialogTagPropTableModel;
Tag m_tagBeingEdited; Tag m_tagBeingEdited;
ToolType m_activeTool = SELECTION_TOOL;
}; };
#endif // NUMBERATOR_H #endif // NUMBERATOR_H

View file

@ -47,3 +47,6 @@ FORMS += \
qnx: target.path = /tmp/$${TARGET}/bin qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target !isEmpty(target.path): INSTALLS += target
RESOURCES += \
Icons.qrc

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

BIN
selection_tool.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

View file

@ -19,7 +19,7 @@ public:
Tag() : valid(false) {} Tag() : valid(false) {}
Tag(long long int id, QString name, qreal anchor_x, qreal anchor_y, QByteArray metadata); Tag(long long int id, QString name, qreal anchor_x, qreal anchor_y, QByteArray metadata);
Tag(long long int id, const Tag &other); Tag(long long int id, const Tag &other);
Tag(QString name, const QPointF &anchor, const QVariantMap metadata=QVariantMap()); Tag(QString name, const QPointF &anchor=QPointF(), const QVariantMap metadata=QVariantMap());
bool operator==(const Tag &t2) const { return id == t2.id; } bool operator==(const Tag &t2) const { return id == t2.id; }
@ -29,6 +29,7 @@ public:
long long int id; long long int id;
QString name; QString name;
QPointF anchor; QPointF anchor;
QPointF labelPos;
QVariantMap metadata; QVariantMap metadata;
private: private:

BIN
tag.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

View file

@ -11,7 +11,6 @@ TagItem::TagItem(const Tag &tag)
, m_margins(2, 2, 2, 2) , m_margins(2, 2, 2, 2)
{ {
setFlags(QGraphicsItem::ItemIsSelectable setFlags(QGraphicsItem::ItemIsSelectable
| QGraphicsItem::ItemIsMovable
| QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusable
| QGraphicsItem::ItemIgnoresTransformations | QGraphicsItem::ItemIgnoresTransformations
| QGraphicsItem::ItemSendsGeometryChanges); | QGraphicsItem::ItemSendsGeometryChanges);
@ -97,6 +96,9 @@ QVariant TagItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVa
* *
*/ */
/* FIXME */ /* FIXME */
} else if (change == ItemSelectedChange) {
if (!value.toBool())
setFlag(QGraphicsItem::ItemIsMovable, false);
} }
return QGraphicsItem::itemChange(change, value); return QGraphicsItem::itemChange(change, value);
} }
@ -123,5 +125,10 @@ void TagItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{ {
Q_UNUSED(event); Q_UNUSED(event);
dragAboveThreshold = false; dragAboveThreshold = false;
if (isSelected())
setFlag(QGraphicsItem::ItemIsMovable, true);
else
setFlag(QGraphicsItem::ItemIsMovable, false);
QGraphicsItem::mouseReleaseEvent(event); QGraphicsItem::mouseReleaseEvent(event);
} }

View file

@ -24,9 +24,25 @@ bool collateTagNames(QString a, QString b) {
if (res_a.captured(1).isEmpty() && !res_b.captured(1).isEmpty()) if (res_a.captured(1).isEmpty() && !res_b.captured(1).isEmpty())
return true; return true;
if (res_a.captured().toInt() < res_b.captured().toInt()) if (res_a.captured(1).toInt() < res_b.captured(1).toInt())
return true; return true;
/* FIXME TODO */
if (res_a.captured(1) != res_b.captured(1))
return false;
if (res_a.captured(2) < res_b.captured(2))
return true;
if (res_a.captured(2) != res_b.captured(2))
return false;
if (res_a.captured(3).isEmpty() && !res_b.captured(3).isEmpty())
return true;
if (res_a.captured(3).toInt() < res_b.captured(3).toInt())
return true;
return false;
} }
void TagListModel::reloadTags() void TagListModel::reloadTags()

BIN
tags.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

View file

@ -90,6 +90,29 @@ void TagScene::selectTag(const Tag &tag)
it->setSelected(true); it->setSelected(true);
} }
void TagScene::setTool(ToolType tool)
{
abortTool();
m_tool = tool;
if (tool == ToolType::TAG_TOOL) {
m_tagToolState = TAG_TOOL_ANCHOR;
} else if (tool == ToolType::SELECTION_TOOL) {
}
}
void TagScene::abortTool()
{
if (m_tool == ToolType::TAG_TOOL) {
removeItem(m_previewTag);
} else if (m_tool == ToolType::SELECTION_TOOL) {
}
}
void TagScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) void TagScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{ {
QGraphicsItem *it = itemAt(event->scenePos(), QTransform()); QGraphicsItem *it = itemAt(event->scenePos(), QTransform());
@ -111,3 +134,29 @@ void TagScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
tagDoubleClicked(tagitem->tag()); tagDoubleClicked(tagitem->tag());
} }
void TagScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (m_tool == ToolType::TAG_TOOL) {
if (m_tagToolState == TAG_TOOL_LABEL) {
Tag t = m_previewTag->tag();
t.labelPos = event->scenePos();
m_previewTag->tagUpdated(t);
}
}
}
void TagScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (m_tool == ToolType::TAG_TOOL) {
if (m_tagToolState == TAG_TOOL_ANCHOR) {
m_previewTag->tagUpdated(Tag(m_proj->getNextAutoTagName(), event->scenePos()));
m_tagToolState = TAG_TOOL_LABEL;
} else { /* TAG_TOOL_LABEL */
removeItem(m_previewTag);
m_proj->createTag(m_previewTag->tag());
m_tagToolState = TAG_TOOL_ANCHOR;
}
}
}

View file

@ -3,6 +3,7 @@
#include "sqlitebackend.h" #include "sqlitebackend.h"
#include "tagitem.h" #include "tagitem.h"
#include "numberator.h"
#include <QGraphicsPixmapItem> #include <QGraphicsPixmapItem>
#include <QGraphicsScene> #include <QGraphicsScene>
@ -14,8 +15,8 @@ class TagScene : public QGraphicsScene
Q_OBJECT Q_OBJECT
public: public:
TagScene() {} TagScene() : m_previewTag(new TagItem()) {}
~TagScene() { this->blockSignals(true); } ~TagScene() { this->blockSignals(true); delete m_previewTag; }
const QGraphicsPixmapItem *backgroundPixmapItem() const { return pix_it; } const QGraphicsPixmapItem *backgroundPixmapItem() const { return pix_it; }
public slots: public slots:
@ -23,6 +24,9 @@ public slots:
void reloadScene(); void reloadScene();
void selectTag(const Tag &tag); void selectTag(const Tag &tag);
void setTool(ToolType tool);
void abortTool();
void setProject(SQLiteSaveFile *proj); void setProject(SQLiteSaveFile *proj);
signals: signals:
@ -31,6 +35,8 @@ signals:
protected: protected:
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override; void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
private slots: private slots:
void tagChanged(TagChange change, const Tag &tag); void tagChanged(TagChange change, const Tag &tag);
@ -43,6 +49,12 @@ private:
QGraphicsPixmapItem *pix_it = nullptr; QGraphicsPixmapItem *pix_it = nullptr;
QPixmap pix; QPixmap pix;
QMap<long long int, TagItem*> tags; QMap<long long int, TagItem*> tags;
ToolType m_tool;
enum TagToolState {
TAG_TOOL_ANCHOR,
TAG_TOOL_LABEL
} m_tagToolState = TAG_TOOL_ANCHOR;
TagItem *m_previewTag;
}; };
#endif // TAGSCENE_H #endif // TAGSCENE_H

View file

@ -3,12 +3,13 @@
#include <QWheelEvent> #include <QWheelEvent>
#include <QScrollBar> #include <QScrollBar>
#include <cmath> #include <cmath>
#include <QApplication>
TagView::TagView(QWidget *parent) TagView::TagView(QWidget *parent)
: QGraphicsView(parent) : QGraphicsView(parent)
, saveCenterTimer(this) , saveCenterTimer(this)
{ {
setDragMode(QGraphicsView::ScrollHandDrag); setDragMode(QGraphicsView::RubberBandDrag);
setScene(&m_scene); setScene(&m_scene);
connect(&m_scene, &TagScene::tagDoubleClicked, this, &TagView::tagDoubleClicked); connect(&m_scene, &TagScene::tagDoubleClicked, this, &TagView::tagDoubleClicked);
connect(&m_scene, &TagScene::imageLoaded, this, &TagView::zoomToFit); connect(&m_scene, &TagScene::imageLoaded, this, &TagView::zoomToFit);
@ -86,6 +87,31 @@ void TagView::scrollContentsBy(int dx, int dy)
saveCenterTimer.start(); saveCenterTimer.start();
} }
void TagView::keyPressEvent(QKeyEvent *event)
{
if (event->modifiers() & Qt::ControlModifier)
setDragMode(QGraphicsView::ScrollHandDrag);
else
setDragMode(QGraphicsView::RubberBandDrag);
}
void TagView::keyReleaseEvent(QKeyEvent *event)
{
if (event->modifiers() & Qt::ControlModifier)
setDragMode(QGraphicsView::ScrollHandDrag);
else
setDragMode(QGraphicsView::RubberBandDrag);
}
void TagView::focusInEvent(QFocusEvent *event)
{
Q_UNUSED(event);
if (QApplication::keyboardModifiers() & Qt::ControlModifier)
setDragMode(QGraphicsView::ScrollHandDrag);
else
setDragMode(QGraphicsView::RubberBandDrag);
}
void TagView::saveCenter() void TagView::saveCenter()
{ {
QPointF p = mapToScene(viewport()->rect().center()); QPointF p = mapToScene(viewport()->rect().center());

View file

@ -33,6 +33,9 @@ signals:
protected: protected:
void wheelEvent(QWheelEvent *evt) override; void wheelEvent(QWheelEvent *evt) override;
void scrollContentsBy(int dx, int dy) override; void scrollContentsBy(int dx, int dy) override;
void keyPressEvent(QKeyEvent *event) override;
void keyReleaseEvent(QKeyEvent *event) override;
void focusInEvent(QFocusEvent *event) override;
private slots: private slots:
void saveCenter(); void saveCenter();