summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/button.pngbin0 -> 3962 bytes
-rw-r--r--test/button.xcfbin0 -> 7496 bytes
-rw-r--r--test/chartarea/MainWindow.cpp26
-rw-r--r--test/chartarea/MainWindow.h26
-rw-r--r--test/chartarea/MainWindow.ui49
-rw-r--r--test/chartarea/chartarea.pro35
-rw-r--r--test/chartarea/main.cpp11
-rw-r--r--test/chartarea/widget.cpp134
-rw-r--r--test/chartarea/widget.h49
-rw-r--r--test/darkbutton/DarkButton.cpp99
-rw-r--r--test/darkbutton/DarkButton.h22
-rw-r--r--test/darkbutton/MainWindow.cpp41
-rw-r--r--test/darkbutton/MainWindow.h26
-rw-r--r--test/darkbutton/MainWindow.ui26
-rw-r--r--test/darkbutton/cancelDarkD.pngbin0 -> 151 bytes
-rw-r--r--test/darkbutton/cancelDarkE.pngbin0 -> 473 bytes
-rw-r--r--test/darkbutton/darkButton.pngbin0 -> 3969 bytes
-rw-r--r--test/darkbutton/darkButtonOver.pngbin0 -> 4286 bytes
-rw-r--r--test/darkbutton/darkButtonPushed.pngbin0 -> 3903 bytes
-rw-r--r--test/darkbutton/darkbutton.pro38
-rw-r--r--test/darkbutton/main.cpp11
-rw-r--r--test/darkbutton/res.qrc9
-rw-r--r--test/progressbardark/MainWindow.cpp32
-rw-r--r--test/progressbardark/MainWindow.h26
-rw-r--r--test/progressbardark/MainWindow.ui26
-rw-r--r--test/progressbardark/ProgressBarDark.cpp50
-rw-r--r--test/progressbardark/ProgressBarDark.h16
-rw-r--r--test/progressbardark/main.cpp11
-rw-r--r--test/progressbardark/progressBarin.pngbin0 -> 4487 bytes
-rw-r--r--test/progressbardark/progressBarout.pngbin0 -> 1287 bytes
-rw-r--r--test/progressbardark/progressbardark.pro38
-rw-r--r--test/progressbardark/progressbardark.pro.user.4.8-pre1336
-rw-r--r--test/progressbardark/res.qrc6
-rw-r--r--test/radialmap/Config.cpp31
-rw-r--r--test/radialmap/Config.h45
-rw-r--r--test/radialmap/MainWindow.cpp81
-rw-r--r--test/radialmap/MainWindow.h29
-rw-r--r--test/radialmap/MainWindow.ui46
-rw-r--r--test/radialmap/fileTree.cpp54
-rw-r--r--test/radialmap/fileTree.h157
-rw-r--r--test/radialmap/main.cpp11
-rw-r--r--test/radialmap/radialMap/labels.cpp317
-rw-r--r--test/radialmap/radialMap/map.cpp413
-rw-r--r--test/radialmap/radialMap/map.h84
-rw-r--r--test/radialmap/radialMap/radialMap.h109
-rw-r--r--test/radialmap/radialMap/sincos.h45
-rw-r--r--test/radialmap/radialMap/widget.cpp191
-rw-r--r--test/radialmap/radialMap/widget.h112
-rw-r--r--test/radialmap/radialMap/widgetEvents.cpp212
-rw-r--r--test/radialmap/radialmap.pro46
50 files changed, 3126 insertions, 0 deletions
diff --git a/test/button.png b/test/button.png
new file mode 100644
index 0000000..40bdd15
--- /dev/null
+++ b/test/button.png
Binary files differ
diff --git a/test/button.xcf b/test/button.xcf
new file mode 100644
index 0000000..274e2a8
--- /dev/null
+++ b/test/button.xcf
Binary files differ
diff --git a/test/chartarea/MainWindow.cpp b/test/chartarea/MainWindow.cpp
new file mode 100644
index 0000000..489fa6f
--- /dev/null
+++ b/test/chartarea/MainWindow.cpp
@@ -0,0 +1,26 @@
+#include "MainWindow.h"
+#include "ui_MainWindow.h"
+#include <QDir>
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow),
+ m_map(new ChartArea::Widget(this))
+{
+ ui->setupUi(this);
+ //m_map->hide();
+ ui->verticalLayout->addWidget(m_map);
+
+ connect(&timer,&QTimer::timeout,this,&MainWindow::addValue);
+ timer.start(1000);
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::addValue()
+{
+ m_map->addValue(rand()%5000);
+}
diff --git a/test/chartarea/MainWindow.h b/test/chartarea/MainWindow.h
new file mode 100644
index 0000000..29a297d
--- /dev/null
+++ b/test/chartarea/MainWindow.h
@@ -0,0 +1,26 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QTimer>
+#include "widget.h"
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+ void addValue();
+private:
+ Ui::MainWindow *ui;
+ ChartArea::Widget * m_map;
+ QTimer timer;
+};
+
+#endif // MAINWINDOW_H
diff --git a/test/chartarea/MainWindow.ui b/test/chartarea/MainWindow.ui
new file mode 100644
index 0000000..312e028
--- /dev/null
+++ b/test/chartarea/MainWindow.ui
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-color: rgb(240, 240, 240);</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="maximumSize">
+ <size>
+ <width>30</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-color: rgb(255, 255, 255,0);</string>
+ </property>
+ <property name="value">
+ <number>24</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="format">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/test/chartarea/chartarea.pro b/test/chartarea/chartarea.pro
new file mode 100644
index 0000000..91b165d
--- /dev/null
+++ b/test/chartarea/chartarea.pro
@@ -0,0 +1,35 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2019-05-30T12:37:58
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = radialmap
+TEMPLATE = app
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+
+SOURCES += \
+ main.cpp \
+ MainWindow.cpp \
+ widget.cpp
+HEADERS += \
+ MainWindow.h \
+ widget.h
+
+FORMS += \
+ MainWindow.ui
diff --git a/test/chartarea/main.cpp b/test/chartarea/main.cpp
new file mode 100644
index 0000000..af9caac
--- /dev/null
+++ b/test/chartarea/main.cpp
@@ -0,0 +1,11 @@
+#include "MainWindow.h"
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/test/chartarea/widget.cpp b/test/chartarea/widget.cpp
new file mode 100644
index 0000000..0da898d
--- /dev/null
+++ b/test/chartarea/widget.cpp
@@ -0,0 +1,134 @@
+/***********************************************************************
+* 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 "widget.h"
+
+#include <QWidget>
+#include <QPainter>
+#include <QVector>
+#include <QPointF>
+#include <iostream>
+
+ChartArea::Widget::Widget(QWidget *parent)
+ : QWidget(parent)
+{
+ setSizePolicy(QSizePolicy::Preferred,QSizePolicy::MinimumExpanding);
+ setMinimumHeight(20);
+ setMinimumWidth(100);
+}
+
+ChartArea::Widget::~Widget()
+{
+}
+
+void ChartArea::Widget::invalidate()
+{
+}
+
+void ChartArea::Widget::resizeEvent(QResizeEvent*)
+{
+ /*std::cerr << "width(): " << width() << std::endl;
+ std::cerr << "height(): " << height() << std::endl;*/
+}
+
+void ChartArea::Widget::addValue(uint64_t value)
+{
+ //m_values.push_back(value);
+ while(m_values.size()>64)
+ m_values.erase(m_values.begin());
+ update();
+}
+
+void ChartArea::Widget::paintEvent(QPaintEvent*)
+{
+ //std::cerr << "paintEvent(): " << width() << std::endl;
+
+ QPainter painter;
+ painter.begin(this);
+ painter.drawRect(0,0,width()-1,height()-1);
+ painter.setRenderHint(QPainter::Antialiasing,true);
+ painter.setRenderHint(QPainter::SmoothPixmapTransform,true);
+ painter.setRenderHint(QPainter::HighQualityAntialiasing,true);
+
+ while(m_values.size()<64)
+ m_values.insert(m_values.begin(),0);
+ std::vector<uint64_t> values=m_values;
+ QVector<QPointF> points;
+ {
+ uint64_t max=0;
+ unsigned int index=0;
+ while(index<values.size())
+ {
+ if(max<values.at(index))
+ max=values.at(index);
+ index++;
+ }
+ if(max<=0)
+ {
+ points << QPointF(0, height()-1);
+ points << QPointF(width()/2, height()-1);
+ points << QPointF(width()-1, height()-1);
+ }
+ else
+ {
+ index=0;
+ while(index<values.size())
+ {
+ int w=width()-1;
+ int nw=w*index/(m_values.size()-1);
+ points << QPointF(nw, height()-values.at(index)*height()/max);
+ index++;
+ }
+ }
+ }
+
+ painter.setPen(Qt::NoPen);
+ QLinearGradient gradient(0,height()*0.5,0,height());
+ gradient.setColorAt(0, QColor(160,240,160,150));
+ //gradient.setColorAt(0.2, QColor(100,220,100,200));
+ gradient.setColorAt(1, QColor(160,240,160,0));
+ painter.setBrush(gradient);
+ points.push_front(QPointF(0, height()-1));
+ points.push_back(QPointF(width()-1, height()-1));
+ painter.drawPolygon(QPolygonF(points));
+
+ if(width()*height()>250000)
+ painter.setPen(QPen(QColor(160,240,160), 3));
+ else
+ painter.setPen(QPen(QColor(160,240,160), 2));
+ painter.drawPolyline(QPolygonF(points));
+
+
+ // todo: bounding rect + center flag
+ if(height()>30)
+ {
+ QFont font = painter.font();
+ int heightTemp=height()/5;
+ if(heightTemp<14)
+ heightTemp=14;
+ font.setPixelSize(heightTemp);
+ painter.setFont(font);
+
+ painter.setPen(QPen(QColor(140,140,140), 3));
+ painter.drawText(0,0,width(),height(),Qt::AlignHCenter | Qt::AlignBottom,tr("%1B/s").arg(m_values.back()));
+ }
+ painter.end();
+}
diff --git a/test/chartarea/widget.h b/test/chartarea/widget.h
new file mode 100644
index 0000000..8a4c742
--- /dev/null
+++ b/test/chartarea/widget.h
@@ -0,0 +1,49 @@
+/***********************************************************************
+* 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/>.
+***********************************************************************/
+
+#ifndef WIDGET_H
+#define WIDGET_H
+
+#include <QResizeEvent>
+#include <QWidget>
+
+namespace ChartArea
+{
+
+class Widget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit Widget(QWidget* = nullptr);
+ ~Widget() override;
+ void addValue(uint64_t value);
+public Q_SLOTS:
+ void invalidate();
+protected:
+ void paintEvent(QPaintEvent*) override;
+ void resizeEvent(QResizeEvent*) override;
+private:
+ std::vector<uint64_t> m_values;
+};
+}
+
+#endif
diff --git a/test/darkbutton/DarkButton.cpp b/test/darkbutton/DarkButton.cpp
new file mode 100644
index 0000000..b785961
--- /dev/null
+++ b/test/darkbutton/DarkButton.cpp
@@ -0,0 +1,99 @@
+#include "DarkButton.h"
+#include <QPainter>
+
+DarkButton::DarkButton(QWidget *parent) :
+ QPushButton(parent)
+{
+ setMinimumHeight(36);
+ setMaximumHeight(36);
+ setStyleSheet("border:none;color:#afb;");
+ over=false;
+ enabled=true;
+}
+
+void DarkButton::paintEvent(QPaintEvent * event)
+{
+ if(backgroundLeft.isNull() || backgroundLeft.height()!=height())
+ {
+ QPixmap background(":/darkButton.png");
+ if(background.isNull())
+ abort();
+ QPixmap backgroundPushed(":/darkButtonPushed.png");
+ if(backgroundPushed.isNull())
+ abort();
+ QPixmap over(":/darkButtonOver.png");
+ if(over.isNull())
+ abort();
+ if(height()==background.height())
+ {
+ backgroundLeft=background.copy(0,0,10,36);
+ backgroundMiddle=background.copy(10,0,46,36);
+ backgroundRight=background.copy(56,0,10,36);
+ backgroundPushedLeft=backgroundPushed.copy(0,0,10,36);
+ backgroundPushedMiddle=backgroundPushed.copy(10,0,46,36);
+ backgroundPushedRight=backgroundPushed.copy(56,0,10,36);
+ overLeft=over.copy(0,0,10,36);
+ overMiddle=over.copy(10,0,46,36);
+ overRight=over.copy(56,0,10,36);
+ }
+ else
+ {
+ backgroundLeft=background.copy(0,0,10,36).scaledToHeight(height(),Qt::SmoothTransformation);
+ backgroundMiddle=background.copy(10,0,46,36).scaledToHeight(height(),Qt::SmoothTransformation);
+ backgroundRight=background.copy(56,0,10,36).scaledToHeight(height(),Qt::SmoothTransformation);
+ backgroundPushedLeft=backgroundPushed.copy(0,0,10,36).scaledToHeight(height(),Qt::SmoothTransformation);
+ backgroundPushedMiddle=backgroundPushed.copy(10,0,46,36).scaledToHeight(height(),Qt::SmoothTransformation);
+ backgroundPushedRight=backgroundPushed.copy(56,0,10,36).scaledToHeight(height(),Qt::SmoothTransformation);
+ overLeft=over.copy(0,0,10,36).scaledToHeight(height(),Qt::SmoothTransformation);
+ overMiddle=over.copy(10,0,46,36).scaledToHeight(height(),Qt::SmoothTransformation);
+ overRight=over.copy(56,0,10,36).scaledToHeight(height(),Qt::SmoothTransformation);
+ }
+ }
+ QPainter paint;
+ paint.begin(this);
+ if(enabled && !isEnabled())
+ {
+ setStyleSheet("border:none;color:#fab;");
+ enabled=false;
+ }
+ if(!enabled && isEnabled())
+ {
+ setStyleSheet("border:none;color:#afb;");
+ enabled=true;
+ }
+ if(isDown() && isEnabled())
+ {
+ paint.drawPixmap(0,0,backgroundPushedLeft.width(), backgroundPushedLeft.height(), backgroundPushedLeft);
+ paint.drawPixmap(backgroundPushedLeft.width(), 0,
+ width()-backgroundPushedLeft.width()-backgroundPushedRight.width(), backgroundPushedLeft.height(),backgroundPushedMiddle);
+ paint.drawPixmap(width()-backgroundPushedRight.width(),0, backgroundPushedRight.width(), backgroundPushedRight.height(),backgroundPushedRight);
+ }
+ else
+ {
+ paint.drawPixmap(0,0,backgroundLeft.width(), backgroundLeft.height(), backgroundLeft);
+ paint.drawPixmap(backgroundLeft.width(), 0,
+ width()-backgroundLeft.width()-backgroundRight.width(), backgroundLeft.height(),backgroundMiddle);
+ paint.drawPixmap(width()-backgroundRight.width(),0, backgroundRight.width(), backgroundRight.height(),backgroundRight);
+ }
+ if(over && isEnabled())
+ {
+ paint.drawPixmap(0,0,overLeft.width(), overLeft.height(), overLeft);
+ paint.drawPixmap(overLeft.width(), 0,
+ width()-overLeft.width()-overRight.width(), overLeft.height(),overMiddle);
+ paint.drawPixmap(width()-overRight.width(),0, overRight.width(), overRight.height(),overRight);
+ }
+ QPushButton::paintEvent(event);
+}
+
+void DarkButton::enterEvent(QEvent *e)
+{
+ over=true;
+ QWidget::enterEvent(e);
+ update();
+}
+void DarkButton::leaveEvent(QEvent *e)
+{
+ over=false;
+ QWidget::leaveEvent(e);
+ update();
+}
diff --git a/test/darkbutton/DarkButton.h b/test/darkbutton/DarkButton.h
new file mode 100644
index 0000000..38dbb60
--- /dev/null
+++ b/test/darkbutton/DarkButton.h
@@ -0,0 +1,22 @@
+#ifndef DarkButton_H
+#define DarkButton_H
+
+#include <QPushButton>
+
+class DarkButton : public QPushButton
+{
+public:
+ DarkButton(QWidget *parent = nullptr);
+ void paintEvent(QPaintEvent *) override;
+protected:
+ void enterEvent(QEvent *e) override;
+ void leaveEvent(QEvent *e) override;
+private:
+ QPixmap backgroundLeft,backgroundMiddle,backgroundRight;
+ QPixmap backgroundPushedLeft,backgroundPushedMiddle,backgroundPushedRight;
+ QPixmap overLeft,overMiddle,overRight;
+ bool over;
+ bool enabled;
+};
+
+#endif // PROGRESSBARDARK_H
diff --git a/test/darkbutton/MainWindow.cpp b/test/darkbutton/MainWindow.cpp
new file mode 100644
index 0000000..78cda6a
--- /dev/null
+++ b/test/darkbutton/MainWindow.cpp
@@ -0,0 +1,41 @@
+#include "MainWindow.h"
+#include "ui_MainWindow.h"
+#include <sys/stat.h>
+#include <iostream>
+#include <dirent.h>
+#include <stdio.h>
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow),
+ darkButton(new DarkButton)
+{
+ ui->setupUi(this);
+
+ darkButton->setText("toto");
+ QIcon icon;
+ icon.addFile(QString::fromUtf8(":/cancelDarkD.png"), QSize(), QIcon::Normal, QIcon::Off);
+ icon.addFile(QString::fromUtf8(":/cancelDarkE.png"), QSize(), QIcon::Normal, QIcon::On);
+ darkButton->setIcon(icon);
+ darkButton->setCheckable(true);
+
+ ui->verticalLayout->addWidget(darkButton);
+ connect(&timer,&QTimer::timeout,this,&MainWindow::create);
+ timer.start(1000);
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::create()
+{
+ if(darkButton->isChecked())
+ {
+ darkButton->setEnabled(!darkButton->isEnabled());
+ darkButton->setChecked(false);
+ }
+ else
+ darkButton->setChecked(true);
+}
diff --git a/test/darkbutton/MainWindow.h b/test/darkbutton/MainWindow.h
new file mode 100644
index 0000000..118257f
--- /dev/null
+++ b/test/darkbutton/MainWindow.h
@@ -0,0 +1,26 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QTimer>
+#include "DarkButton.h"
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+ void create();
+private:
+ Ui::MainWindow *ui;
+ DarkButton * darkButton;
+ QTimer timer;
+};
+
+#endif // MAINWINDOW_H
diff --git a/test/darkbutton/MainWindow.ui b/test/darkbutton/MainWindow.ui
new file mode 100644
index 0000000..246d92c
--- /dev/null
+++ b/test/darkbutton/MainWindow.ui
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">#MainWindow{background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgb(70, 70, 70), stop:1 rgb(40, 40, 40));}</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QVBoxLayout" name="verticalLayout"/>
+ </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/test/darkbutton/cancelDarkD.png b/test/darkbutton/cancelDarkD.png
new file mode 100644
index 0000000..a2f4556
--- /dev/null
+++ b/test/darkbutton/cancelDarkD.png
Binary files differ
diff --git a/test/darkbutton/cancelDarkE.png b/test/darkbutton/cancelDarkE.png
new file mode 100644
index 0000000..1cda258
--- /dev/null
+++ b/test/darkbutton/cancelDarkE.png
Binary files differ
diff --git a/test/darkbutton/darkButton.png b/test/darkbutton/darkButton.png
new file mode 100644
index 0000000..561fc02
--- /dev/null
+++ b/test/darkbutton/darkButton.png
Binary files differ
diff --git a/test/darkbutton/darkButtonOver.png b/test/darkbutton/darkButtonOver.png
new file mode 100644
index 0000000..ea42018
--- /dev/null
+++ b/test/darkbutton/darkButtonOver.png
Binary files differ
diff --git a/test/darkbutton/darkButtonPushed.png b/test/darkbutton/darkButtonPushed.png
new file mode 100644
index 0000000..e2e63a5
--- /dev/null
+++ b/test/darkbutton/darkButtonPushed.png
Binary files differ
diff --git a/test/darkbutton/darkbutton.pro b/test/darkbutton/darkbutton.pro
new file mode 100644
index 0000000..fc31c76
--- /dev/null
+++ b/test/darkbutton/darkbutton.pro
@@ -0,0 +1,38 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2019-05-30T12:37:58
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = darkbutton
+TEMPLATE = app
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+FORMS += \
+ MainWindow.ui
+
+HEADERS += \
+ MainWindow.h \
+ DarkButton.h
+
+SOURCES += \
+ main.cpp \
+ MainWindow.cpp \
+ DarkButton.cpp
+
+RESOURCES += \
+ res.qrc
diff --git a/test/darkbutton/main.cpp b/test/darkbutton/main.cpp
new file mode 100644
index 0000000..af9caac
--- /dev/null
+++ b/test/darkbutton/main.cpp
@@ -0,0 +1,11 @@
+#include "MainWindow.h"
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/test/darkbutton/res.qrc b/test/darkbutton/res.qrc
new file mode 100644
index 0000000..cd9341b
--- /dev/null
+++ b/test/darkbutton/res.qrc
@@ -0,0 +1,9 @@
+<RCC>
+ <qresource prefix="/">
+ <file>darkButton.png</file>
+ <file>darkButtonPushed.png</file>
+ <file>darkButtonOver.png</file>
+ <file>cancelDarkE.png</file>
+ <file>cancelDarkD.png</file>
+ </qresource>
+</RCC>
diff --git a/test/progressbardark/MainWindow.cpp b/test/progressbardark/MainWindow.cpp
new file mode 100644
index 0000000..07939bc
--- /dev/null
+++ b/test/progressbardark/MainWindow.cpp
@@ -0,0 +1,32 @@
+#include "MainWindow.h"
+#include "ui_MainWindow.h"
+#include <sys/stat.h>
+#include <iostream>
+#include <dirent.h>
+#include <stdio.h>
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow),
+ progressBarDark(new ProgressBarDark)
+{
+ ui->setupUi(this);
+ ui->verticalLayout->addWidget(progressBarDark);
+ connect(&treeTimer,&QTimer::timeout,this,&MainWindow::create);
+ treeTimer.start(100);
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::create()
+{
+ int val=progressBarDark->value();
+ if(val>=100)
+ val=0;
+ else
+ val++;
+ progressBarDark->setValue(val);
+}
diff --git a/test/progressbardark/MainWindow.h b/test/progressbardark/MainWindow.h
new file mode 100644
index 0000000..7fcf988
--- /dev/null
+++ b/test/progressbardark/MainWindow.h
@@ -0,0 +1,26 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QTimer>
+#include "ProgressBarDark.h"
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+ void create();
+private:
+ Ui::MainWindow *ui;
+ ProgressBarDark * progressBarDark;
+ QTimer treeTimer;
+};
+
+#endif // MAINWINDOW_H
diff --git a/test/progressbardark/MainWindow.ui b/test/progressbardark/MainWindow.ui
new file mode 100644
index 0000000..246d92c
--- /dev/null
+++ b/test/progressbardark/MainWindow.ui
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">#MainWindow{background-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgb(70, 70, 70), stop:1 rgb(40, 40, 40));}</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QVBoxLayout" name="verticalLayout"/>
+ </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/test/progressbardark/ProgressBarDark.cpp b/test/progressbardark/ProgressBarDark.cpp
new file mode 100644
index 0000000..a03167e
--- /dev/null
+++ b/test/progressbardark/ProgressBarDark.cpp
@@ -0,0 +1,50 @@
+#include "ProgressBarDark.h"
+#include <QPainter>
+
+ProgressBarDark::ProgressBarDark(QWidget *parent) :
+ QProgressBar(parent)
+{
+ setMinimumHeight(22);
+ setMaximumHeight(22);
+}
+
+void ProgressBarDark::paintEvent(QPaintEvent *)
+{
+ if(backgroundLeft.isNull() || backgroundLeft.height()!=height())
+ {
+ QPixmap background(":/progressBarout.png");
+ QPixmap bar(":/progressBarin.png");
+ if(height()==background.height())
+ {
+ backgroundLeft=background.copy(0,0,24,55);
+ backgroundMiddle=background.copy(24,0,701,55);
+ backgroundRight=background.copy(725,0,24,55);
+ barLeft=bar.copy(0,0,24,55);
+ barMiddle=bar.copy(24,0,701,55);
+ barRight=bar.copy(725,0,24,55);
+ }
+ else
+ {
+ backgroundLeft=background.copy(0,0,24,55).scaledToHeight(height(),Qt::SmoothTransformation);
+ backgroundMiddle=background.copy(24,0,701,55).scaledToHeight(height(),Qt::SmoothTransformation);
+ backgroundRight=background.copy(725,0,24,55).scaledToHeight(height(),Qt::SmoothTransformation);
+ barLeft=bar.copy(0,0,24,55).scaledToHeight(height(),Qt::SmoothTransformation);
+ barMiddle=bar.copy(24,0,701,55).scaledToHeight(height(),Qt::SmoothTransformation);
+ barRight=bar.copy(725,0,24,55).scaledToHeight(height(),Qt::SmoothTransformation);
+ }
+ }
+ int size=width()-barLeft.width()-barRight.width();
+ int inpixel=value()*size/maximum();
+ QPainter paint;
+ paint.begin(this);
+ paint.drawPixmap(0,0,backgroundLeft.width(), backgroundLeft.height(), backgroundLeft);
+ paint.drawPixmap(0,0,barLeft.width(), barLeft.height(), barLeft);
+
+ paint.drawPixmap(backgroundLeft.width(), 0,
+ width()-backgroundLeft.width()-backgroundRight.width(), backgroundLeft.height(),backgroundMiddle);
+ paint.drawPixmap(barLeft.width(), 0,
+ inpixel, barLeft.height(),barMiddle);
+
+ paint.drawPixmap(width()-backgroundRight.width(),0, backgroundRight.width(), backgroundRight.height(),backgroundRight);
+ paint.drawPixmap(barLeft.width()+inpixel, 0, barRight.width(), barRight.height(),barRight);
+}
diff --git a/test/progressbardark/ProgressBarDark.h b/test/progressbardark/ProgressBarDark.h
new file mode 100644
index 0000000..9bf92f8
--- /dev/null
+++ b/test/progressbardark/ProgressBarDark.h
@@ -0,0 +1,16 @@
+#ifndef PROGRESSBARDARK_H
+#define PROGRESSBARDARK_H
+
+#include <QProgressBar>
+
+class ProgressBarDark : public QProgressBar
+{
+public:
+ ProgressBarDark(QWidget *parent = nullptr);
+ void paintEvent(QPaintEvent *) override;
+private:
+ QPixmap backgroundLeft,backgroundMiddle,backgroundRight;
+ QPixmap barLeft,barMiddle,barRight;
+};
+
+#endif // PROGRESSBARDARK_H
diff --git a/test/progressbardark/main.cpp b/test/progressbardark/main.cpp
new file mode 100644
index 0000000..af9caac
--- /dev/null
+++ b/test/progressbardark/main.cpp
@@ -0,0 +1,11 @@
+#include "MainWindow.h"
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/test/progressbardark/progressBarin.png b/test/progressbardark/progressBarin.png
new file mode 100644
index 0000000..6af26c7
--- /dev/null
+++ b/test/progressbardark/progressBarin.png
Binary files differ
diff --git a/test/progressbardark/progressBarout.png b/test/progressbardark/progressBarout.png
new file mode 100644
index 0000000..08f3748
--- /dev/null
+++ b/test/progressbardark/progressBarout.png
Binary files differ
diff --git a/test/progressbardark/progressbardark.pro b/test/progressbardark/progressbardark.pro
new file mode 100644
index 0000000..bdf4f71
--- /dev/null
+++ b/test/progressbardark/progressbardark.pro
@@ -0,0 +1,38 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2019-05-30T12:37:58
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = progressbardark
+TEMPLATE = app
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+FORMS += \
+ MainWindow.ui
+
+HEADERS += \
+ MainWindow.h \
+ ProgressBarDark.h
+
+SOURCES += \
+ main.cpp \
+ MainWindow.cpp \
+ ProgressBarDark.cpp
+
+RESOURCES += \
+ res.qrc
diff --git a/test/progressbardark/progressbardark.pro.user.4.8-pre1 b/test/progressbardark/progressbardark.pro.user.4.8-pre1
new file mode 100644
index 0000000..efcb89e
--- /dev/null
+++ b/test/progressbardark/progressbardark.pro.user.4.8-pre1
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE QtCreatorProject>
+<!-- Written by QtCreator 4.6.2, 2019-06-16T18:36:54. -->
+<qtcreator>
+ <data>
+ <variable>EnvironmentId</variable>
+ <value type="QByteArray">{74ab603f-f657-4135-92cf-c93af71b2f91}</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.ActiveTarget</variable>
+ <value type="int">0</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.EditorSettings</variable>
+ <valuemap type="QVariantMap">
+ <value type="bool" key="EditorConfiguration.AutoIndent">true</value>
+ <value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
+ <value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
+ <value type="QString" key="language">Cpp</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
+ </valuemap>
+ </valuemap>
+ <valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
+ <value type="QString" key="language">QmlJS</value>
+ <valuemap type="QVariantMap" key="value">
+ <value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
+ </valuemap>
+ </valuemap>
+ <value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
+ <value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
+ <value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
+ <value type="int" key="EditorConfiguration.IndentSize">4</value>
+ <value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
+ <value type="int" key="EditorConfiguration.MarginColumn">80</value>
+ <value type="bool" key="EditorConfiguration.MouseHiding">true</value>
+ <value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
+ <value type="int" key="EditorConfiguration.PaddingMode">1</value>
+ <value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
+ <value type="bool" key="EditorConfiguration.ShowMargin">false</value>
+ <value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
+ <value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
+ <value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
+ <value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
+ <value type="int" key="EditorConfiguration.TabSize">8</value>
+ <value type="bool" key="EditorConfiguration.UseGlobal">true</value>
+ <value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
+ <value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
+ <value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
+ <value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
+ <value type="bool" key="EditorConfiguration.inEntireDocument">true</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.PluginSettings</variable>
+ <valuemap type="QVariantMap"/>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Target.0</variable>
+ <valuemap type="QVariantMap">
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{23178a1c-09be-4e9f-9aab-ff55e05e7637}</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
+ <value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/user/Desktop/ultracopier/sources/test/build-progressbardark-Desktop-Debug</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/user/Desktop/ultracopier/sources/test/build-progressbardark-Desktop-Release</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
+ <value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/user/Desktop/ultracopier/sources/test/build-progressbardark-Desktop-Profile</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
+ <value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
+ <value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">true</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
+ </valuemap>
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
+ <value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
+ <valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
+ <value type="QString">-w</value>
+ <value type="QString">-r</value>
+ </valuelist>
+ <value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
+ <value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
+ <value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
+ <valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
+ <value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
+ <valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
+ <value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy Configuration</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
+ <valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
+ <value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
+ <value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
+ <value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
+ <value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
+ <value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
+ <value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
+ <value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
+ <value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
+ <value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
+ <value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
+ <value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
+ <value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
+ <value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
+ <value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
+ <value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
+ <valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
+ <value type="int">0</value>
+ <value type="int">1</value>
+ <value type="int">2</value>
+ <value type="int">3</value>
+ <value type="int">4</value>
+ <value type="int">5</value>
+ <value type="int">6</value>
+ <value type="int">7</value>
+ <value type="int">8</value>
+ <value type="int">9</value>
+ <value type="int">10</value>
+ <value type="int">11</value>
+ <value type="int">12</value>
+ <value type="int">13</value>
+ <value type="int">14</value>
+ </valuelist>
+ <value type="int" key="PE.EnvironmentAspect.Base">2</value>
+ <valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">progressbardark</value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
+ <value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:/home/user/Desktop/ultracopier/sources/test/progressbardark/progressbardark.pro</value>
+ <value type="bool" key="QmakeProjectManager.QmakeRunConfiguration.UseLibrarySearchPath">true</value>
+ <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
+ <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">progressbardark.pro</value>
+ <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
+ <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
+ <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory.default">/home/user/Desktop/ultracopier/sources/test/build-progressbardark-Desktop-Debug</value>
+ <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
+ <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
+ <value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
+ <value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
+ </valuemap>
+ <value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
+ </valuemap>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.TargetCount</variable>
+ <value type="int">1</value>
+ </data>
+ <data>
+ <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
+ <value type="int">18</value>
+ </data>
+ <data>
+ <variable>Version</variable>
+ <value type="int">18</value>
+ </data>
+</qtcreator>
diff --git a/test/progressbardark/res.qrc b/test/progressbardark/res.qrc
new file mode 100644
index 0000000..c4486c9
--- /dev/null
+++ b/test/progressbardark/res.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>progressBarin.png</file>
+ <file>progressBarout.png</file>
+ </qresource>
+</RCC>
diff --git a/test/radialmap/Config.cpp b/test/radialmap/Config.cpp
new file mode 100644
index 0000000..b36c392
--- /dev/null
+++ b/test/radialmap/Config.cpp
@@ -0,0 +1,31 @@
+/***********************************************************************
+* 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 "Config.h"
+
+#include <QFont>
+
+bool Config::varyLabelFontSizes=true;
+bool Config::showSmallFiles=false;
+bool Config::antialias=true;
+uint Config::contrast=94;
+int Config::minFontPitch=QFont().pointSize() - 3;
+uint Config::defaultRingDepth=4;
diff --git a/test/radialmap/Config.h b/test/radialmap/Config.h
new file mode 100644
index 0000000..1fb43df
--- /dev/null
+++ b/test/radialmap/Config.h
@@ -0,0 +1,45 @@
+/***********************************************************************
+* 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/>.
+***********************************************************************/
+
+#ifndef Config_H
+#define Config_H
+
+#include <QStringList>
+
+namespace Filelight
+{
+class Config
+{
+public:
+ //keep everything positive, avoid using DON'T, NOT or NO
+
+ static bool varyLabelFontSizes;
+ static bool showSmallFiles;
+ static uint contrast;
+ static bool antialias;
+ static int minFontPitch;
+ static uint defaultRingDepth;
+};
+}
+
+using Filelight::Config;
+
+#endif
diff --git a/test/radialmap/MainWindow.cpp b/test/radialmap/MainWindow.cpp
new file mode 100644
index 0000000..5bebc05
--- /dev/null
+++ b/test/radialmap/MainWindow.cpp
@@ -0,0 +1,81 @@
+#include "MainWindow.h"
+#include "ui_MainWindow.h"
+#include "radialMap/widget.h"
+#include <sys/stat.h>
+#include <iostream>
+#include <dirent.h>
+#include <stdio.h>
+
+MainWindow::MainWindow(QWidget *parent) :
+ QMainWindow(parent),
+ ui(new Ui::MainWindow),
+ m_map(new RadialMap::Widget(this)),
+ tree(new Folder(""))
+{
+ recursiveTreeLoad(tree,"/etc/");
+
+ ui->setupUi(this);
+ //m_map->hide();
+ ui->verticalLayout->addWidget(m_map);
+ connect(&treeTimer,&QTimer::timeout,this,&MainWindow::create);
+ treeTimer.setSingleShot(true);
+ treeTimer.start(1);
+}
+
+MainWindow::~MainWindow()
+{
+ delete ui;
+}
+
+void MainWindow::create()
+{
+ m_map->create(tree);
+}
+
+uint64_t MainWindow::recursiveTreeLoad(Folder * tree,std::string folder)
+{
+ uint64_t size=0;
+ DIR *d;
+ struct dirent *entry;
+ d = opendir(folder.c_str());
+ if (d)
+ {
+ while ((entry = readdir(d)) != NULL)
+ {
+ if(entry==NULL)
+ break;
+ bool skip=false;
+ if(entry->d_name[0]=='.')
+ {
+ if(entry->d_name[1]==0x00)
+ skip=true;
+ else if(entry->d_name[1]=='.' && entry->d_name[2]==0x00)
+ skip=true;
+ }
+ if(!skip)
+ {
+
+ if(entry->d_type == DT_DIR)
+ {
+ Folder * newDir=new Folder(entry->d_name);
+ size+=recursiveTreeLoad(newDir,folder+entry->d_name+"/");
+ tree->append(newDir);
+ }
+ else
+ {
+ struct stat statbuf;
+ std::string path=folder+entry->d_name;
+ if(stat(path.c_str(), &statbuf) != -1)
+ {
+ size+=statbuf.st_size;
+ tree->append(entry->d_name,statbuf.st_size);
+ }
+ }
+ }
+ }
+ closedir(d);
+ }
+ if(tree->size()!=size)//wrong is recursiveTreeLoad() is call after append
+ abort();
+ return size;
+}
diff --git a/test/radialmap/MainWindow.h b/test/radialmap/MainWindow.h
new file mode 100644
index 0000000..1e0a4f7
--- /dev/null
+++ b/test/radialmap/MainWindow.h
@@ -0,0 +1,29 @@
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QTimer>
+#include "radialMap/widget.h"
+
+namespace Ui {
+class MainWindow;
+}
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
+ void create();
+private:
+ Ui::MainWindow *ui;
+ RadialMap::Widget * m_map;
+ Folder * tree;
+ QTimer treeTimer;
+
+ uint64_t recursiveTreeLoad(Folder * tree, std::string folder);
+};
+
+#endif // MAINWINDOW_H
diff --git a/test/radialmap/MainWindow.ui b/test/radialmap/MainWindow.ui
new file mode 100644
index 0000000..7b51134
--- /dev/null
+++ b/test/radialmap/MainWindow.ui
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QProgressBar" name="progressBar">
+ <property name="maximumSize">
+ <size>
+ <width>30</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="styleSheet">
+ <string notr="true">background-color: rgb(255, 255, 255,0);</string>
+ </property>
+ <property name="value">
+ <number>24</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="format">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/test/radialmap/fileTree.cpp b/test/radialmap/fileTree.cpp
new file mode 100644
index 0000000..84c7938
--- /dev/null
+++ b/test/radialmap/fileTree.cpp
@@ -0,0 +1,54 @@
+/***********************************************************************
+* Copyright 2003-2004 Max Howell <max.howell@methylblue.com>
+* Copyright 2008-2009 Martin Sandsmark <martin.sandsmark@kde.org>
+* Copyright 2017 Harald Sitter <sitter@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 <QDir>
+#include <QUrl>
+
+QString File::displayName() const {
+ const QString decodedName = QFile::decodeName(m_name);
+ return url().isLocalFile() ? QDir::toNativeSeparators(decodedName) : decodedName;
+}
+
+QString File::displayPath(const Folder *root) const
+{
+ // Use QUrl to sanitize the path for display and then run it through
+ // QDir to make sure we use native path separators.
+ const QUrl url = this->url(root);
+ const QString cleanPath = url.toDisplayString(QUrl::PreferLocalFile | QUrl::NormalizePathSegments);
+ return url.isLocalFile() ? QDir::toNativeSeparators(cleanPath) : cleanPath;
+}
+
+QUrl File::url(const Folder *root) const
+{
+ QString path;
+
+ if (root == this)
+ root = nullptr; //prevent returning empty string when there is something we could return
+
+ for (const Folder *d = (Folder*)this; d != root && d; d = d->parent()) {
+ path.prepend(QFile::decodeName(d->name8Bit()));
+ }
+
+ return QUrl::fromUserInput(path, QString(), QUrl::AssumeLocalFile);
+}
diff --git a/test/radialmap/fileTree.h b/test/radialmap/fileTree.h
new file mode 100644
index 0000000..6baa316
--- /dev/null
+++ b/test/radialmap/fileTree.h
@@ -0,0 +1,157 @@
+/***********************************************************************
+* Copyright 2003-2004 Max Howell <max.howell@methylblue.com>
+* Copyright 2008-2009 Martin Sandsmark <martin.sandsmark@kde.org>
+* Copyright 2017 Harald Sitter <sitter@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/>.
+***********************************************************************/
+
+#ifndef FILETREE_H
+#define FILETREE_H
+
+#include <QByteArray> //qstrdup
+#include <QFile> //decodeName()
+#include <QDebug>
+#include <QLocale>
+
+#include <stdlib.h>
+
+typedef quint64 FileSize;
+typedef quint64 Dirsize; //**** currently unused
+
+class Folder;
+
+class File
+{
+public:
+ friend class Folder;
+
+public:
+ File(const char *name, FileSize size) : m_parent(nullptr), m_name(qstrdup(name)), m_size(size) {}
+ virtual ~File() {
+ delete [] m_name;
+ }
+
+ Folder *parent() const {
+ return m_parent;
+ }
+
+ /** Do not use for user visible strings. Use name instead. */
+ const char *name8Bit() const {
+ return m_name;
+ }
+ /** Decoded name. Use when you need a QString. */
+ QString decodedName() const {
+ return QFile::decodeName(m_name);
+ }
+ /**
+ * Human readable name (including native separators where applicable).
+ * Only use for display.
+ */
+ QString displayName() const;
+
+ FileSize size() const {
+ return m_size;
+ }
+
+ virtual bool isFolder() const {
+ return false;
+ }
+
+ /**
+ * Human readable path for display (including native separators where applicable.
+ * Only use for display.
+ */
+ QString displayPath(const Folder * = nullptr) const;
+ QString humanReadableSize() const {
+ return QString::number(m_size);
+ }
+
+ /** Builds a complete QUrl by walking up to root. */
+ QUrl url(const Folder *root = nullptr) const;
+
+protected:
+ File(const char *name, FileSize size, Folder *parent) : m_parent(parent), m_name(qstrdup(name)), m_size(size) {}
+
+ Folder *m_parent; //0 if this is treeRoot
+ char *m_name;
+ FileSize m_size; //in units of KiB
+
+private:
+ File(const File&);
+ void operator=(const File&);
+};
+
+
+class Folder : public File
+{
+public:
+ Folder(const char *name) : File(name, 0), m_children(0) {} //DON'T pass the full path!
+
+ uint children() const {
+ return m_children;
+ }
+ bool isFolder() const override {
+ return true;
+ }
+
+ ///appends a Folder
+ void append(Folder *d, const char *name=nullptr)
+ {
+ if (name) {
+ delete [] d->m_name;
+ d->m_name = qstrdup(name);
+ } //directories that had a fullpath copy just their names this way
+
+ m_children += d->children(); //doesn't include the dir itself
+ d->m_parent = this;
+ append((File*)d); //will add 1 to filecount for the dir itself
+ }
+
+ ///appends a File
+ void append(const char *name, FileSize size)
+ {
+ append(new File(name, size, this));
+ }
+
+ /// removes a file
+ void remove(const File *f) {
+ files.removeAll(const_cast<File*>(f));
+
+ for (Folder *d = this; d; d = d->parent()) {
+ d->m_size -= f->size();
+ }
+ }
+
+ QList<File *> files;
+
+private:
+ void append(File *p)
+ {
+ m_children++;
+ m_size += p->size();
+ files.append(p);
+ }
+
+ uint m_children;
+
+private:
+ Folder(const Folder&); //undefined
+ void operator=(const Folder&); //undefined
+};
+
+#endif
diff --git a/test/radialmap/main.cpp b/test/radialmap/main.cpp
new file mode 100644
index 0000000..af9caac
--- /dev/null
+++ b/test/radialmap/main.cpp
@@ -0,0 +1,11 @@
+#include "MainWindow.h"
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.show();
+
+ return a.exec();
+}
diff --git a/test/radialmap/radialMap/labels.cpp b/test/radialmap/radialMap/labels.cpp
new file mode 100644
index 0000000..030f4f4
--- /dev/null
+++ b/test/radialmap/radialMap/labels.cpp
@@ -0,0 +1,317 @@
+/***********************************************************************
+* 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 <QFont>
+#include <QFontMetrics>
+#include <QPainter>
+#include <QVector>
+
+#include "Config.h"
+#include "fileTree.h"
+#include "radialMap.h"
+#include "sincos.h"
+#include "widget.h"
+
+
+
+namespace RadialMap
+{
+class Label
+{
+public:
+ Label(const RadialMap::Segment *s, int l) : segment(s), level(l), angle(segment->start() + (segment->length() / 2)) { }
+
+ bool tooClose(const int otherAngle) const {
+ return (angle > otherAngle - LABEL_ANGLE_MARGIN && angle < otherAngle + LABEL_ANGLE_MARGIN);
+ }
+
+ const RadialMap::Segment *segment;
+ const unsigned int level;
+ const int angle;
+
+ int targetX, targetY, middleX, startY, startX;
+ int textX, textY, tw, th;
+
+ QString qs;
+};
+
+void RadialMap::Widget::paintExplodedLabels(QPainter &paint) const
+{
+ //we are a friend of RadialMap::Map
+
+ QVector<Label*> list;
+ unsigned int startLevel = 0;
+
+
+ //1. Create list of labels sorted in the order they will be rendered
+
+ if (m_focus && m_focus->file() != m_tree) { //separate behavior for selected vs unselected segments
+ //don't bother with files
+ if (m_focus && m_focus->file() && !m_focus->file()->isFolder()) {
+ return;
+ }
+
+ //find the range of levels we will be potentially drawing labels for
+ //startLevel is the level above whatever m_focus is in
+ for (const Folder *p = (const Folder*)m_focus->file(); p != m_tree; ++startLevel) {
+ p = p->parent();
+ }
+
+ //range=2 means 2 levels to draw labels for
+
+ const uint start = m_focus->start();
+ const uint end = m_focus->end(); //boundary angles
+ const uint minAngle = int(m_focus->length() * LABEL_MIN_ANGLE_FACTOR);
+
+
+ //**** Levels should be on a scale starting with 0
+ //**** range is a useless parameter
+ //**** keep a topblock var which is the lowestLevel OR startLevel for indentation purposes
+ for (unsigned int i = startLevel; i <= m_map.m_visibleDepth; ++i) {
+ for (const Segment *segment : m_map.m_signature[i]) {
+ if (segment->start() >= start && segment->end() <= end) {
+ if (segment->length() > minAngle) {
+ list.append(new Label(segment, i));
+ }
+ }
+ }
+ }
+ } else {
+ for (Segment *segment : *m_map.m_signature) {
+ if (segment->length() > 288) {
+ list.append(new Label(segment, 0));
+
+ }
+ }
+ }
+
+ std::sort(list.begin(), list.end(), [](Label *item1, Label *item2) {
+ //you add 1440 to work round the fact that later you want the circle split vertically
+ //and as it is you start at 3 o' clock. It's to do with rightPrevY, stops annoying bug
+
+ int angle1 = (item1)->angle + 1440;
+ int angle2 = (item2)->angle + 1440;
+
+ // Also sort by level
+ if (angle1 == angle2) {
+ return (item1->level > item2->level);
+ }
+
+ if (angle1 > 5760) angle1 -= 5760;
+ if (angle2 > 5760) angle2 -= 5760;
+
+ return (angle1 < angle2);
+
+ });
+
+ //2. Check to see if any adjacent labels are too close together
+ // if so, remove it (the least significant labels, since we sort by level too).
+
+ int pos = 0;
+ while (pos < list.size() - 1) {
+ if (list[pos]->tooClose(list[pos+1]->angle)) {
+ delete list.takeAt(pos+1);
+ } else {
+ ++pos;
+ }
+ }
+
+ //used in next two steps
+ bool varySizes;
+ //**** should perhaps use doubles
+ int *sizes = new int [ m_map.m_visibleDepth + 1 ]; //**** make sizes an array of floats I think instead (or doubles)
+
+ // If the minimum is larger than the default it fucks up further down
+ if (paint.font().pointSize() < 0 ||
+ paint.font().pointSize() < Config::minFontPitch) {
+ QFont font = paint.font();
+ font.setPointSize(Config::minFontPitch);
+ paint.setFont(font);
+ }
+
+ QVector<Label*>::iterator it;
+
+ do {
+ //3. Calculate font sizes
+
+ {
+ //determine current range of levels to draw for
+ uint range = 0;
+
+ for (Label *label : list) {
+ range = qMax(range, label->level);
+
+ //**** better way would just be to assign if nothing is range
+ }
+
+ range -= startLevel; //range 0 means 1 level of labels
+
+ varySizes = Config::varyLabelFontSizes && (range != 0);
+
+ if (varySizes) {
+ //create an array of font sizes for various levels
+ //will exceed normal font pitch automatically if necessary, but not minPitch
+ //**** this needs to be checked lots
+
+ //**** what if this is negative (min size gtr than default size)
+ uint step = (paint.font().pointSize() - Config::minFontPitch) / range;
+ if (step == 0) {
+ step = 1;
+ }
+
+ for (uint x = range + startLevel, y = Config::minFontPitch; x >= startLevel; y += step, --x) {
+ sizes[x] = y;
+ }
+ }
+ }
+
+ //4. determine label co-ordinates
+
+
+ const int preSpacer = int(m_map.m_ringBreadth * 0.5) + m_map.m_innerRadius;
+ const int fullStrutLength = (m_map.width() - m_map.MAP_2MARGIN) / 2 + LABEL_MAP_SPACER; //full length of a strut from map center
+
+ int prevLeftY = 0;
+ int prevRightY = height();
+
+ QFont font;
+
+ for (it = list.begin(); it != list.end(); ++it) {
+ Label *label = *it;
+ //** bear in mind that text is drawn with QPoint param as BOTTOM left corner of text box
+ QString string = label->segment->file()->displayName();
+ if (varySizes) {
+ font.setPointSize(sizes[label->level]);
+ }
+ QFontMetrics fontMetrics(font);
+ const int minTextWidth = fontMetrics.width(QString::fromLatin1("M...")) + LABEL_TEXT_HMARGIN; // Fully elided string
+
+ const int fontHeight = fontMetrics.height() + LABEL_TEXT_VMARGIN; //used to ensure label texts don't overlap
+ const int lineSpacing = fontHeight / 4;
+
+ const bool rightSide = (label->angle < 1440 || label->angle > 4320);
+
+ double sinra, cosra;
+ const double ra = M_PI/2880 * label->angle; //convert to radians
+ sincos(ra, &sinra, &cosra);
+
+
+ const int spacer = preSpacer + m_map.m_ringBreadth * label->level;
+
+ const int centerX = m_map.width() / 2 + m_offset.x(); //centre relative to canvas
+ const int centerY = m_map.height() / 2 + m_offset.y();
+ int targetX = centerX + cosra * spacer;
+ int targetY = centerY - sinra * spacer;
+ int startX = targetX + cosra * (fullStrutLength - spacer + m_map.m_ringBreadth / 2);
+ int startY = targetY - sinra * (fullStrutLength - spacer);
+
+ if (rightSide) { //righthand side, going upwards
+ if (startY > prevRightY /*- fmh*/) { //then it is too low, needs to be drawn higher
+ startY = prevRightY /*- fmh*/;
+ }
+ } else {//lefthand side, going downwards
+ if (startY < prevLeftY/* + fmh*/) { //then we're too high, need to be drawn lower
+ startY = prevLeftY /*+ fmh*/;
+ }
+ }
+
+ int middleX = targetX - (startY - targetY) / tan(ra);
+ int textY = startY + lineSpacing;
+
+ int textX;
+ const int textWidth = fontMetrics.width(string) + LABEL_TEXT_HMARGIN;
+ if (rightSide) {
+ if (startX + minTextWidth > width() || textY < fontHeight || middleX < targetX) {
+ //skip this strut
+ //**** don't duplicate this code
+ list.erase(it); //will delete the label and set it to list.current() which _should_ be the next ptr
+ break;
+ }
+
+ prevRightY = textY - fontHeight - lineSpacing; //must be after above's "continue"
+
+ if (m_offset.x() + m_map.width() + textWidth < width()) {
+ startX = m_offset.x() + m_map.width();
+ } else {
+ startX = qMax(width() - textWidth, startX);
+ string = fontMetrics.elidedText(string, Qt::ElideMiddle, width() - startX);
+ }
+
+ textX = startX + LABEL_TEXT_HMARGIN;
+ } else { // left side
+ if (startX - minTextWidth < 0 || textY > height() || middleX > targetX) {
+ //skip this strut
+ list.erase(it); //will delete the label and set it to list.current() which _should_ be the next ptr
+ break;
+ }
+
+ prevLeftY = textY + fontHeight - lineSpacing;
+
+ if (m_offset.x() - textWidth > 0) {
+ startX = m_offset.x();
+ textX = startX - textWidth - LABEL_TEXT_HMARGIN;
+ } else {
+ textX = 0;
+ string = fontMetrics.elidedText(string, Qt::ElideMiddle, startX);
+ startX = fontMetrics.width(string) + LABEL_TEXT_HMARGIN;
+ }
+ }
+
+ label->targetX = targetX;
+ label->targetY = targetY;
+ label->middleX = middleX;
+ label->startY = startY;
+ label->startX = startX;
+ label->textX = textX;
+ label->textY = textY;
+ label->qs = string;
+ }
+
+ //if an element is deleted at this stage, we need to do this whole
+ //iteration again, thus the following loop
+ //**** in rare case that deleted label was last label in top level
+ // and last in labelList too, this will not work as expected (not critical)
+
+ } while (it != list.end());
+
+
+ //5. Render labels
+
+ QFont font;
+ for (Label *label : list) {
+ if (varySizes) {
+ //**** how much overhead in making new QFont each time?
+ // (implicate sharing remember)
+ font.setPointSize(sizes[label->level]);
+ paint.setFont(font);
+ }
+
+ paint.drawLine(label->targetX, label->targetY, label->middleX, label->startY);
+ paint.drawLine(label->middleX, label->startY, label->startX, label->startY);
+
+ paint.drawText(label->textX, label->textY, label->qs);
+ }
+
+ qDeleteAll(list);
+ delete [] sizes;
+}
+}
+
diff --git a/test/radialmap/radialMap/map.cpp b/test/radialmap/radialMap/map.cpp
new file mode 100644
index 0000000..16d492b
--- /dev/null
+++ b/test/radialmap/radialMap/map.cpp
@@ -0,0 +1,413 @@
+/***********************************************************************
+* 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 <QApplication> //make()
+#include <QImage> //make() & paint()
+#include <QFont> //ctor
+#include <QFontMetrics> //ctor
+#include <QPainter>
+#include <QBrush>
+
+#include "radialMap.h" // defines
+
+#include "Config.h"
+#include "fileTree.h"
+#define SINCOS_H_IMPLEMENTATION (1)
+#include "sincos.h"
+#include "widget.h"
+
+RadialMap::Map::Map()
+ : m_signature(nullptr)
+ , m_visibleDepth(DEFAULT_RING_DEPTH)
+ , m_ringBreadth(MIN_RING_BREADTH)
+ , m_innerRadius(0)
+{
+
+ //FIXME this is all broken. No longer is a maximum depth!
+ const int fmh = QFontMetrics(QFont()).height();
+ const int fmhD4 = fmh / 4;
+ MAP_2MARGIN = 2 * (fmh - (fmhD4 - LABEL_MAP_SPACER)); //margin is dependent on fitting in labels at top and bottom
+
+ m_minSize=27300;
+}
+
+RadialMap::Map::~Map()
+{
+ delete [] m_signature;
+}
+
+void RadialMap::Map::invalidate()
+{
+ delete [] m_signature;
+ m_signature = nullptr;
+
+ m_visibleDepth = Config::defaultRingDepth;
+}
+
+void RadialMap::Map::make(const Folder *tree, bool refresh)
+{
+ if(height()<1)
+ abort();
+ //slow operation so set the wait cursor
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+
+ //build a signature of visible components
+ {
+ //**** REMOVE NEED FOR the +1 with MAX_RING_DEPTH uses
+ //**** add some angle bounds checking (possibly in Segment ctor? can I delete in a ctor?)
+ //**** this is a mess
+
+ delete [] m_signature;
+ m_signature = new QList<Segment*>[m_visibleDepth + 1];
+
+ m_root = tree;
+
+ if (!refresh) {
+ quint64 varSize=tree->size();
+ quint64 varHeight=height();
+ quint64 varA=(varSize * 3);
+ quint64 varB=(PI * varHeight - MAP_2MARGIN);
+ m_minSize = varA / varB;
+ findVisibleDepth(tree);
+ }
+
+ setRingBreadth();
+
+ // Calculate ring size limits
+ m_limits.resize(m_visibleDepth + 1);
+ const double size = m_root->size();
+ const double pi2B = M_PI * 4 * m_ringBreadth;
+ for (uint depth = 0; depth <= m_visibleDepth; ++depth) {
+ m_limits[depth] = uint(size / double(pi2B * (depth + 1))); //min is angle that gives 3px outer diameter for that depth
+ }
+
+ build(tree);
+ }
+
+ //colour the segments
+ colorise();
+
+ m_centerText = tree->humanReadableSize();
+
+ //paint the pixmap
+ paint();
+
+ QApplication::restoreOverrideCursor();
+}
+
+void RadialMap::Map::setRingBreadth()
+{
+ //FIXME called too many times on creation
+
+ m_ringBreadth = (height() - MAP_2MARGIN) / (2 * m_visibleDepth + 4);
+ m_ringBreadth = qBound(MIN_RING_BREADTH, m_ringBreadth, MAX_RING_BREADTH);
+}
+
+void RadialMap::Map::findVisibleDepth(const Folder *dir, uint currentDepth)
+{
+
+ //**** because I don't use the same minimumSize criteria as in the visual function
+ // this can lead to incorrect visual representation
+ //**** BUT, you can't set those limits until you know m_depth!
+
+ //**** also this function doesn't check to see if anything is actually visible
+ // it just assumes that when it reaches a new level everything in it is visible
+ // automatically. This isn't right especially as there might be no files in the
+ // dir provided to this function!
+
+ static uint stopDepth = 0;
+
+ if (dir == m_root) {
+ stopDepth = m_visibleDepth;
+ m_visibleDepth = 0;
+ }
+
+ if (m_visibleDepth < currentDepth) m_visibleDepth = currentDepth;
+ if (m_visibleDepth >= stopDepth) return;
+
+ for (File *file : dir->files) {
+ if (file->isFolder() && file->size() > m_minSize) {
+ findVisibleDepth((Folder *)file, currentDepth + 1); //if no files greater than min size the depth is still recorded
+ }
+ }
+}
+
+//**** segments currently overlap at edges (i.e. end of first is start of next)
+bool RadialMap::Map::build(const Folder * const dir, const uint depth, uint a_start, const uint a_end)
+{
+ //first iteration: dir == m_root
+
+ if (dir->children() == 0) //we do fileCount rather than size to avoid chance of divide by zero later
+ return false;
+
+ FileSize hiddenSize = 0;
+ uint hiddenFileCount = 0;
+
+ for (File *file : dir->files) {
+ if (file->size() < m_limits[depth] * 6) { // limit is half a degree? we want at least 3 degrees
+ hiddenSize += file->size();
+ if (file->isFolder()) { //**** considered virtual, but dir wouldn't count itself!
+ hiddenFileCount += static_cast<const Folder*>(file)->children(); //need to add one to count the dir as well
+ }
+ ++hiddenFileCount;
+ continue;
+ }
+
+ unsigned int a_len = (unsigned int)(5760 * ((double)file->size() / (double)m_root->size()));
+
+ Segment *s = new Segment(file, a_start, a_len);
+ m_signature[depth].append(s);
+
+ if (file->isFolder()) {
+ if (depth != m_visibleDepth) {
+ //recurse
+ s->m_hasHiddenChildren = build((Folder*)file, depth + 1, a_start, a_start + a_len);
+ } else {
+ s->m_hasHiddenChildren = true;
+ }
+ }
+
+ a_start += a_len; //**** should we add 1?
+ }
+
+ if (hiddenFileCount == dir->children() && !Config::showSmallFiles) {
+ return true;
+ }
+
+ if ((depth == 0 || Config::showSmallFiles) && hiddenSize >= m_limits[depth] && hiddenFileCount > 0) {
+ //append a segment for unrepresented space - a "fake" segment
+ const QString s = QObject::tr("1 file, with an average size of %2",
+ "%1 files, with an average size of %2").arg(hiddenFileCount)
+ .arg(QString::number(hiddenSize/hiddenFileCount));
+
+
+ (m_signature + depth)->append(new Segment(new File(s.toUtf8().constData(), hiddenSize), a_start, a_end - a_start, true));
+ }
+
+ return false;
+}
+
+bool RadialMap::Map::resize(const QRect &rect)
+{
+ //there's a MAP_2MARGIN border
+
+#define mw width()
+#define mh height()
+#define cw rect.width()
+#define ch rect.height()
+
+ if (cw < mw || ch < mh || (cw > mw && ch > mh))
+ {
+ uint size = ((cw < ch) ? cw : ch) - MAP_2MARGIN;
+
+ //this also causes uneven sizes to always resize when resizing but map is small in that dimension
+ //size -= size % 2; //even sizes mean less staggered non-antialiased resizing
+
+ {
+ const uint minSize = MIN_RING_BREADTH * 2 * (m_visibleDepth + 2);
+
+ if (size < minSize)
+ size = minSize;
+
+ //this QRect is used by paint()
+ m_rect.setRect(0,0,size,size);
+ }
+ m_pixmap = QPixmap(m_rect.size());
+
+ //resize the pixmap
+ size += MAP_2MARGIN;
+
+ if (m_signature != nullptr)
+ {
+ setRingBreadth();
+ paint();
+ }
+
+ return true;
+ }
+
+#undef mw
+#undef mh
+#undef cw
+#undef ch
+
+ return false;
+}
+
+void RadialMap::Map::colorise()
+{
+ if (!m_signature || m_signature->isEmpty()) {
+ qDebug() << "no signature yet";
+ return;
+ }
+
+ QColor cp, cb;
+ double darkness = 1;
+ double contrast = (double)Config::contrast / (double)100;
+ int h, s1, s2, v1, v2;
+
+ for (uint i = 0; i <= m_visibleDepth; ++i, darkness += 0.04) {
+ for (Segment *segment : m_signature[i]) {
+ h = int(segment->start() / 16);
+ s1 = 160;
+ v1 = (int)(255.0 / darkness); //doing this more often than once seems daft!
+
+ v2 = v1 - int(contrast * v1);
+ s2 = s1 + int(contrast * (255 - s1));
+
+ if (s1 < 80) s1 = 80; //can fall too low and makes contrast between the files hard to discern
+
+ if (segment->isFake()) { //multi-file
+ cb.setHsv(h, s2, (v2 < 90) ? 90 : v2); //too dark if < 100
+ cp.setHsv(h, 17, v1);
+ } else if (!segment->file()->isFolder()) { //file
+ cb.setHsv(h, 17, v1);
+ cp.setHsv(h, 17, v2);
+ } else { //folder
+ cb.setHsv(h, s1, v1); //v was 225
+ cp.setHsv(h, s2, v2); //v was 225 - delta
+ }
+
+ segment->setPalette(cp, cb);
+ }
+ }
+}
+
+void RadialMap::Map::paint(bool antialias)
+{
+ QPainter paint;
+ QRect rect = m_rect;
+
+ rect.adjust(5, 5, -5, -5);
+ m_pixmap.fill(QColor(255,255,255));
+
+ //m_rect.moveRight(1); // Uncommenting this breaks repainting when recreating map from cache
+
+
+ //**** best option you can think of is to make the circles slightly less perfect,
+ // ** i.e. slightly eliptic when resizing inbetween
+
+ if (m_pixmap.isNull())
+ return;
+
+ if (!paint.begin(&m_pixmap)) {
+ qWarning() << "Filelight::RadialMap Failed to initialize painting, returning...";
+ return;
+ }
+
+ if (antialias && Config::antialias) {
+ paint.translate(0.7, 0.7);
+ paint.setRenderHint(QPainter::Antialiasing);
+ }
+
+ int step = m_ringBreadth;
+ int excess = -1;
+
+ //do intelligent distribution of excess to prevent nasty resizing
+ if (m_ringBreadth != MAX_RING_BREADTH && m_ringBreadth != MIN_RING_BREADTH) {
+ excess = rect.width() % m_ringBreadth;
+ ++step;
+ }
+
+
+ for (int x = m_visibleDepth; x >= 0; --x)
+ {
+ int width = rect.width() / 2;
+ //clever geometric trick to find largest angle that will give biggest arrow head
+ uint a_max = int(acos((double)width / double((width + 5))) * (180*16 / M_PI));
+
+ for (Segment *segment : m_signature[x]) {
+ //draw the pie segments, most of this code is concerned with drawing the little
+ //arrows on the ends of segments when they have hidden files
+
+ paint.setPen(segment->pen());
+
+ if (segment->hasHiddenChildren())
+ {
+ //draw arrow head to indicate undisplayed files/directories
+ QPolygon pts(3);
+ QPoint pos, cpos = rect.center();
+ uint a[3] = { segment->start(), segment->length(), 0 };
+
+ a[2] = a[0] + (a[1] / 2); //assign to halfway between
+ if (a[1] > a_max)
+ {
+ a[1] = a_max;
+ a[0] = a[2] - a_max / 2;
+ }
+
+ a[1] += a[0];
+
+ for (int i = 0, radius = width; i < 3; ++i)
+ {
+ double ra = M_PI/(180*16) * a[i], sinra, cosra;
+
+ if (i == 2)
+ radius += 5;
+ sincos(ra, &sinra, &cosra);
+ pos.rx() = cpos.x() + static_cast<int>(cosra * radius);
+ pos.ry() = cpos.y() - static_cast<int>(sinra * radius);
+ pts.setPoint(i, pos);
+ }
+
+ paint.setBrush(segment->pen());
+ paint.drawPolygon(pts);
+ }
+
+ paint.setBrush(segment->brush());
+ paint.drawPie(rect, segment->start(), segment->length());
+
+ if (segment->hasHiddenChildren())
+ {
+ //**** code is bloated!
+ paint.save();
+ QPen pen = paint.pen();
+ int width = 2;
+ pen.setWidth(width);
+ paint.setPen(pen);
+ QRect rect2 = rect;
+ width /= 2;
+ rect2.adjust(width, width, -width, -width);
+ paint.drawArc(rect2, segment->start(), segment->length());
+ paint.restore();
+ }
+ }
+
+ if (excess >= 0) { //excess allows us to resize more smoothly (still crud tho)
+ if (excess < 2) //only decrease rect by more if even number of excesses left
+ --step;
+ excess -= 2;
+ }
+
+ rect.adjust(step, step, -step, -step);
+ }
+
+ // if(excess > 0) rect.addCoords(excess, excess, 0, 0); //ugly
+
+ paint.setPen(QColor(0,0,0));
+ paint.setBrush(QColor(255,255,255));
+ paint.drawEllipse(rect);
+ paint.drawText(rect, Qt::AlignCenter, m_centerText);
+
+ m_innerRadius = rect.width() / 2; //rect.width should be multiple of 2
+
+ paint.end();
+}
diff --git a/test/radialmap/radialMap/map.h b/test/radialmap/radialMap/map.h
new file mode 100644
index 0000000..da899b0
--- /dev/null
+++ b/test/radialmap/radialMap/map.h
@@ -0,0 +1,84 @@
+/***********************************************************************
+* 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/>.
+***********************************************************************/
+
+#ifndef MAP_H
+#define MAP_H
+
+#include "fileTree.h"
+
+#include <QPixmap>
+#include <QRect>
+#include <QString>
+
+namespace RadialMap {
+class Segment;
+
+class Map
+{
+public:
+ explicit Map();
+ ~Map();
+
+ void make(const Folder *, bool = false);
+ bool resize(const QRect&);
+
+ bool isNull() const {
+ return (m_signature == nullptr);
+ }
+ void invalidate();
+
+ int height() const {
+ return m_rect.height();
+ }
+ int width() const {
+ return m_rect.width();
+ }
+ QPixmap pixmap() const {
+ return m_pixmap;
+ }
+
+
+ friend class Widget;
+
+private:
+ void paint(bool antialias = true);
+ void colorise();
+ void setRingBreadth();
+ void findVisibleDepth(const Folder *dir, uint currentDepth = 0);
+ bool build(const Folder* const dir, const uint depth =0, uint a_start =0, const uint a_end =5760);
+
+ QList<Segment*> *m_signature;
+
+ const Folder *m_root;
+ uint m_minSize;
+ QVector<FileSize> m_limits;
+ QRect m_rect;
+ uint m_visibleDepth; ///visible level depth of system
+ QPixmap m_pixmap;
+ int m_ringBreadth;
+ uint m_innerRadius; ///radius of inner circle
+ QString m_centerText;
+
+ uint MAP_2MARGIN;
+};
+}
+
+#endif
diff --git a/test/radialmap/radialMap/radialMap.h b/test/radialmap/radialMap/radialMap.h
new file mode 100644
index 0000000..5bbba10
--- /dev/null
+++ b/test/radialmap/radialMap/radialMap.h
@@ -0,0 +1,109 @@
+/***********************************************************************
+* 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/>.
+***********************************************************************/
+
+#ifndef RADIALMAP_H
+#define RADIALMAP_H
+
+#include <QColor>
+
+class File;
+
+namespace RadialMap
+{
+class Segment //all angles are in 16ths of degrees
+{
+public:
+ Segment(const File *f, uint s, uint l, bool isFake = false)
+ : m_angleStart(s)
+ , m_angleSegment(l)
+ , m_file(f)
+ , m_hasHiddenChildren(false)
+ , m_fake(isFake) {}
+ ~Segment();
+
+ uint start() const {
+ return m_angleStart;
+ }
+ uint length() const {
+ return m_angleSegment;
+ }
+ uint end() const {
+ return m_angleStart + m_angleSegment;
+ }
+ const File *file() const {
+ return m_file;
+ }
+ const QColor& pen() const {
+ return m_pen;
+ }
+ const QColor& brush() const {
+ return m_brush;
+ }
+
+ bool isFake() const {
+ return m_fake;
+ }
+ bool hasHiddenChildren() const {
+ return m_hasHiddenChildren;
+ }
+
+ bool intersects(uint a) const {
+ return ((a >= start()) && (a < end()));
+ }
+
+ friend class Map;
+ friend class Builder;
+
+private:
+ void setPalette(const QColor &p, const QColor &b) {
+ m_pen = p;
+ m_brush = b;
+ }
+
+ const uint m_angleStart, m_angleSegment;
+ const File* const m_file;
+ QColor m_pen, m_brush;
+ bool m_hasHiddenChildren;
+ const bool m_fake;
+};
+}
+
+
+#ifndef PI
+#define PI 3.141592653589793
+#endif
+#ifndef M_PI
+#define M_PI 3.14159265358979323846264338327
+#endif
+
+#define MIN_RING_BREADTH 20
+#define MAX_RING_BREADTH 60
+#define DEFAULT_RING_DEPTH 4 //first level = 0
+#define MIN_RING_DEPTH 0
+
+#define LABEL_MAP_SPACER 7
+#define LABEL_TEXT_HMARGIN 5
+#define LABEL_TEXT_VMARGIN 0
+#define LABEL_ANGLE_MARGIN 32
+#define LABEL_MIN_ANGLE_FACTOR 0.05
+#define LABEL_MAX_CHARS 30
+
+#endif
diff --git a/test/radialmap/radialMap/sincos.h b/test/radialmap/radialMap/sincos.h
new file mode 100644
index 0000000..2fe716d
--- /dev/null
+++ b/test/radialmap/radialMap/sincos.h
@@ -0,0 +1,45 @@
+/***********************************************************************
+* 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/>.
+***********************************************************************/
+
+#ifndef SINCOS_H
+#define SINCOS_H
+
+#include <math.h>
+
+#if !defined(__GLIBC__) || (__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1)
+
+#include <qmath.h>
+
+void
+sincos(double angleRadians, double *Sin, double *Cos);
+
+#ifdef SINCOS_H_IMPLEMENTATION
+void
+sincos(double angleRadians, double *Sin, double *Cos)
+{
+ *Sin = qSin(angleRadians);
+ *Cos = qCos(angleRadians);
+}
+#endif
+
+#endif
+
+#endif
diff --git a/test/radialmap/radialMap/widget.cpp b/test/radialmap/radialMap/widget.cpp
new file mode 100644
index 0000000..145de20
--- /dev/null
+++ b/test/radialmap/radialMap/widget.cpp
@@ -0,0 +1,191 @@
+/***********************************************************************
+* 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 "widget.h"
+
+#include "Config.h"
+#include "fileTree.h"
+#include "radialMap.h" //constants
+#include "map.h"
+
+#include <QUrl>
+
+#include <QApplication> //sendEvent
+#include <QBitmap> //ctor - finding cursor size
+#include <QCursor> //slotPostMouseEvent()
+#include <QTimer> //member
+#include <QWidget>
+
+
+RadialMap::Widget::Widget(QWidget *parent)
+ : QWidget(parent)
+ , m_tree(nullptr)
+ , m_focus(nullptr)
+ , m_map()
+ , m_rootSegment(nullptr) //TODO we don't delete it, *shrug*
+ , m_toBeDeleted(nullptr)
+{
+ setAcceptDrops(true);
+ setMinimumSize(350, 250);
+
+ connect(this, &Widget::folderCreated, this, &Widget::sendFakeMouseEvent);
+ connect(&m_timer, &QTimer::timeout, this, &Widget::resizeTimeout);
+ m_tooltip.setFrameShape(QFrame::StyledPanel);
+ m_tooltip.setWindowFlags(Qt::ToolTip | Qt::WindowTransparentForInput);
+}
+
+RadialMap::Widget::~Widget()
+{
+ delete m_rootSegment;
+}
+
+
+QString RadialMap::Widget::path() const
+{
+ return m_tree->displayPath();
+}
+
+QUrl RadialMap::Widget::url(File const * const file) const
+{
+ return file ? file->url() : m_tree->url();
+}
+
+void RadialMap::Widget::invalidate()
+{
+ if (isValid())
+ {
+ //**** have to check that only way to invalidate is this function frankly
+ //**** otherwise you may get bugs..
+
+ //disable mouse tracking
+ setMouseTracking(false);
+
+ // Get this before reseting m_tree below
+ QUrl invalidatedUrl(url());
+
+ //ensure this class won't think we have a map still
+ m_tree = nullptr;
+ m_focus = nullptr;
+
+ delete m_rootSegment;
+ m_rootSegment = nullptr;
+
+ //FIXME move this disablement thing no?
+ // it is confusing in other areas, like the whole createFromCache() thing
+ m_map.invalidate();
+ update();
+
+ //tell rest of Filelight
+ emit invalidated(invalidatedUrl);
+ }
+}
+
+void
+RadialMap::Widget::create(const Folder *tree)
+{
+ //it is not the responsibility of create() to invalidate first
+ //skip invalidation at your own risk
+
+ //FIXME make it the responsibility of create to invalidate first
+
+ if (tree)
+ {
+ m_focus = nullptr;
+ //generate the filemap image
+ m_map.make(tree);
+
+ //this is the inner circle in the center
+ m_rootSegment = new Segment(tree, 0, 16*360);
+
+ setMouseTracking(true);
+ }
+
+ m_tree = tree;
+
+ //tell rest of Filelight
+ emit folderCreated(tree);
+}
+
+void
+RadialMap::Widget::createFromCache(const Folder *tree)
+{
+ //no scan was necessary, use cached tree, however we MUST still emit invalidate
+ invalidate();
+ create(tree);
+}
+
+void
+RadialMap::Widget::sendFakeMouseEvent() //slot
+{
+ QMouseEvent me(QEvent::MouseMove, mapFromGlobal(QCursor::pos()), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
+ QApplication::sendEvent(this, &me);
+ update();
+}
+
+void
+RadialMap::Widget::resizeTimeout() //slot
+{
+ // the segments are about to erased!
+ // this was a horrid bug, and proves the OO programming should be obeyed always!
+ m_focus = nullptr;
+ if (m_tree)
+ m_map.make(m_tree, true);
+ update();
+}
+
+void
+RadialMap::Widget::refresh(int filth)
+{
+ //TODO consider a more direct connection
+
+ if (!m_map.isNull())
+ {
+ switch (filth)
+ {
+ case 1:
+ m_focus=nullptr;
+ m_map.make(m_tree, true); //true means refresh only
+ break;
+
+ case 2:
+ m_map.paint(true); //antialiased painting
+ break;
+
+ case 3:
+ m_map.colorise(); //FALL THROUGH!
+ case 4:
+ m_map.paint();
+
+ default:
+ break;
+ }
+
+ update();
+ }
+}
+
+RadialMap::Segment::~Segment()
+{
+ if (isFake())
+ delete m_file; //created by us in Builder::build()
+}
+
+
diff --git a/test/radialmap/radialMap/widget.h b/test/radialmap/radialMap/widget.h
new file mode 100644
index 0000000..35d1f1d
--- /dev/null
+++ b/test/radialmap/radialMap/widget.h
@@ -0,0 +1,112 @@
+/***********************************************************************
+* 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/>.
+***********************************************************************/
+
+#ifndef WIDGET_H
+#define WIDGET_H
+
+#include <QUrl>
+
+#include <QLabel>
+#include <QDragEnterEvent>
+#include <QDropEvent>
+#include <QMouseEvent>
+#include <QPaintEvent>
+#include <QResizeEvent>
+#include <QWidget>
+#include <QTimer>
+
+#include "map.h"
+
+class Folder;
+class File;
+namespace KIO {
+class Job;
+}
+
+namespace RadialMap
+{
+class Segment;
+
+class Widget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit Widget(QWidget* = nullptr);
+ ~Widget() override;
+ QString path() const;
+ QUrl url(File const * const = nullptr) const;
+
+ bool isValid() const {
+ return m_tree != nullptr;
+ }
+
+ friend class Label; //FIXME badness
+
+public Q_SLOTS:
+ void create(const Folder*);
+ void invalidate();
+ void refresh(int);
+
+private Q_SLOTS:
+ void resizeTimeout();
+ void sendFakeMouseEvent();
+ void createFromCache(const Folder*);
+
+Q_SIGNALS:
+ void activated(const QUrl&);
+ void invalidated(const QUrl&);
+ void folderCreated(const Folder*);
+ void mouseHover(const QString&);
+ void giveMeTreeFor(const QUrl&);
+
+protected:
+ void changeEvent(QEvent*) override;
+ void mouseMoveEvent(QMouseEvent*) override;
+ void paintEvent(QPaintEvent*) override;
+ void resizeEvent(QResizeEvent*) override;
+ void enterEvent(QEvent*) override;
+ void leaveEvent(QEvent*) override;
+
+protected:
+ const Segment *segmentAt(QPoint&) const; //FIXME const reference for a library others can use
+ const Segment *rootSegment() const {
+ return m_rootSegment; ///never == 0
+ }
+ const Segment *focusSegment() const {
+ return m_focus; ///0 == nothing in focus
+ }
+
+private:
+ void paintExplodedLabels(QPainter&) const;
+
+ const Folder *m_tree;
+ const Segment *m_focus;
+ QPoint m_offset;
+ QTimer m_timer;
+ Map m_map;
+ Segment *m_rootSegment;
+ const Segment *m_toBeDeleted;
+ QLabel m_tooltip;
+};
+}
+
+#endif
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();
+}
diff --git a/test/radialmap/radialmap.pro b/test/radialmap/radialmap.pro
new file mode 100644
index 0000000..0a560ab
--- /dev/null
+++ b/test/radialmap/radialmap.pro
@@ -0,0 +1,46 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2019-05-30T12:37:58
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = radialmap
+TEMPLATE = app
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+
+SOURCES += \
+ main.cpp \
+ MainWindow.cpp \
+ radialMap/labels.cpp \
+ radialMap/map.cpp \
+ radialMap/widgetEvents.cpp \
+ radialMap/widget.cpp \
+ fileTree.cpp \
+ Config.cpp
+
+HEADERS += \
+ MainWindow.h \
+ radialMap/map.h \
+ radialMap/widget.h \
+ radialMap/radialMap.h \
+ radialMap/sincos.h \
+ fileTree.h \
+ Config.h
+
+FORMS += \
+ MainWindow.ui