From ab037d45cc0785bcdada44ba55bb33f08a65ee1c Mon Sep 17 00:00:00 2001 From: Damir Porobic Date: Tue, 14 Apr 2020 22:32:00 +0200 Subject: [PATCH] Add tabs for images #48 --- CHANGELOG.md | 3 +- CMakeLists.txt | 2 +- README.md | 2 +- include/kImageAnnotator/KImageAnnotator.h | 9 +- src/CMakeLists.txt | 2 + src/gui/CoreView.cpp | 37 +++++-- src/gui/CoreView.h | 7 ++ src/gui/KImageAnnotator.cpp | 33 +++++++ src/gui/annotator/AnnotationTabContent.cpp | 46 +++++++++ src/gui/annotator/AnnotationTabContent.h | 49 ++++++++++ src/gui/annotator/AnnotationTabWidget.cpp | 107 +++++++++++++++++++++ src/gui/annotator/AnnotationTabWidget.h | 65 +++++++++++++ src/gui/annotator/AnnotationWidget.cpp | 71 ++++++++++---- src/gui/annotator/AnnotationWidget.h | 15 +-- src/gui/cropper/CropSelectionHandler.cpp | 11 ++- src/gui/cropper/CropSelectionHandler.h | 3 +- src/gui/cropper/CropView.cpp | 8 +- src/gui/cropper/CropView.h | 3 +- src/gui/cropper/CropWidget.cpp | 17 +++- src/gui/cropper/CropWidget.h | 6 +- src/gui/scaler/ScaleWidget.cpp | 13 ++- src/gui/scaler/ScaleWidget.h | 6 +- 22 files changed, 459 insertions(+), 56 deletions(-) create mode 100644 src/gui/annotator/AnnotationTabContent.cpp create mode 100644 src/gui/annotator/AnnotationTabContent.h create mode 100644 src/gui/annotator/AnnotationTabWidget.cpp create mode 100644 src/gui/annotator/AnnotationTabWidget.h diff --git a/CHANGELOG.md b/CHANGELOG.md index e52348df..7ab4b028 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Change log -## Release 0.2.2 +## Release 0.3.0 +* New: Tabs for images. ([#48](https://github.com/ksnip/kImageAnnotator/issues/48)) ## Release 0.2.1 * Fixed: Edit border around text box doesn't disappear when done with editing. ([#71](https://github.com/ksnip/kImageAnnotator/issues/71)) diff --git a/CMakeLists.txt b/CMakeLists.txt index b121dee7..98df51c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(kImageAnnotator LANGUAGES CXX VERSION 0.2.2) +project(kImageAnnotator LANGUAGES CXX VERSION 0.3.0) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/README.md b/README.md index ff59735a..412c4f22 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # kImageAnnotator [![Build Status](https://travis-ci.org/ksnip/kImageAnnotator.svg?branch=master)](https://travis-ci.org/ksnip/kImageAnnotator) Tool for annotating images -Version 0.2.2 - Work in Progress +Version 0.3.0 - Work in Progress ![kImageAnnotator](https://imgur.com/HguleRO.png "kImageAnnotator") diff --git a/include/kImageAnnotator/KImageAnnotator.h b/include/kImageAnnotator/KImageAnnotator.h index 7b78357c..c771a9cd 100644 --- a/include/kImageAnnotator/KImageAnnotator.h +++ b/include/kImageAnnotator/KImageAnnotator.h @@ -36,7 +36,7 @@ Q_OBJECT public: explicit KImageAnnotator(); - ~KImageAnnotator(); + ~KImageAnnotator() override; QImage image() const; QAction *undoAction(); QAction *redoAction(); @@ -47,6 +47,8 @@ Q_OBJECT public slots: void loadImage(const QPixmap &pixmap); + int addImage(const QPixmap &pixmap, const QString &title, const QString &toolTip); + void updateTabInfo(int index, const QString &title, const QString &toolTip); void insertImageItem(const QPointF &position, const QPixmap &pixmap); void setTextFont(const QFont &font); void setNumberFont(const QFont &font); @@ -54,9 +56,14 @@ public slots: void setSmoothPathEnabled(bool enabled); void setSaveToolSelection(bool enabled); void setSmoothFactor(int factor); + void setTabBarAutoHide(bool enabled); + void removeTab(int index); signals: void imageChanged() const; + void currentTabChanged(int index) const; + void tabCloseRequested(int index) const; + void tabMoved(int fromIndex, int toIndex); private: QScopedPointer const d_ptr; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c2c0a0b1..db59c44f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,8 @@ set(KIMAGEANNOTATOR_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/gui/annotator/AnnotationView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gui/annotator/WidgetConfigurator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gui/annotator/AnnotationSettings.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/gui/annotator/AnnotationTabContent.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/gui/annotator/AnnotationTabWidget.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gui/cropper/CropWidget.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gui/cropper/CropView.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gui/cropper/CropSelectionHandler.cpp diff --git a/src/gui/CoreView.cpp b/src/gui/CoreView.cpp index 6afcfa77..59178320 100644 --- a/src/gui/CoreView.cpp +++ b/src/gui/CoreView.cpp @@ -21,17 +21,20 @@ namespace kImageAnnotator { -CoreView::CoreView(Config *config) +CoreView::CoreView(Config *config) : + mConfig(config), + mAnnotationWidget(new AnnotationWidget(mConfig)), + mCropWidget(new CropWidget), + mScaleWidget(new ScaleWidget) { - mConfig = config; - mAnnotationWidget = new AnnotationWidget(mConfig); - mCropWidget = new CropWidget(mAnnotationWidget->annotationArea()); - mScaleWidget = new ScaleWidget(mAnnotationWidget->annotationArea()); addWidget(mAnnotationWidget); addWidget(mCropWidget); addWidget(mScaleWidget); connect(mAnnotationWidget, &AnnotationWidget::imageChanged, this, &CoreView::imageChanged); + connect(mAnnotationWidget, &AnnotationWidget::currentTabChanged, this, &CoreView::currentTabChanged); + connect(mAnnotationWidget, &AnnotationWidget::tabCloseRequested, this, &CoreView::tabCloseRequested); + connect(mAnnotationWidget, &AnnotationWidget::tabMoved, this, &CoreView::tabMoved); connect(mCropWidget, &CropWidget::closing, this, &CoreView::showAnnotator); connect(mScaleWidget, &ScaleWidget::closing, this, &CoreView::showAnnotator); } @@ -53,11 +56,26 @@ void CoreView::loadImage(const QPixmap &pixmap) mAnnotationWidget->loadImage(pixmap); } +int CoreView::addImage(const QPixmap &pixmap, const QString &title, const QString &toolTip) +{ + return mAnnotationWidget->addImage(pixmap, title, toolTip); +} + +void CoreView::updateTabInfo(int index, const QString &title, const QString &toolTip) +{ + mAnnotationWidget->updateTabInfo(index, title, toolTip); +} + void CoreView::insertImageItem(const QPointF &position, const QPixmap &pixmap) { mAnnotationWidget->insertImageItem(position, pixmap); } +void CoreView::removeTab(int index) +{ + mAnnotationWidget->removeTab(index); +} + void CoreView::showAnnotator() { mAnnotationWidget->setUndoEnabled(true); @@ -69,7 +87,7 @@ void CoreView::showCropper() mAnnotationWidget->setUndoEnabled(false); mAnnotationWidget->clearSelection(); setCurrentWidget(mCropWidget); - mCropWidget->activate(); + mCropWidget->activate(mAnnotationWidget->annotationArea()); } void CoreView::showScaler() @@ -77,7 +95,12 @@ void CoreView::showScaler() mAnnotationWidget->setUndoEnabled(false); mAnnotationWidget->clearSelection(); setCurrentWidget(mScaleWidget); - mScaleWidget->activate(); + mScaleWidget->activate(mAnnotationWidget->annotationArea()); +} + +void CoreView::setTabBarAutoHide(bool enabled) +{ + mAnnotationWidget->setTabBarAutoHide(enabled); } QAction *CoreView::undoAction() diff --git a/src/gui/CoreView.h b/src/gui/CoreView.h index 611aba05..87f97c84 100644 --- a/src/gui/CoreView.h +++ b/src/gui/CoreView.h @@ -43,13 +43,20 @@ Q_OBJECT signals: void imageChanged() const; + void currentTabChanged(int index) const; + void tabCloseRequested(int index) const; + void tabMoved(int fromIndex, int toIndex); public slots: void loadImage(const QPixmap &pixmap); + int addImage(const QPixmap &pixmap, const QString &title, const QString &toolTip); + void updateTabInfo(int index, const QString &title, const QString &toolTip); void insertImageItem(const QPointF &position, const QPixmap &pixmap); + void removeTab(int index); void showAnnotator(); void showCropper(); void showScaler(); + void setTabBarAutoHide(bool enabled); private: Config *mConfig; diff --git a/src/gui/KImageAnnotator.cpp b/src/gui/KImageAnnotator.cpp index 159c8370..5ee3f210 100644 --- a/src/gui/KImageAnnotator.cpp +++ b/src/gui/KImageAnnotator.cpp @@ -79,6 +79,24 @@ void KImageAnnotator::loadImage(const QPixmap &pixmap) } } +int KImageAnnotator::addImage(const QPixmap &pixmap, const QString &title, const QString &toolTip) +{ + Q_D(KImageAnnotator); + auto newTabIndex = d->mCoreView.addImage(pixmap, title, toolTip); + + if (isHidden()) { + show(); + } + + return newTabIndex; +} + +void KImageAnnotator::updateTabInfo(int index, const QString &title, const QString &toolTip) +{ + Q_D(KImageAnnotator); + d->mCoreView.updateTabInfo(index, title, toolTip); +} + void KImageAnnotator::insertImageItem(const QPointF &position, const QPixmap &pixmap) { Q_D(KImageAnnotator); @@ -132,6 +150,18 @@ void KImageAnnotator::setSmoothFactor(int factor) d->mConfig.setSmoothFactor(factor); } +void KImageAnnotator::setTabBarAutoHide(bool enabled) +{ + Q_D(KImageAnnotator); + d->mCoreView.setTabBarAutoHide(enabled); +} + +void KImageAnnotator::removeTab(int index) +{ + Q_D(KImageAnnotator); + d->mCoreView.removeTab(index); +} + void KImageAnnotator::showAnnotator() { Q_D(KImageAnnotator); @@ -163,6 +193,9 @@ KImageAnnotatorPrivate::KImageAnnotatorPrivate(KImageAnnotator *kImageAnnotator) kImageAnnotator->hide(); kImageAnnotator->connect(&mCoreView, &CoreView::imageChanged, kImageAnnotator, &KImageAnnotator::imageChanged); + kImageAnnotator->connect(&mCoreView, &CoreView::currentTabChanged, kImageAnnotator, &KImageAnnotator::currentTabChanged); + kImageAnnotator->connect(&mCoreView, &CoreView::tabCloseRequested, kImageAnnotator, &KImageAnnotator::tabCloseRequested); + kImageAnnotator->connect(&mCoreView, &CoreView::tabMoved, kImageAnnotator, &KImageAnnotator::tabMoved); } } // namespace kImageAnnotator diff --git a/src/gui/annotator/AnnotationTabContent.cpp b/src/gui/annotator/AnnotationTabContent.cpp new file mode 100644 index 00000000..25641263 --- /dev/null +++ b/src/gui/annotator/AnnotationTabContent.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 Damir Porobic + * + * 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 2 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 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "AnnotationTabContent.h" + +namespace kImageAnnotator { + +AnnotationTabContent::AnnotationTabContent(const QPixmap &pixmap, Config *config, AbstractSettingsProvider *settingsProvider) : + mAnnotationArea(new AnnotationArea(config, settingsProvider)), + mAnnotationView(new AnnotationView(mAnnotationArea)), + mMainLayout(new QHBoxLayout(this)) +{ + mAnnotationArea->loadImage(pixmap); + mMainLayout->addWidget(mAnnotationView); + setLayout(mMainLayout); +} + +AnnotationTabContent::~AnnotationTabContent() +{ + delete mMainLayout; + delete mAnnotationArea; + delete mAnnotationView; +} + +AnnotationArea* AnnotationTabContent::annotationArea() const +{ + return mAnnotationArea; +} + +} // namespace kImageAnnotator \ No newline at end of file diff --git a/src/gui/annotator/AnnotationTabContent.h b/src/gui/annotator/AnnotationTabContent.h new file mode 100644 index 00000000..332285da --- /dev/null +++ b/src/gui/annotator/AnnotationTabContent.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 Damir Porobic + * + * 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 2 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 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef ANNOTATIONTAB_H +#define ANNOTATIONTAB_H + +#include +#include + +#include "AnnotationView.h" +#include "AnnotationSettings.h" +#include "src/annotations/core/AnnotationArea.h" + +namespace kImageAnnotator { + +class AnnotationTabContent : public QWidget +{ + Q_OBJECT +public: + AnnotationTabContent(const QPixmap &pixmap, Config *config, AbstractSettingsProvider *settingsProvider); + ~AnnotationTabContent() override; + + AnnotationArea* annotationArea() const; + +private: + AnnotationArea *mAnnotationArea; + AnnotationView *mAnnotationView; + QHBoxLayout *mMainLayout; +}; + +} // namespace kImageAnnotator + +#endif //ANNOTATIONTAB_H diff --git a/src/gui/annotator/AnnotationTabWidget.cpp b/src/gui/annotator/AnnotationTabWidget.cpp new file mode 100644 index 00000000..3853d0a5 --- /dev/null +++ b/src/gui/annotator/AnnotationTabWidget.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2020 Damir Porobic + * + * 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 2 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 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "AnnotationTabWidget.h" + +namespace kImageAnnotator { + +AnnotationTabWidget::AnnotationTabWidget(Config *config, AbstractSettingsProvider *settingsProvider) : + mConfig(config), + mSettingsProvider(settingsProvider), + mRedoAction(new QAction(this)), + mUndoAction(new QAction(this)) +{ + setTabBarAutoHide(true); + setMovable(true); + setTabsClosable(false); + + connect(mUndoAction, &QAction::triggered, this, &AnnotationTabWidget::undoTriggered); + connect(mRedoAction, &QAction::triggered, this, &AnnotationTabWidget::redoTriggered); + connect(tabBar(), &QTabBar::tabMoved, this, &AnnotationTabWidget::tabMoved); +} + +int AnnotationTabWidget::addImage(const QPixmap &image, const QString &title, const QString &toolTip) +{ + auto content = new AnnotationTabContent(image, mConfig, mSettingsProvider); + connect(content->annotationArea(), &AnnotationArea::imageChanged, this, &AnnotationTabWidget::imageChanged); + + return QTabWidget::addTab(content, title); +} + +AnnotationArea* AnnotationTabWidget::currentAnnotationArea() const +{ + return currentWidget() != nullptr ? dynamic_cast(currentWidget())->annotationArea() : nullptr; +} + +QAction *AnnotationTabWidget::undoAction() const +{ + return mUndoAction; +} + +QAction *AnnotationTabWidget::redoAction() const +{ + return mRedoAction; +} + +void AnnotationTabWidget::updateTabInfo(int index, const QString &title, const QString &toolTip) +{ + setTabText(index, title); + setTabToolTip(index, toolTip); +} + +void AnnotationTabWidget::tabInserted(int index) +{ + updateCurrentWidget(index); + updateTabsClosable(); + QTabWidget::tabInserted(index); +} + +void AnnotationTabWidget::tabRemoved(int index) +{ + updateTabsClosable(); + QTabWidget::tabRemoved(index); +} + +void AnnotationTabWidget::undoTriggered() +{ + auto annotationArea = currentAnnotationArea(); + if(annotationArea != nullptr) { + currentAnnotationArea()->undoAction()->trigger(); + } +} + +void AnnotationTabWidget::redoTriggered() +{ + auto annotationArea = currentAnnotationArea(); + if(annotationArea != nullptr) { + currentAnnotationArea()->redoAction()->trigger(); + } +} + +void AnnotationTabWidget::updateTabsClosable() +{ + setTabsClosable(count() > 1); +} + +void AnnotationTabWidget::updateCurrentWidget(int index) +{ + setCurrentIndex(index); +} + +} // namespace kImageAnnotator \ No newline at end of file diff --git a/src/gui/annotator/AnnotationTabWidget.h b/src/gui/annotator/AnnotationTabWidget.h new file mode 100644 index 00000000..b356e03e --- /dev/null +++ b/src/gui/annotator/AnnotationTabWidget.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2020 Damir Porobic + * + * 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 2 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 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef ANNOTATIONTABWIDGET_H +#define ANNOTATIONTABWIDGET_H + +#include +#include + +#include "AnnotationTabContent.h" + +namespace kImageAnnotator { + +class AnnotationTabWidget : public QTabWidget +{ + Q_OBJECT +public: + AnnotationTabWidget(Config *config, AbstractSettingsProvider *settingsProvider); + ~AnnotationTabWidget() override = default; + int addImage(const QPixmap &image, const QString &title, const QString &toolTip); + AnnotationArea* currentAnnotationArea() const; + QAction* undoAction() const; + QAction* redoAction() const; + void updateTabInfo(int index, const QString &title, const QString &toolTip); + +signals: + void imageChanged() const; + void tabMoved(int fromIndex, int toIndex) const; + +protected: + void tabInserted(int index) override; + void tabRemoved(int index) override; + +private: + Config *mConfig; + AbstractSettingsProvider *mSettingsProvider; + QAction *mUndoAction; + QAction *mRedoAction; + +private slots: + void undoTriggered(); + void redoTriggered(); + void updateTabsClosable(); + void updateCurrentWidget(int index); +}; + +} // namespace kImageAnnotator + +#endif //ANNOTATIONTABWIDGET_H diff --git a/src/gui/annotator/AnnotationWidget.cpp b/src/gui/annotator/AnnotationWidget.cpp index 2d13bd59..45938363 100644 --- a/src/gui/annotator/AnnotationWidget.cpp +++ b/src/gui/annotator/AnnotationWidget.cpp @@ -21,25 +21,23 @@ namespace kImageAnnotator { -AnnotationWidget::AnnotationWidget(Config *config) +AnnotationWidget::AnnotationWidget(Config *config) : + mSettings(new AnnotationSettings(config)), + mAnnotationTabWidget(new AnnotationTabWidget(config, mSettings)) { - mConfig = config; - initGui(); } AnnotationWidget::~AnnotationWidget() { - delete mAnnotationView; delete mMainLayout; delete mSettings; - delete mAnnotationArea; } QSize AnnotationWidget::sizeHint() const { auto minSize = mSettings->sizeHint(); - auto sceneSize = mAnnotationArea->sceneRect().size(); + auto sceneSize = mAnnotationTabWidget->sizeHint(); auto width = minSize.width() + sceneSize.width(); auto height = (minSize.height() > sceneSize.height()) ? minSize.height() : sceneSize.height(); auto offset = QSize(100, 100); @@ -48,57 +46,87 @@ QSize AnnotationWidget::sizeHint() const void AnnotationWidget::initGui() { - mSettings = new AnnotationSettings(mConfig); - mAnnotationArea = new AnnotationArea(mConfig, mSettings); - mAnnotationView = new AnnotationView(mAnnotationArea); mMainLayout = new QHBoxLayout(); mMainLayout->addWidget(mSettings); - mMainLayout->addWidget(mAnnotationView); + mMainLayout->addWidget(mAnnotationTabWidget); setLayout(mMainLayout); setFocusPolicy(Qt::ClickFocus); - connect(mAnnotationArea, &AnnotationArea::imageChanged, this, &AnnotationWidget::imageChanged); + connect(mAnnotationTabWidget, &AnnotationTabWidget::imageChanged, this, &AnnotationWidget::imageChanged); + connect(mAnnotationTabWidget, &AnnotationTabWidget::currentChanged, this, &AnnotationWidget::currentTabChanged); + connect(mAnnotationTabWidget, &AnnotationTabWidget::tabCloseRequested, this, &AnnotationWidget::tabCloseRequested); + connect(mAnnotationTabWidget, &AnnotationTabWidget::tabMoved, this, &AnnotationWidget::tabMoved); } QImage AnnotationWidget::image() const { - return mAnnotationArea->image(); + auto currentAnnotationArea = annotationArea(); + return currentAnnotationArea != nullptr ? currentAnnotationArea->image() : QImage(); } void AnnotationWidget::loadImage(const QPixmap &pixmap) { - mAnnotationArea->loadImage(pixmap); + auto currentAnnotationArea = annotationArea(); + if(currentAnnotationArea == nullptr) { + addImage(pixmap, QString(), QString()); + } else { + currentAnnotationArea->loadImage(pixmap); + } +} + +int AnnotationWidget::addImage(const QPixmap &pixmap, const QString &title, const QString &toolTip) +{ + return mAnnotationTabWidget->addImage(pixmap, title, toolTip); +} + +void AnnotationWidget::updateTabInfo(int index, const QString &title, const QString &toolTip) +{ + mAnnotationTabWidget->updateTabInfo(index, title, toolTip); } void AnnotationWidget::insertImageItem(const QPointF &position, const QPixmap &pixmap) { - mAnnotationArea->insertImageItem(position, pixmap); + auto currentAnnotationArea = annotationArea(); + if(currentAnnotationArea != nullptr) { + currentAnnotationArea->insertImageItem(position, pixmap); + } +} + +void AnnotationWidget::removeTab(int index) +{ + mAnnotationTabWidget->removeTab(index); } void AnnotationWidget::setUndoEnabled(bool enabled) { - mAnnotationArea->setUndoEnabled(enabled); + auto currentAnnotationArea = annotationArea(); + if(currentAnnotationArea != nullptr) { + annotationArea()->setUndoEnabled(enabled); + } } QAction *AnnotationWidget::undoAction() const { - return mAnnotationArea->undoAction(); + return mAnnotationTabWidget->undoAction(); } QAction *AnnotationWidget::redoAction() const { - return mAnnotationArea->redoAction(); + return mAnnotationTabWidget->redoAction(); } void AnnotationWidget::clearSelection() { - mAnnotationArea->clearSelection(); + auto currentAnnotationArea = annotationArea(); + if(currentAnnotationArea != nullptr) { + annotationArea()->clearSelection(); + } } AnnotationArea *AnnotationWidget::annotationArea() const { - return mAnnotationArea; + return mAnnotationTabWidget->currentAnnotationArea(); } void AnnotationWidget::reloadConfig() @@ -106,4 +134,9 @@ void AnnotationWidget::reloadConfig() mSettings->reloadConfig(); } +void AnnotationWidget::setTabBarAutoHide(bool enabled) +{ + mAnnotationTabWidget->setTabBarAutoHide(enabled); +} + } // namespace kImageAnnotator diff --git a/src/gui/annotator/AnnotationWidget.h b/src/gui/annotator/AnnotationWidget.h index 45684f72..86436342 100644 --- a/src/gui/annotator/AnnotationWidget.h +++ b/src/gui/annotator/AnnotationWidget.h @@ -20,11 +20,9 @@ #ifndef KIMAGEANNOTATOR_ANNOTATIONWIDGET_H #define KIMAGEANNOTATOR_ANNOTATIONWIDGET_H -#include #include -#include "AnnotationView.h" -#include "AnnotationSettings.h" +#include "AnnotationTabWidget.h" #include "src/annotations/core/AnnotationArea.h" namespace kImageAnnotator { @@ -38,23 +36,28 @@ Q_OBJECT QSize sizeHint() const override; QImage image () const; void loadImage(const QPixmap &pixmap); + int addImage(const QPixmap &pixmap, const QString &title, const QString &toolTip); + void updateTabInfo(int index, const QString &title, const QString &toolTip); void insertImageItem(const QPointF &position, const QPixmap &pixmap); + void removeTab(int index); void setUndoEnabled(bool enabled); QAction* undoAction() const; QAction* redoAction() const; void clearSelection(); AnnotationArea* annotationArea() const; void reloadConfig(); + void setTabBarAutoHide(bool enabled); signals: void imageChanged() const; + void currentTabChanged(int index) const; + void tabCloseRequested(int index) const; + void tabMoved(int fromIndex, int toIndex); private: - AnnotationArea *mAnnotationArea; - AnnotationView *mAnnotationView; AnnotationSettings *mSettings; + AnnotationTabWidget *mAnnotationTabWidget; QHBoxLayout *mMainLayout; - Config *mConfig; void initGui(); }; diff --git a/src/gui/cropper/CropSelectionHandler.cpp b/src/gui/cropper/CropSelectionHandler.cpp index 647a14dc..e615aa74 100644 --- a/src/gui/cropper/CropSelectionHandler.cpp +++ b/src/gui/cropper/CropSelectionHandler.cpp @@ -21,8 +21,13 @@ namespace kImageAnnotator { -CropSelectionHandler::CropSelectionHandler(AnnotationArea *annotationArea) : mAnnotationArea(annotationArea) +CropSelectionHandler::CropSelectionHandler() : mAnnotationArea(nullptr) { +} + +void CropSelectionHandler::init(AnnotationArea *annotationArea) +{ + mAnnotationArea = annotationArea; resetSelection(); } @@ -76,6 +81,8 @@ void CropSelectionHandler::release() void CropSelectionHandler::resetSelection() { + Q_ASSERT(mAnnotationArea != nullptr); + mMaxSelection = mAnnotationArea->sceneRect(); setSelection(mAnnotationArea->sceneRect()); } @@ -111,6 +118,8 @@ void CropSelectionHandler::setPositionY(int y) void CropSelectionHandler::update() { + Q_ASSERT(mAnnotationArea != nullptr); + mCropHandles.updateHandles(mSelection); mAnnotationArea->update(); notifyAboutChange(); diff --git a/src/gui/cropper/CropSelectionHandler.h b/src/gui/cropper/CropSelectionHandler.h index 343848d3..5c0e4699 100644 --- a/src/gui/cropper/CropSelectionHandler.h +++ b/src/gui/cropper/CropSelectionHandler.h @@ -34,8 +34,9 @@ class CropSelectionHandler : public QObject { Q_OBJECT public: - explicit CropSelectionHandler(AnnotationArea *annotationArea); + explicit CropSelectionHandler(); ~CropSelectionHandler() override = default; + void init(AnnotationArea *annotationArea); QRectF selection() const; QVector selectionHandles() const; void grab(const QPointF &position); diff --git a/src/gui/cropper/CropView.cpp b/src/gui/cropper/CropView.cpp index def52f16..94d681aa 100644 --- a/src/gui/cropper/CropView.cpp +++ b/src/gui/cropper/CropView.cpp @@ -21,10 +21,16 @@ namespace kImageAnnotator { -CropView::CropView(kImageAnnotator::AnnotationArea *annotationArea, CropSelectionHandler *cropSelectionHandler, KeyHelper *keyHelper) : +CropView::CropView(CropSelectionHandler *cropSelectionHandler, KeyHelper *keyHelper) : mKeyHelper(keyHelper), mCropSelectionHandler(cropSelectionHandler) { +} + +void CropView::init(AnnotationArea *annotationArea) +{ + Q_ASSERT(annotationArea != nullptr); + setScene(annotationArea); } diff --git a/src/gui/cropper/CropView.h b/src/gui/cropper/CropView.h index 77ef65bf..d8581c88 100644 --- a/src/gui/cropper/CropView.h +++ b/src/gui/cropper/CropView.h @@ -32,8 +32,9 @@ class CropView : public QGraphicsView { Q_OBJECT public: - explicit CropView(AnnotationArea *annotationArea, CropSelectionHandler *cropSelectionHandler, KeyHelper *keyHelper); + explicit CropView(CropSelectionHandler *cropSelectionHandler, KeyHelper *keyHelper); ~CropView() override = default; + void init(AnnotationArea *annotationArea); protected: void keyPressEvent(QKeyEvent *event) override; diff --git a/src/gui/cropper/CropWidget.cpp b/src/gui/cropper/CropWidget.cpp index f0c83f22..8c500389 100644 --- a/src/gui/cropper/CropWidget.cpp +++ b/src/gui/cropper/CropWidget.cpp @@ -21,11 +21,11 @@ namespace kImageAnnotator { -CropWidget::CropWidget(kImageAnnotator::AnnotationArea *annotationArea) : - mAnnotationArea(annotationArea), +CropWidget::CropWidget() : + mAnnotationArea(nullptr), mKeyHelper(new KeyHelper()), - mCropSelectionHandler(new CropSelectionHandler(annotationArea)), - mCropView(new CropView(annotationArea, mCropSelectionHandler, mKeyHelper)) + mCropSelectionHandler(new CropSelectionHandler()), + mCropView(new CropView(mCropSelectionHandler, mKeyHelper)) { initCropSelectionHandler(); initKeyHelper(); @@ -58,8 +58,13 @@ CropWidget::~CropWidget() delete mHeightLineEdit; } -void CropWidget::activate() +void CropWidget::activate(AnnotationArea *annotationArea) { + Q_ASSERT(annotationArea != nullptr); + + mAnnotationArea = annotationArea; + mCropSelectionHandler->init(annotationArea); + mCropView->init(annotationArea); reset(); setFocus(); } @@ -131,6 +136,8 @@ void CropWidget::keyReleaseEvent(QKeyEvent *event) void CropWidget::crop() { + Q_ASSERT(mAnnotationArea != nullptr); + mAnnotationArea->crop(mCropSelectionHandler->selection()); emit closing(); } diff --git a/src/gui/cropper/CropWidget.h b/src/gui/cropper/CropWidget.h index f3842ef8..1b58458b 100644 --- a/src/gui/cropper/CropWidget.h +++ b/src/gui/cropper/CropWidget.h @@ -39,9 +39,9 @@ class CropWidget : public QWidget { Q_OBJECT public: - explicit CropWidget(AnnotationArea *annotationArea); - ~CropWidget(); - void activate(); + explicit CropWidget(); + ~CropWidget() override; + void activate(AnnotationArea *annotationArea); signals: void closing() const; diff --git a/src/gui/scaler/ScaleWidget.cpp b/src/gui/scaler/ScaleWidget.cpp index 24b95eb0..7caa9243 100644 --- a/src/gui/scaler/ScaleWidget.cpp +++ b/src/gui/scaler/ScaleWidget.cpp @@ -21,11 +21,10 @@ namespace kImageAnnotator { -kImageAnnotator::ScaleWidget::ScaleWidget(kImageAnnotator::AnnotationArea *annotationArea) +kImageAnnotator::ScaleWidget::ScaleWidget(): + mAnnotationArea(nullptr), + mView(new QGraphicsView) { - mAnnotationArea = annotationArea; - - mView = new QGraphicsView(annotationArea); initGui(); } @@ -35,8 +34,12 @@ ScaleWidget::~ScaleWidget() delete mView; } -void ScaleWidget::activate() +void ScaleWidget::activate(AnnotationArea *annotationArea) { + Q_ASSERT(annotationArea != nullptr); + + mAnnotationArea = annotationArea; + mView->setScene(annotationArea); showDialog(); } diff --git a/src/gui/scaler/ScaleWidget.h b/src/gui/scaler/ScaleWidget.h index 942886e6..706ea779 100644 --- a/src/gui/scaler/ScaleWidget.h +++ b/src/gui/scaler/ScaleWidget.h @@ -33,9 +33,9 @@ class ScaleWidget : public QWidget { Q_OBJECT public: - explicit ScaleWidget(AnnotationArea *annotationArea); - ~ScaleWidget(); - void activate(); + explicit ScaleWidget(); + ~ScaleWidget() override; + void activate(AnnotationArea *annotationArea); signals: void closing() const;