summaryrefslogtreecommitdiff
path: root/test/radialmap/radialMap/widgetEvents.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/radialmap/radialMap/widgetEvents.cpp')
-rw-r--r--test/radialmap/radialMap/widgetEvents.cpp212
1 files changed, 212 insertions, 0 deletions
diff --git a/test/radialmap/radialMap/widgetEvents.cpp b/test/radialmap/radialMap/widgetEvents.cpp
new file mode 100644
index 0000000..0dd980d
--- /dev/null
+++ b/test/radialmap/radialMap/widgetEvents.cpp
@@ -0,0 +1,212 @@
+/***********************************************************************
+* Copyright 2003-2004 Max Howell <max.howell@methylblue.com>
+* Copyright 2008-2009 Martin Sandsmark <martin.sandsmark@kde.org>
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation; either version 2 of
+* the License or (at your option) version 3 or any later version
+* accepted by the membership of KDE e.V. (or its successor approved
+* by the membership of KDE e.V.), which shall act as a proxy
+* defined in Section 14 of version 3 of the license.
+*
+* 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 General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+***********************************************************************/
+
+#include "fileTree.h"
+#include "Config.h"
+#include "radialMap.h" //class Segment
+#include "widget.h"
+
+#include <QMenu> //::mousePressEvent()
+#include <QUrl>
+
+#include <QApplication> //QApplication::setOverrideCursor()
+#include <QClipboard>
+#include <QPainter>
+#include <QTimer> //::resizeEvent()
+#include <QDropEvent>
+#include <QPaintEvent>
+#include <QResizeEvent>
+#include <QMouseEvent>
+#include <QDragEnterEvent>
+#include <QToolTip>
+#include <QMimeData>
+
+#include <cmath> //::segmentAt()
+
+void RadialMap::Widget::resizeEvent(QResizeEvent*)
+{
+ if (m_map.resize(rect()))
+ m_timer.setSingleShot(true);
+ m_timer.start(500); //will cause signature to rebuild for new size
+
+ //always do these as they need to be initialised on creation
+ m_offset.rx() = (width() - m_map.width()) / 2;
+ m_offset.ry() = (height() - m_map.height()) / 2;
+}
+
+void RadialMap::Widget::paintEvent(QPaintEvent*)
+{
+ QPainter paint;
+ paint.begin(this);
+
+ if (!m_map.isNull())
+ paint.drawPixmap(m_offset, m_map.pixmap());
+ else
+ {
+ paint.drawText(rect(), 0, tr("We messed up, the user needs to initiate a rescan."));
+ return;
+ }
+
+ //exploded labels
+ if (!m_map.isNull() && !m_timer.isActive())
+ {
+ if (Config::antialias) {
+ paint.setRenderHint(QPainter::Antialiasing);
+ //make lines appear on pixel boundaries
+ paint.translate(0.5, 0.5);
+ }
+ paintExplodedLabels(paint);
+ }
+}
+
+const RadialMap::Segment* RadialMap::Widget::segmentAt(QPoint &e) const
+{
+ //determine which segment QPoint e is above
+
+ e -= m_offset;
+
+ if (!m_map.m_signature)
+ return nullptr;
+
+ if (e.x() <= m_map.width() && e.y() <= m_map.height())
+ {
+ //transform to cartesian coords
+ e.rx() -= m_map.width() / 2; //should be an int
+ e.ry() = m_map.height() / 2 - e.y();
+
+ double length = hypot(e.x(), e.y());
+
+ if (length >= m_map.m_innerRadius) //not hovering over inner circle
+ {
+ uint depth = ((int)length - m_map.m_innerRadius) / m_map.m_ringBreadth;
+
+ if (depth <= m_map.m_visibleDepth) //**** do earlier since you can //** check not outside of range
+ {
+ //vector calculation, reduces to simple trigonometry
+ //cos angle = (aibi + ajbj) / albl
+ //ai = x, bi=1, aj=y, bj=0
+ //cos angle = x / (length)
+
+ uint a = (uint)(acos((double)e.x() / length) * 916.736); //916.7324722 = #radians in circle * 16
+
+ //acos only understands 0-180 degrees
+ if (e.y() < 0) a = 5760 - a;
+
+ for (Segment *segment : m_map.m_signature[depth]) {
+ if (segment->intersects(a))
+ return segment;
+ }
+ }
+ }
+ else return m_rootSegment; //hovering over inner circle
+ }
+
+ return nullptr;
+}
+
+void RadialMap::Widget::mouseMoveEvent(QMouseEvent *e)
+{
+ //set m_focus to what we hover over, update UI if it's a new segment
+
+ Segment const * const oldFocus = m_focus;
+ QPoint p = e->pos();
+
+ m_focus = segmentAt(p); //NOTE p is passed by non-const reference
+
+ if (m_focus)
+ {
+ m_tooltip.move(e->globalX() + 20, e->globalY() + 20);
+ if (m_focus != oldFocus) //if not same as last time
+ {
+ setCursor(Qt::PointingHandCursor);
+
+ QString string;
+
+
+ string = QObject::tr("Tooltip of file/folder, %1 is path, %2 is size")
+ .arg(m_focus->file()->displayPath())
+ .arg(m_focus->file()->humanReadableSize());
+
+ if (m_focus->file()->isFolder()) {
+ int files = static_cast<const Folder*>(m_focus->file())->children();
+ const uint percent = uint((100 * files) / (double)m_tree->children());
+
+ string += QLatin1Char('\n');
+ if (percent > 0) {
+ string += QObject::tr("Tooltip of folder, %1 File (%2%)")
+ .arg(files).arg(percent);
+ } else {
+ string += QObject::tr("Tooltip of folder, %1 File")
+ .arg(files);
+ }
+ }
+
+
+ // Calculate a semi-sane size for the tooltip
+ QFontMetrics fontMetrics(font());
+ int tooltipWidth = 0;
+ int tooltipHeight = 0;
+ for (const QString &part : string.split(QLatin1Char('\n'))) {
+ tooltipHeight += fontMetrics.height();
+ tooltipWidth = qMax(tooltipWidth, fontMetrics.width(part));
+ }
+ // Limit it to the window size, probably should find something better
+ tooltipWidth = qMin(tooltipWidth, window()->width());
+ tooltipWidth += 10;
+ tooltipHeight += 10;
+ m_tooltip.resize(tooltipWidth, tooltipHeight);
+ m_tooltip.setText(string);
+ m_tooltip.show();
+
+ emit mouseHover(m_focus->file()->displayPath());
+ update();
+ }
+ }
+ else if (oldFocus && oldFocus->file() != m_tree)
+ {
+ m_tooltip.hide();
+ unsetCursor();
+ update();
+
+ emit mouseHover(QString());
+ }
+}
+
+void RadialMap::Widget::enterEvent(QEvent *)
+{
+ if (!m_focus) return;
+
+ setCursor(Qt::PointingHandCursor);
+ emit mouseHover(m_focus->file()->displayPath());
+ update();
+}
+
+void RadialMap::Widget::leaveEvent(QEvent *)
+{
+ m_tooltip.hide();
+}
+
+void RadialMap::Widget::changeEvent(QEvent *e)
+{
+ if (e->type() == QEvent::ApplicationPaletteChange ||
+ e->type() == QEvent::PaletteChange)
+ m_map.paint();
+}