1 /***************************************************************************
2                           kmagselrect.cpp  -  description
3                              -------------------
4     begin                : Mon Feb 12 23:45:41 EST 2001
5     copyright            : (C) 2001-2003 by Sarang Lakare
6     email                : sarang#users.sf.net
7     copyright            : (C) 2003-2004 by Olaf Schmidt
8     email                : ojschmidt@kde.org
9  ***************************************************************************/
10 
11 /***************************************************************************
12  *                                                                         *
13  *   This program is free software; you can redistribute it and/or modify  *
14  *   it under the terms of the GNU General Public License as published by  *
15  *   the Free Software Foundation; either version 2 of the License, or     *
16  *   (at your option) any later version.                                   *
17  *                                                                         *
18  ***************************************************************************/
19 
20 #include "kmagselrect.h"
21 
22 // Qt
23 #include <QApplication>
24 #include <QBitmap>
25 #include <QDesktopWidget>
26 #include <QMouseEvent>
27 // KF5
28 #include <KLocalizedString>
29 
30 static const uchar line_bits[] = {0x2d, 0x96, 0x4b, 0xa5, 0xd2, 0x69, 0xb4, 0x5a};
31 
32 static QColor titleColor = QColor (0,0,128);
33 static QColor titleBtnColor = QColor (255,255,0);
34 static QColor textColor = QColor (255,255,255);
35 
36 static int frameSize = 10;
37 static int titleSize = 24;
38 
setTitleColors(const QColor & title,const QColor & text,const QColor & titleBtn)39 void setTitleColors (const QColor &title, const QColor &text, const QColor &titleBtn)
40 {
41   titleColor = title;
42   titleBtnColor = titleBtn;
43   textColor = text;
44 }
45 
setFrameSize(int size)46 void setFrameSize (int size)
47 {
48   frameSize = size;
49 }
50 
setTitleSize(int size)51 void setTitleSize (int size)
52 {
53   titleSize = size;
54 }
55 
getTitleColor()56 QColor getTitleColor ()
57 {
58   return titleColor;
59 }
60 
getTitleBtnColor()61 QColor getTitleBtnColor ()
62 {
63   return titleBtnColor;
64 }
65 
getTextColor()66 QColor getTextColor ()
67 {
68   return textColor;
69 }
70 
getFrameSize()71 int getFrameSize ()
72 {
73   return frameSize;
74 }
75 
getTitleSize()76 int getTitleSize ()
77 {
78   if (titleSize > frameSize)
79     return titleSize;
80   else
81     return frameSize;
82 }
83 
84 //--------------------------------------------------------------------------
85 //   Construction
86 //--------------------------------------------------------------------------
87 
KMagSelRect(QWidget * parent)88 KMagSelRect::KMagSelRect(QWidget *parent) :
89   QRect()
90 {
91   init(parent);
92 }
93 
KMagSelRect(const QPoint & topLeft,const QPoint & bottomRight,QWidget * parent)94 KMagSelRect::KMagSelRect(const QPoint &topLeft, const QPoint &bottomRight,
95                  QWidget *parent) :
96 QRect(topLeft, bottomRight)
97 {
98   init(parent);
99 }
100 
KMagSelRect(const QPoint & topLeft,const QSize & size,QWidget * parent)101 KMagSelRect::KMagSelRect(const QPoint &topLeft, const QSize &size,
102                  QWidget *parent) :
103 QRect(topLeft, size)
104 {
105   init(parent);
106 }
107 
KMagSelRect(int left,int top,int width,int height,QWidget * parent)108 KMagSelRect::KMagSelRect(int left, int top, int width, int height,
109                  QWidget *parent) :
110 QRect(left, top, width, height)
111 {
112   init(parent);
113 }
114 
init(QWidget * parent)115 void KMagSelRect::init(QWidget *parent)
116 {
117   // Make sure parent is the window itself, not a widget within the window
118   if (parent != nullptr)
119     while (parent->parentWidget() != nullptr)
120       parent=parent->parentWidget();
121 
122   selectionwindow = nullptr;
123   selWindowParent = parent;
124 
125   m_alwaysVisible = false;
126 }
127 
~KMagSelRect()128 KMagSelRect::~KMagSelRect()
129 {
130 }
131 
132 //--------------------------------------------------------------------------
133 //
134 //--------------------------------------------------------------------------
135 
visible() const136 bool KMagSelRect::visible() const
137 {
138   return (selectionwindow != nullptr);
139 }
140 
alwaysVisible(bool visible)141 void KMagSelRect::alwaysVisible(bool visible)
142 {
143   m_alwaysVisible = visible;
144 }
145 
146 
147 //--------------------------------------------------------------------------
148 //   Slots
149 //--------------------------------------------------------------------------
150 
show()151 void KMagSelRect::show()
152 {
153   if (selectionwindow == nullptr) {
154     selectionwindow = new KMagSelWin (selWindowParent);
155     selectionwindow->setObjectName( QStringLiteral("selectionwindow" ));
156     connect (selectionwindow, &KMagSelWin::resized, this, &KMagSelRect::selWinResized);
157 
158     update();
159     selectionwindow->show();
160     selWindowParent->activateWindow();
161   }
162 }
163 
hide()164 void KMagSelRect::hide()
165 {
166   if(m_alwaysVisible)
167     return;
168   if (selectionwindow != nullptr) {
169     selectionwindow->hide();
170     delete selectionwindow;
171     selectionwindow = nullptr;
172   }
173 }
174 
update()175 void KMagSelRect::update()
176 {
177   if (selectionwindow)
178     selectionwindow->setSelRect (QRect (topLeft(), bottomRight()));
179 }
180 
selWinResized()181 void KMagSelRect::selWinResized()
182 {
183   if (selectionwindow)
184   {
185     const QRect newRect = selectionwindow->getSelRect();
186     setRect (newRect.x(), newRect.y(), newRect.width(), newRect.height());
187   }
188 }
189 
190 //--------------------------------------------------------------------------
191 //   KMagSelWin
192 //--------------------------------------------------------------------------
193 
setPaletteColor(QWidget * w,QPalette::ColorRole r,const QColor & c)194 void setPaletteColor(QWidget* w, QPalette::ColorRole r, const QColor& c)
195 {
196   QPalette p = w->palette();
197   p.setColor(r, c);
198   w->setPalette(p);
199 }
200 
KMagSelWin(QWidget * parent)201 KMagSelWin::KMagSelWin ( QWidget * parent ) :
202     QWidget(parent) //Qt::WStyle_Customize | Qt::WStyle_NoBorder | Qt::WStyle_StaysOnTop | Qt::WType_TopLevel | Qt::WX11BypassWM)
203 {
204   setWindowFlags( Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
205 
206   QPalette p = palette();
207   p.setBrush(backgroundRole(), QBrush(QBitmap::fromData( QSize(8,  8),  line_bits)));
208   setPalette(p);
209 
210   titleBar = new KMagSelWinCorner (this);
211   titleBar->setObjectName( QStringLiteral("titlebar" ));
212   setPaletteColor(titleBar, QPalette::Window, getTitleColor());
213   setPaletteColor(titleBar, QPalette::WindowText, getTextColor());
214   titleBar->setText(i18n("Selection Window")+QLatin1String( " - " )+i18n("KMagnifier"));
215   connect (titleBar, &KMagSelWinCorner::startResizing, this, &KMagSelWin::startResizing);
216   connect (titleBar, &KMagSelWinCorner::resized, this, &KMagSelWin::titleMoved);
217 
218   topLeftCorner = new KMagSelWinCorner (this);
219   topLeftCorner->setObjectName( QStringLiteral("topleft" ));
220   topLeftCorner->setCursor (Qt::SizeFDiagCursor);
221   setPaletteColor(topLeftCorner, QPalette::Window, getTitleBtnColor());
222   connect (topLeftCorner, &KMagSelWinCorner::startResizing, this, &KMagSelWin::startResizing);
223   connect (topLeftCorner, &KMagSelWinCorner::resized, this, &KMagSelWin::topLeftResized);
224 
225   topRightCorner = new KMagSelWinCorner (this);
226   topRightCorner->setObjectName( QStringLiteral("topright" ));
227   topRightCorner->setCursor (Qt::SizeBDiagCursor);
228   setPaletteColor(topRightCorner, QPalette::Window, getTitleBtnColor ());
229   connect (topRightCorner, &KMagSelWinCorner::startResizing, this, &KMagSelWin::startResizing);
230   connect (topRightCorner, &KMagSelWinCorner::resized, this, &KMagSelWin::topRightResized);
231 
232   bottomLeftCorner = new KMagSelWinCorner (this);
233   bottomLeftCorner->setObjectName( QStringLiteral("bottomleft" ));
234   bottomLeftCorner->setCursor (Qt::SizeBDiagCursor);
235   setPaletteColor(bottomLeftCorner, QPalette::Window, getTitleBtnColor());
236   connect (bottomLeftCorner, &KMagSelWinCorner::startResizing, this, &KMagSelWin::startResizing);
237   connect (bottomLeftCorner, &KMagSelWinCorner::resized, this, &KMagSelWin::bottomLeftResized);
238 
239   bottomRightCorner = new KMagSelWinCorner (this);
240   bottomRightCorner->setObjectName( QStringLiteral("bottomright" ));
241   bottomRightCorner->setCursor (Qt::SizeFDiagCursor);
242   setPaletteColor(bottomRightCorner, QPalette::Window, getTitleBtnColor ());
243   connect (bottomRightCorner, &KMagSelWinCorner::startResizing, this, &KMagSelWin::startResizing);
244   connect (bottomRightCorner, &KMagSelWinCorner::resized, this, &KMagSelWin::bottomRightResized);
245 }
246 
~KMagSelWin()247 KMagSelWin::~KMagSelWin()
248 {
249   delete titleBar;
250   delete topLeftCorner;
251   delete topRightCorner;
252   delete bottomLeftCorner;
253   delete bottomRightCorner;
254 }
255 
setSelRect(const QRect & _selRect)256 void KMagSelWin::setSelRect (const QRect &_selRect)
257 {
258   QRect selRect = _selRect.normalized();
259 
260   if (selRect.left() < 0)
261     selRect.setLeft (0);
262   if (selRect.top() < 0)
263     selRect.setTop (0);
264   if (selRect.right() > QApplication::desktop()->width())
265     selRect.setRight (QApplication::desktop()->width());
266   if (selRect.bottom() > QApplication::desktop()->height())
267     selRect.setBottom (QApplication::desktop()->height());
268 
269   setGeometry (
270       selRect.left() - getFrameSize(),
271       selRect.top() - getTitleSize() - 2,
272       selRect.width() + getFrameSize() + getFrameSize(),
273       selRect.height() + getFrameSize() + getTitleSize()+2);
274 
275   int w = getFrameSize();
276   if (selRect.width() < w+w)
277     w = static_cast<int>(selRect.width()/2);
278 
279   int h = getFrameSize();
280   if (selRect.height() < h+h)
281     h = static_cast<int>(selRect.height()/2);
282 
283   setMask (QRegion (QRect (0, 0, width(), height ()))
284            - QRegion (QRect (getFrameSize(), getTitleSize()+2, selRect.width(), selRect.height()))
285            - QRegion (QRect (0, 0, getFrameSize()+w, getTitleSize()+2-getFrameSize()))
286            - QRegion (QRect (width()-getFrameSize()-w, 0, getFrameSize()+w, getTitleSize()+2-getFrameSize()))
287            - QRegion (QRect (0, getTitleSize()+2+h, getFrameSize()-2, selRect.height()-h-h))
288            - QRegion (QRect (width()-getFrameSize()+2, getTitleSize()+2+h, getFrameSize()-2, selRect.height()-h-h))
289            - QRegion (QRect (getFrameSize()+w, height()-getFrameSize()+2, selRect.width()-w-w, getFrameSize()-2)));
290 
291   titleBar->setGeometry (getFrameSize()+w, 0, selRect.width()-h-h, getTitleSize());
292   topLeftCorner->setGeometry (0, getTitleSize()+2-getFrameSize(), getFrameSize()+w, getFrameSize()+h);
293   topRightCorner->setGeometry (width()-getFrameSize()-w, getTitleSize()+2-getFrameSize(), getFrameSize()+w, getFrameSize()+h);
294   bottomLeftCorner->setGeometry (0, height()-getFrameSize()-h, getFrameSize()+w, getFrameSize()+h);
295   bottomRightCorner->setGeometry (width()-getFrameSize()-w, height()-getFrameSize()-h, getFrameSize()+w, getFrameSize()+h);
296 }
297 
getSelRect()298 QRect KMagSelWin::getSelRect ()
299 {
300   return QRect (
301       x() + getFrameSize(),
302       y() + getTitleSize()+2,
303       width() - getFrameSize() - getFrameSize(),
304       height() - getFrameSize() - getTitleSize()-2);
305 }
306 
startResizing()307 void KMagSelWin::startResizing ()
308 {
309   oldSelRect = getSelRect();
310 }
311 
titleMoved(const QPoint & offset)312 void KMagSelWin::titleMoved (const QPoint &offset)
313 {
314   QRect selRect = oldSelRect;
315   selRect.translate (offset.x(), offset.y());
316   setSelRect (selRect);
317   Q_EMIT resized ();
318 }
319 
topLeftResized(const QPoint & offset)320 void KMagSelWin::topLeftResized (const QPoint &offset)
321 {
322   setSelRect (QRect(oldSelRect.topLeft() + offset, oldSelRect.bottomRight ()));
323   Q_EMIT resized();
324 }
325 
topRightResized(const QPoint & offset)326 void KMagSelWin::topRightResized (const QPoint &offset)
327 {
328   setSelRect (QRect(oldSelRect.topRight() + offset, oldSelRect.bottomLeft ()));
329   Q_EMIT resized();
330 }
331 
bottomLeftResized(const QPoint & offset)332 void KMagSelWin::bottomLeftResized (const QPoint &offset)
333 {
334   setSelRect (QRect(oldSelRect.bottomLeft() + offset, oldSelRect.topRight ()));
335   Q_EMIT resized();
336 }
337 
bottomRightResized(const QPoint & offset)338 void KMagSelWin::bottomRightResized (const QPoint &offset)
339 {
340   setSelRect (QRect(oldSelRect.bottomRight() + offset, oldSelRect.topLeft()));
341   Q_EMIT resized();
342 }
343 
344 
345 //--------------------------------------------------------------------------
346 //   KMagSelWinCorner
347 //--------------------------------------------------------------------------
348 
KMagSelWinCorner(QWidget * parent)349 KMagSelWinCorner::KMagSelWinCorner ( QWidget * parent ) :
350     QLabel (parent)
351 {
352   setFrameStyle (QFrame::WinPanel | QFrame::Raised);
353   setLineWidth (1);
354 }
355 
~KMagSelWinCorner()356 KMagSelWinCorner::~KMagSelWinCorner()
357 {
358 }
359 
mousePressEvent(QMouseEvent * e)360 void KMagSelWinCorner::mousePressEvent ( QMouseEvent * e )
361 {
362   oldPos = e->globalPos ();
363   Q_EMIT startResizing ();
364 }
365 
mouseReleaseEvent(QMouseEvent * e)366 void KMagSelWinCorner::mouseReleaseEvent ( QMouseEvent * e )
367 {
368   setFrameShadow (QFrame::Raised);
369   Q_EMIT resized (e->globalPos () - oldPos);
370 }
371 
mouseMoveEvent(QMouseEvent * e)372 void KMagSelWinCorner::mouseMoveEvent ( QMouseEvent * e )
373 {
374   Q_EMIT resized (e->globalPos () - oldPos);
375 }
376