1 /*
2  * Copyright (C) 2018 Damir Porobic <damir.porobic@gmx.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #include "AnnotationMultiItemResizer.h"
21 
22 namespace kImageAnnotator {
23 
AnnotationMultiItemResizer(ZoomValueProvider * zoomValueProvider)24 AnnotationMultiItemResizer::AnnotationMultiItemResizer(ZoomValueProvider *zoomValueProvider)
25 {
26 	mZoomValueProvider = zoomValueProvider;
27     mCurrentResizer = nullptr;
28 }
29 
boundingRect() const30 QRectF AnnotationMultiItemResizer::boundingRect() const
31 {
32     QRectF rect;
33     for (auto resizer : childItems()) {
34         rect = rect.united(resizer->boundingRect());
35     }
36     return rect;
37 }
38 
attachTo(const QList<AbstractAnnotationItem * > & items)39 void AnnotationMultiItemResizer::attachTo(const QList<AbstractAnnotationItem *>& items)
40 {
41     detach();
42     for (auto item : items) {
43         auto resizer = getResizerForItem(item);
44         showResizer(resizer);
45     }
46 }
47 
detach()48 void AnnotationMultiItemResizer::detach()
49 {
50     for (auto resizer : childItems()) {
51         hideResizer(resizer);
52     }
53 
54     mCurrentResizer = nullptr;
55 }
56 
grabHandle(const QPointF & pos)57 void AnnotationMultiItemResizer::grabHandle(const QPointF &pos)
58 {
59     for (auto item : childItems()) {
60         auto resizer = castToResizer(item);
61         resizer->grabHandle(pos);
62         if (resizer->isResizing()) {
63             mCurrentResizer = resizer;
64             return;
65         }
66     }
67     mCurrentResizer = nullptr;
68 }
69 
moveHandle(const QPointF & pos,bool isCtrlPressed)70 void AnnotationMultiItemResizer::moveHandle(const QPointF &pos, bool isCtrlPressed)
71 {
72     if (mCurrentResizer == nullptr) {
73         return;
74     }
75 
76 	mCurrentResizer->moveHandle(pos, isCtrlPressed);
77 }
78 
releaseHandle()79 void AnnotationMultiItemResizer::releaseHandle()
80 {
81     if (mCurrentResizer == nullptr) {
82         return;
83     }
84 
85     mCurrentResizer->releaseHandle();
86 }
87 
isResizing() const88 bool AnnotationMultiItemResizer::isResizing() const
89 {
90     return mCurrentResizer != nullptr && mCurrentResizer->isResizing();
91 }
92 
refresh()93 void AnnotationMultiItemResizer::refresh()
94 {
95     for (auto item : childItems()) {
96         auto resizer = castToResizer(item);
97         resizer->refresh();
98     }
99 }
100 
update()101 void AnnotationMultiItemResizer::update()
102 {
103     for (auto item : childItems()) {
104         auto resizer = castToResizer(item);
105         if (!resizer->isItemVisible()) {
106             hideResizer(resizer);
107         }
108     }
109 }
110 
hasItemsAttached() const111 bool AnnotationMultiItemResizer::hasItemsAttached() const
112 {
113     return childItems().count() > 0;
114 }
115 
cursorForPos(const QPointF & pos)116 Qt::CursorShape AnnotationMultiItemResizer::cursorForPos(const QPointF &pos)
117 {
118     for (auto item : childItems()) {
119         auto resizer = castToResizer(item);
120         if (resizer->boundingRect().contains(pos)) {
121             return resizer->cursorForPos(pos);
122         }
123     }
124 
125     return CursorHelper::defaultCursor();
126 }
127 
cursorForCurrentHandle()128 Qt::CursorShape AnnotationMultiItemResizer::cursorForCurrentHandle()
129 {
130     if (mCurrentResizer == nullptr) {
131         return CursorHelper::defaultCursor();
132     }
133     return mCurrentResizer->cursorForCurrentHandle();
134 }
135 
hideCurrentResizer()136 void AnnotationMultiItemResizer::hideCurrentResizer()
137 {
138     if (mCurrentResizer == nullptr) {
139         return;
140     }
141 
142     mCurrentResizer->hide();
143 }
144 
showCurrentResizer()145 void AnnotationMultiItemResizer::showCurrentResizer()
146 {
147     if (mCurrentResizer == nullptr) {
148         return;
149     }
150 
151     mCurrentResizer->show();
152 }
153 
getResizerForItem(AbstractAnnotationItem * item)154 AnnotationItemResizer *AnnotationMultiItemResizer::getResizerForItem(AbstractAnnotationItem *item)
155 {
156     if (!mItemToResizer.contains(item)) {
157         mItemToResizer[item] = new AnnotationItemResizer(item, mZoomValueProvider);
158         connect(mItemToResizer[item], &AnnotationItemResizer::newCommand, this, &AnnotationMultiItemResizer::newCommand);
159     }
160 
161     return mItemToResizer[item];
162 }
163 
hideResizer(QGraphicsItem * resizer)164 void AnnotationMultiItemResizer::hideResizer(QGraphicsItem *resizer)
165 {
166     removeFromGroup(resizer);
167     resizer->hide();
168 }
169 
showResizer(AnnotationItemResizer * resizer)170 void AnnotationMultiItemResizer::showResizer(AnnotationItemResizer *resizer)
171 {
172     addToGroup(resizer);
173     resizer->refresh();
174     resizer->show();
175 }
176 
castToResizer(QGraphicsItem * item)177 AnnotationItemResizer *AnnotationMultiItemResizer::castToResizer(QGraphicsItem *item)
178 {
179     return dynamic_cast<AnnotationItemResizer *>(item);
180 }
181 
182 } // namespace kImageAnnotator
183