+#include "scrollareacustom.h"
+
+class HistoryPage : public TabPage
+{
+ Q_OBJECT
+
+private:
+ ScrollAreaCustom* scrollArea;
+
+public:
+ HistoryPage(QWidget* parent = nullptr);
+
+private slots:
+ void AddHistory(const QString & expStr, const QString & expStrHtml, const QString & resStrHtml);
+};
+
+#endif // HISTORYPAGE_H
diff --git a/infopage.cpp b/infopage.cpp
new file mode 100644
index 0000000..a0fb575
--- /dev/null
+++ b/infopage.cpp
@@ -0,0 +1,28 @@
+#include "infopage.h"
+
+InfoPage::InfoPage(QWidget* parent) : TabPage(parent)
+{
+ QVBoxLayout* mainLayout = new QVBoxLayout;
+ mainLayout->setContentsMargins(0, 0, 0, 0);
+ this->setLayout(mainLayout);
+ mainLayout->setAlignment(Qt::AlignCenter);
+ QTextBrowser* InfoBrowser = new QTextBrowser(this);
+ InfoBrowser->setHtml("\
+ About This Application:\
+
\
+\
+ Author: Jonathan Zhang ( Linloir ) \
+
\
+\
+ Version: 1.0\
+
\
+\
+ GitHub: https://github.com/Linloir\
+
\
+\
+
\
+
");
+ InfoBrowser->setStyleSheet("background:transparent;border-width:0;border-style:outset");
+ InfoBrowser->setOpenExternalLinks(true);
+ mainLayout->addWidget(InfoBrowser);
+}
diff --git a/infopage.h b/infopage.h
new file mode 100644
index 0000000..e94b1b8
--- /dev/null
+++ b/infopage.h
@@ -0,0 +1,17 @@
+#ifndef INFOPAGE_H
+#define INFOPAGE_H
+
+#include "tabpage.h"
+#include
+#include
+#include
+#include
+
+class InfoPage : public TabPage
+{
+ Q_OBJECT
+public:
+ InfoPage(QWidget* parent = nullptr);
+};
+
+#endif // INFOPAGE_H
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..a7542aa
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,15 @@
+#include "acrylic.h"
+
+#include
+
+HashMap opMap;
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+ Acrylic w;
+ w.setWindowFlags(Qt::FramelessWindowHint);
+ w.setAttribute(Qt::WA_TranslucentBackground);
+ w.show();
+ return a.exec();
+}
diff --git a/qtransparentbutton.cpp b/qtransparentbutton.cpp
new file mode 100644
index 0000000..ef240f3
--- /dev/null
+++ b/qtransparentbutton.cpp
@@ -0,0 +1,62 @@
+#include "qtransparentbutton.h"
+
+QTransparentButton::QTransparentButton(QWidget* parent) : QPushButton(parent)
+{
+ bgColor = bgColor_default;
+ buttonText = this->text();
+}
+
+void QTransparentButton::paintEvent(QPaintEvent *event){
+ QPainter bgPainter(this);
+ bgPainter.setPen(Qt::NoPen);
+ bgPainter.setBrush(bgColor);
+ bgPainter.drawRect(this->rect());
+ buttonText = this->text();
+
+
+ //QPainter test(this);
+ //test.setPen(Qt::SolidLine);
+ //test.setBrush(Qt::NoBrush);
+
+ QPainter textPainter(this);
+ QFont textFont("FuturaNo2D", 14);
+ textPainter.setFont(textFont);
+ int widthOfText = textPainter.fontMetrics().size(Qt::TextSingleLine, buttonText).width();
+ int heightOfText = textPainter.fontMetrics().ascent() - textPainter.fontMetrics().descent() + textPainter.fontMetrics().leading();
+ //test.drawRect(this->width() / 2 - widthOfText / 2, this->height() / 2 - heightOfText / 2, widthOfText, heightOfText);
+ textPainter.drawText(this->width() / 2 - widthOfText / 2, this->height() / 2 + heightOfText / 2, buttonText);
+}
+
+void QTransparentButton::enterEvent(QEnterEvent *event){
+ bgColor = bgColor_Hover;
+ update();
+}
+
+void QTransparentButton::leaveEvent(QEvent *event){
+ bgColor = bgColor_default;
+ update();
+}
+
+void QTransparentButton::mousePressEvent(QMouseEvent *event){
+ emit clicked();
+ bgColor = bgColor_Clicked;
+ update();
+}
+
+void QTransparentButton::mouseReleaseEvent(QMouseEvent *event){
+ bgColor = bgColor_Hover;
+ update();
+}
+
+void QTransparentButton::setColor(QColor c){
+ bgColor_default = c;
+ bgColor = bgColor_default;
+}
+
+void QTransparentButton::setHoverColor(QColor c){
+ bgColor_Hover = c;
+}
+
+void QTransparentButton::setClickedColor(QColor c){
+ bgColor_Clicked = c;
+}
diff --git a/qtransparentbutton.h b/qtransparentbutton.h
new file mode 100644
index 0000000..c66cc54
--- /dev/null
+++ b/qtransparentbutton.h
@@ -0,0 +1,35 @@
+#ifndef QTRANSPARENTBUTTON_H
+#define QTRANSPARENTBUTTON_H
+
+#include
+#include
+#include
+#include
+#include
+
+class QTransparentButton : public QPushButton
+{
+ Q_OBJECT
+
+protected:
+ void paintEvent(QPaintEvent* event);
+ void enterEvent(QEnterEvent *event);
+ void leaveEvent(QEvent* event);
+ void mousePressEvent(QMouseEvent* event);
+ void mouseReleaseEvent(QMouseEvent* event);
+
+private:
+ QString buttonText;
+ QColor bgColor;
+ QColor bgColor_default = QColor(255, 255, 255, 220);
+ QColor bgColor_Hover = QColor(190, 190, 190, 70);
+ QColor bgColor_Clicked = QColor(170, 170, 170, 70);
+
+public:
+ QTransparentButton(QWidget* parent = nullptr);
+ void setColor(QColor c);
+ void setClickedColor(QColor c);
+ void setHoverColor(QColor c);
+};
+
+#endif // QTRANSPARENTBUTTON_H
diff --git a/scrollareacustom.cpp b/scrollareacustom.cpp
new file mode 100644
index 0000000..19a2591
--- /dev/null
+++ b/scrollareacustom.cpp
@@ -0,0 +1,244 @@
+#include "scrollareacustom.h"
+
+ScrollAreaCustom::ScrollAreaCustom(QWidget *parent) : QWidget(parent)
+{
+ //initialize list container and timer
+ container = new ScrollListContainer(this);
+ container->move(0, 0);
+ container->resize(this->width(), 3);
+ //container->setMinimumWidth(this->width());
+ //container->setMaximumWidth(this->width());
+ getCord = new QTimer;
+ getCord->setSingleShot(true);
+ rfrshView = new QTimer;
+ getCord->setSingleShot(true);
+
+ indicator = new ScrollIndicator(this);
+ indicator->resize(indicator->width(), (int)((double)this->height() * this->height() / (double)container->height()));
+ indicator->move(this->width() - indicator->width() - 3, 0);
+
+ this->setMouseTracking(true);
+ container->setMouseTracking(true);
+ indicator->setMouseTracking(true);
+
+ bounce = new QPropertyAnimation(container, "pos");
+
+ QObject::connect(getCord, SIGNAL(timeout()), this, SLOT(updateSpd()));
+ QObject::connect(rfrshView, SIGNAL(timeout()), this, SLOT(scrollContainer()));
+ QObject::connect(indicator, SIGNAL(scrollPage(int)), this, SLOT(scrollIndicator(int)));
+}
+
+void ScrollAreaCustom::paintEvent(QPaintEvent *event){
+ //keep container the same size as parent widget
+ //qDebug() << "scrollAreaWidth:[" << this->x() << "," << this->y() << "," << this->width() << "," << this->height() << "]\n";
+ //qDebug() << "containerWidth:[" << container->x() << "," << container->y() << "," << container->width() << "," << container->height() << "]\n";
+ //qDebug() << "speed:" << curSpd << "\n";
+ //container->setMinimumWidth(this->width());
+ //container->setMaximumWidth(this->width());
+ container->resize(this->width(), container->height());
+ if(container->height() > this->height() && container->y() < this->height() - container->height() && curSpd == 0 && bounce->state() == QAbstractAnimation::Stopped)
+ container->move(container->x(), this->height() - container->height());
+ if(container->height() <= this->height()){
+ container->move(container->x(), 0);
+ indicator->hide();
+ }
+ else{
+ indicator->show();
+ }
+ indicator->resize(indicator->width(), (int)((double)this->height() * this->height() / (double)container->height()));
+ indicator->move(this->width() - indicator->width() - 3, -container->y() * this->height() / container->height());
+}
+
+void ScrollAreaCustom::mousePressEvent(QMouseEvent *event){
+ if(container->height() > this->height()){
+ if(container->y() <= 0 && container->y() + container->height() >= this->height())
+ pressed = true;
+ lastY = event->pos().y();
+ }
+ getCord->stop();
+ rfrshView->stop();
+ curSpd = 0;
+ outOfEdge = false;
+ moveStored = 0;
+ nextMove = 1;
+}
+
+void ScrollAreaCustom::mouseMoveEvent(QMouseEvent *event){
+ setCursor(Qt::ArrowCursor);
+ if(pressed){
+ //qDebug() << "move\n";
+ //start scroll
+ if(!getCord->isActive() && event->pos().y() - lastY != 0){
+ //start 30ms timer
+ //qDebug() << "timer Start\n";
+ getCord->start(30);
+ strtY = event->pos().y();
+ }
+ if(container->y() <= 0 && container->y() + container->height() >= this->height()){
+ //qDebug() << "in\n" ;
+ container->move(container->x(), container->y() + event->pos().y() - lastY);
+ //qDebug() << -container->y() * this->height() / container->height() << "\n";
+ }
+ else{
+ //qDebug() << "outOfEdge\n";
+ //qDebug() << event->pos().y() << "\n";
+ //qDebug() << "nextMove:" << nextMove << "Stored: " << moveStored << "\n";
+ if(!outOfEdge){
+ bfEdgeY = event->pos().y();
+ container->move(container->x(), container->y() + event->pos().y() - lastY);
+ outOfEdge = true;
+ }
+ else{
+ //qDebug() << "Damp\n" << "bfEdgeY: " << bfEdgeY << "\n";
+ int pos = container->y() >= 0 ? 1 : -1;
+ //qDebug() << "pos:" << pos << "\n";
+ int dp = event->pos().y() - bfEdgeY;
+ if(dp == 0){
+ outOfEdge = false;
+ nextMove = 1;
+ moveStored = 0;
+ if(container->y() >= 0)
+ container->move(container->x(), 0);
+ else
+ container->move(container->x(), this->height() - container->height());
+ }
+ else if(dp / abs(dp) != pos){
+ //qDebug() << "X";
+ outOfEdge = false;
+
+ container->move(container->x(), this->y() + event->pos().y() - bfEdgeY);
+ nextMove = 1;
+ moveStored = 0;
+ }
+ else{
+ while(abs(moveStored) + nextMove <= abs(event->pos().y() - bfEdgeY)){
+ //qDebug() << "add\n";
+ moveStored += nextMove * pos;
+ container->move(container->x(), container->y() + pos);
+ nextMove++;
+ }
+ while(nextMove > 1 && abs(moveStored) > abs(event->pos().y() - bfEdgeY)){
+ //qDebug() << "dec\n";
+ nextMove--;
+ moveStored -= nextMove * pos;
+ container->move(container->x(), container->y() - pos);
+ }
+ if(moveStored == 0){
+ outOfEdge = false;
+ if(container->y() >= 0)
+ container->move(container->x(), 0);
+ else
+ container->move(container->x(), this->height() - container->height());
+ nextMove = 1;
+ moveStored = 0;
+ }
+ }
+ }
+ }
+ lastY = event->pos().y();
+ }
+}
+
+void ScrollAreaCustom::mouseReleaseEvent(QMouseEvent *event){
+ //start scrolling
+ //qDebug() << "mouseRelease\n";
+ if(container->y() > 0 || container->y() + container->height() < this->height())
+ bounceBack();
+ else
+ rfrshView->start(30);
+ pressed = false;
+}
+
+void ScrollAreaCustom::bounceBack(){
+ rfrshView->stop();
+ getCord->stop();
+ bounce->setDuration(500);
+ bounce->setStartValue(container->pos());
+ if(container->y() > 0)
+ bounce->setEndValue(QPoint(container->x(), 0));
+ else
+ bounce->setEndValue(QPoint(container->x(), this->height() - container->height()));
+ bounce->setEasingCurve(QEasingCurve::OutQuad);
+ bounce->start();
+}
+
+void ScrollAreaCustom::scrollContainer(){
+ //scroll
+ if(curSpd > 0){
+ if(curSpd > MAXSPEED)
+ curSpd = MAXSPEED;
+ int dp = scrollDown ? curSpd : -curSpd;
+ container->move(container->x(), container->y() + dp);
+ }
+ else
+ return;
+ if(container->y() <= 0 && container->y() + container->height() >= this->height()){
+ curSpd -= damp;
+ curSpd = curSpd < 0 ? 0 : curSpd;
+ }
+ else
+ curSpd /= 2;
+ if(curSpd == 0 && (container->y() > 0 || container->y() + container->height() < this->height()))
+ bounceBack();
+ else
+ rfrshView->start(30);
+
+ //qDebug() << "spd2:" << curSpd << "\n";
+}
+
+void ScrollAreaCustom::updateSpd(){
+ int spd = lastY - strtY;
+ //qDebug() << "spd:" << spd << "\n";
+ scrollDown = spd >= 0;
+ strtY = lastY;
+ curSpd = abs(spd);
+}
+
+void ScrollAreaCustom::addWidget(QWidget *newWidget){
+ newWidget->setParent(container);
+ container->AddWidget(newWidget);
+}
+
+void ScrollAreaCustom::removeWidget(QWidget *w){
+ //container->layout()->removeWidget(w);
+
+ //qDebug() << "good\n";
+ container->RemoveWidget(w);
+}
+
+void ScrollAreaCustom::clear(){
+ container->clear();
+}
+
+void ScrollAreaCustom::scrollIndicator(int dp){
+ //qDebug() << "dp=" << dp << "\n";
+ int newY = container->y() - dp * container->height() / this->height();
+ if(newY > 0)
+ newY = 0;
+ else if(newY < this->height() - container->height())
+ newY = this->height() - container->height();
+ container->move(container->x(), newY);
+ update();
+}
+
+void ScrollAreaCustom::wheelEvent(QWheelEvent *event){
+ //qDebug() << "wheel" << event->angleDelta().y() * 100 / 360 << "\n";
+ //int newY = container->y() + event->angleDelta().y() * 100 / 360 * container->height() / this->height();
+ //if(newY > 0)
+ // newY = 0;
+ //else if(newY < this->height() - container->height())
+ // newY = this->height() - container->height();
+ //container->move(container->x(), newY);
+ if(container->y() > 0 || container->y() + container->height() < this->height())
+ return;
+ curSpd += 5;
+ bool newDirection = event->angleDelta().y() > 0;
+ if(newDirection != scrollDown)
+ curSpd = 5;
+ if(curSpd > MAXSPEED)
+ curSpd = MAXSPEED;
+ scrollDown = newDirection;
+ if(!rfrshView->isActive())
+ rfrshView->start(30);
+ update();
+}
diff --git a/scrollareacustom.h b/scrollareacustom.h
new file mode 100644
index 0000000..1570588
--- /dev/null
+++ b/scrollareacustom.h
@@ -0,0 +1,68 @@
+#ifndef SCROLLAREACUSTOM_H
+#define SCROLLAREACUSTOM_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "scrolllistcontainer.h"
+#include "scrollindicator.h"
+#include
+#include
+
+#define MAXSPEED 50
+
+class ScrollAreaCustom : public QWidget
+{
+ Q_OBJECT
+
+private:
+ QTimer* getCord;
+ QTimer* rfrshView;
+
+ ScrollListContainer* container;
+ ScrollIndicator* indicator;
+
+ QPropertyAnimation* bounce;
+
+ bool pressed = false;
+ bool scrollDown = true;
+ bool outOfEdge = false;
+
+ int strtY;
+ int lastY;
+ int bfEdgeY; //last y value before out of edge
+
+ int curSpd = 0;
+ int damp = 1;
+ int moveStored = 0;
+ int nextMove = 1;
+
+ void paintEvent(QPaintEvent* event);
+ void mousePressEvent(QMouseEvent* event);
+ void mouseMoveEvent(QMouseEvent* event);
+ void mouseReleaseEvent(QMouseEvent* event);
+ void wheelEvent(QWheelEvent* event);
+ void bounceBack();
+
+
+public:
+ explicit ScrollAreaCustom(QWidget *parent = nullptr);
+ void addWidget(QWidget* newWidget);
+ void removeWidget(QWidget* w = nullptr);
+ void clear();
+
+signals:
+
+private slots:
+ void scrollContainer();
+ void updateSpd();
+ void scrollIndicator(int dp);
+
+};
+
+#endif // SCROLLAREACUSTOM_H
diff --git a/scrollcontainer.cpp b/scrollcontainer.cpp
new file mode 100644
index 0000000..45fdbbf
--- /dev/null
+++ b/scrollcontainer.cpp
@@ -0,0 +1,6 @@
+#include "scrollcontainer.h"
+
+ScrollContainer::ScrollContainer(QWidget *parent) : QWidget(parent)
+{
+
+}
diff --git a/scrollcontainer.h b/scrollcontainer.h
new file mode 100644
index 0000000..b7f1b77
--- /dev/null
+++ b/scrollcontainer.h
@@ -0,0 +1,17 @@
+#ifndef SCROLLCONTAINER_H
+#define SCROLLCONTAINER_H
+
+#include
+#include
+#include
+
+class ScrollContainer : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit ScrollContainer(QWidget *parent = nullptr);
+signals:
+
+};
+
+#endif // SCROLLCONTAINER_H
diff --git a/scrollindicator.cpp b/scrollindicator.cpp
new file mode 100644
index 0000000..6e4b55b
--- /dev/null
+++ b/scrollindicator.cpp
@@ -0,0 +1,76 @@
+#include "scrollindicator.h"
+
+ScrollIndicator::ScrollIndicator(QWidget *parent) : QWidget(parent)
+{
+ this->resize(defaultWidth, 0);
+ hovTimer = new QTimer(this);
+ hovTimer->setSingleShot(true);
+ aniPause = new QTimer(this);
+ aniPause->setSingleShot(true);
+ QObject::connect(hovTimer, SIGNAL(timeout()), this, SLOT(setHoverActive()));
+ this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ this->curColor = defaultColor;
+
+ this->setMouseTracking(true);
+}
+
+void ScrollIndicator::paintEvent(QPaintEvent *event){
+ QPainter painter(this);
+ painter.setPen(Qt::NoPen);
+ painter.setBrush(curColor);
+ painter.drawRect(this->rect());
+}
+
+void ScrollIndicator::enterEvent(QEnterEvent *event){
+ if(!pressed){
+ hovTimer->start(100);
+ curColor = hoverColor;
+ update();
+ }
+}
+
+void ScrollIndicator::leaveEvent(QEvent *event){
+ //qDebug() << "leave";
+ hovTimer->stop();
+ curColor = defaultColor;
+ QPropertyAnimation* narrow = new QPropertyAnimation(this, "geometry");
+ narrow->setDuration(300);
+ narrow->setStartValue(QRect(this->x(), this->y(), this->width(), this->height()));
+ narrow->setEndValue(QRect(this->parentWidget()->width() - margin - defaultWidth, this->y(), defaultWidth, this->height()));
+ narrow->setEasingCurve(QEasingCurve::InOutQuad);
+ narrow->start(QAbstractAnimation::DeleteWhenStopped);
+ aniPause->start(300);
+ update();
+}
+
+void ScrollIndicator::mousePressEvent(QMouseEvent *event){
+ //qDebug() << "press\n";
+ curColor = pressColor;
+ pressed = true;
+ lastY = event->globalPos().y();
+ update();
+}
+
+void ScrollIndicator::mouseMoveEvent(QMouseEvent *event){
+ if(pressed && !aniPause->isActive()){
+ int dp = event->globalPos().y() - lastY;
+ emit scrollPage(dp);
+ lastY = event->globalPos().y();
+ }
+}
+
+void ScrollIndicator::mouseReleaseEvent(QMouseEvent *event){
+ pressed = false;
+ curColor = hoverColor;
+ update();
+}
+
+void ScrollIndicator::setHoverActive(){
+ QPropertyAnimation* widen = new QPropertyAnimation(this, "geometry");
+ widen->setDuration(300);
+ widen->setStartValue(QRect(this->x(), this->y(), this->width(), this->height()));
+ widen->setEndValue(QRect(this->parentWidget()->width() - margin - defaultWidthAtFocus, this->y(), defaultWidthAtFocus, this->height()));
+ widen->setEasingCurve(QEasingCurve::InOutQuad);
+ widen->start(QAbstractAnimation::DeleteWhenStopped);
+ aniPause->start(300);
+}
diff --git a/scrollindicator.h b/scrollindicator.h
new file mode 100644
index 0000000..512a096
--- /dev/null
+++ b/scrollindicator.h
@@ -0,0 +1,51 @@
+#ifndef SCROLLINDICATOR_H
+#define SCROLLINDICATOR_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+class ScrollIndicator : public QWidget
+{
+ Q_OBJECT
+
+private:
+ QColor curColor;
+ QColor defaultColor = QColor(100, 100, 100, 130);
+ QColor hoverColor = QColor(70, 70, 70, 150);
+ QColor pressColor = QColor(50, 50, 50, 170);
+
+ QTimer* hovTimer;
+ QTimer* aniPause;
+
+ int lastY;
+
+ int defaultWidth = 2;
+ int defaultWidthAtFocus = 9;
+ int margin = 3;
+
+ bool pressed = false;
+
+public:
+ explicit ScrollIndicator(QWidget *parent = nullptr);
+
+private:
+ void paintEvent(QPaintEvent* event);
+ void enterEvent(QEnterEvent* event);
+ void leaveEvent(QEvent* event);
+ void mousePressEvent(QMouseEvent* event);
+ void mouseMoveEvent(QMouseEvent* event);
+ void mouseReleaseEvent(QMouseEvent* event);
+
+signals:
+ void scrollPage(int);
+
+private slots:
+ void setHoverActive();
+
+};
+
+#endif // SCROLLINDICATOR_H
diff --git a/scrolllistcontainer.cpp b/scrolllistcontainer.cpp
new file mode 100644
index 0000000..11ea8e0
--- /dev/null
+++ b/scrolllistcontainer.cpp
@@ -0,0 +1,155 @@
+#include "scrolllistcontainer.h"
+
+ScrollListContainer::ScrollListContainer(QWidget *parent) : QWidget(parent)
+{
+ //QVBoxLayout* mainLayout = new QVBoxLayout;
+ //this->setLayout(mainLayout);
+ //mainLayout->setContentsMargins(0, 0, 0, 0);
+ //this->setLayout(nullptr);
+ //newWidgetFade = new QTimer(this);
+ //newWidgetFade->setSingleShot(true);
+ //QObject::connect(newWidgetFade, SIGNAL(timsout()), this, SLOT(fadeIn()));
+ //QWidget* nullWidget = new QWidget(this);
+ //ys.push_back(1);
+ //widgets.push_back(nullWidget);
+ //nullWidget->resize(this->width(), 1);
+}
+
+void ScrollListContainer::paintEvent(QPaintEvent *event){
+ for(int i = 0; i < widgets.size(); i++){
+ widgets[i]->resize(this->width(), widgets[i]->height());
+ }
+}
+
+void ScrollListContainer::AddWidget(QWidget *widget){
+ //Add animation for all widgets current
+
+ //qDebug() << "Adding2" << "\n";
+ this->resize(this->width(), this->height() + widget->height() + spacing);
+ //qDebug() << "containerHeight:" << this->height() << "\n";
+ widgets.push_back(widget);
+ size++;
+ //qDebug() << "current widgets size (i): " << widgets.size() << "\n";
+ ys.push_back(0);
+ //qDebug() << "Widget wh" << widget->width() << "," << widget->height() << "\n";
+ //qDebug() << "Widget xy" << widget->x() << "," << widget->y() << "\n";
+ //widget->setParent(this);
+ widget->resize(this->width(), widget->height());
+ widget->show();
+ QGraphicsOpacityEffect* widgetOpac = new QGraphicsOpacityEffect(widget);
+ widgetOpac->setOpacity(0);
+ widget->setGraphicsEffect(widgetOpac);
+ //this->layout()->addWidget(widget);
+ QParallelAnimationGroup* dpGroup = new QParallelAnimationGroup;
+ QSequentialAnimationGroup* newWidgetFadeIn = new QSequentialAnimationGroup;
+ //for(int i = 0; i < widgets.size() - 1; i++){
+ for(int i = 0; i < size - 1; i++){
+ ys[i] += widget->height() + spacing;
+ QPropertyAnimation* move = new QPropertyAnimation(widgets[i], "pos");
+ move->setDuration(750);
+ move->setStartValue(widgets[i]->pos());
+ move->setEndValue(QPoint(widgets[i]->x(), ys[i]));
+ move->setEasingCurve(QEasingCurve::InOutQuart);
+ dpGroup->addAnimation(move);
+ }
+ newWidgetFadeIn->addPause(300);
+ QPropertyAnimation* fade = new QPropertyAnimation(widgetOpac, "opacity", widget);
+ fade->setDuration(300);
+ fade->setStartValue(0);
+ fade->setEndValue(1);
+ newWidgetFadeIn->addAnimation(fade);
+ dpGroup->addAnimation(newWidgetFadeIn);
+ dpGroup->start();
+ connect(dpGroup, &QPropertyAnimation::stateChanged, [=](){
+ if(dpGroup->state() == QAbstractAnimation::Stopped){
+ if(widgetOpac->opacity() != 1){
+ fade->start(QAbstractAnimation::DeleteWhenStopped);
+ connect(fade,&QPropertyAnimation::finished,[=](){widgetOpac->deleteLater();});
+ //qDebug() << "paused\n";
+ }
+ else{
+ dpGroup->deleteLater();
+ widgetOpac->deleteLater();
+ }
+ }
+ });
+
+}
+
+void ScrollListContainer::RemoveWidget(QWidget *widget){
+ int index;
+ if(widget == nullptr){
+ index = size - 1;
+ if(index != -1)
+ widget = widgets[index];
+ }
+ else
+ index = widgets.indexOf(widget);
+ if(index == -1 || widget == nullptr){
+ //qDebug() << "returnning";
+ return;
+ }
+ //qDebug() << "deleting index:" << index << "\n";
+// QGraphicsOpacityEffect* widgetOpac = new QGraphicsOpacityEffect(widget);
+// widgetOpac->setOpacity(1);
+// widget->setGraphicsEffect(widgetOpac);
+ //this->layout()->addWidget(widget);
+ this->resize(this->width(), this->height() - widget->height() - spacing);
+ this->parentWidget()->update();
+ widget->hide();
+ widget->setParent(nullptr);
+// widget->deleteLater();
+ QParallelAnimationGroup* dpGroup = new QParallelAnimationGroup;
+// QSequentialAnimationGroup* oldWidgetFadeOut = new QSequentialAnimationGroup;
+ for(int i = index - 1; i >= 0; i--){
+ //qDebug() << "adding Posani to index:" << i << "\n";
+ ys[i] -= (widget->height() + spacing);
+ QPropertyAnimation* move = new QPropertyAnimation(widgets[i], "pos");
+ move->setDuration(750);
+ move->setStartValue(widgets[i]->pos());
+ move->setEndValue(QPoint(widgets[i]->x(), ys[i]));
+ move->setEasingCurve(QEasingCurve::InOutQuart);
+ dpGroup->addAnimation(move);
+ }
+// oldWidgetFadeOut->addPause(300);
+// QPropertyAnimation* fade = new QPropertyAnimation(widgetOpac, "opacity", widget);
+// fade->setDuration(300);
+// fade->setStartValue(1);
+// fade->setEndValue(0);
+// oldWidgetFadeOut->addAnimation(fade);
+// dpGroup->addAnimation(oldWidgetFadeOut);
+ dpGroup->start(QAbstractAnimation::DeleteWhenStopped);
+ widgets.remove(index);
+ size--;
+// qDebug() << "current widgets size (o): " << widgets.size() << "\n";
+ ys.remove(index);
+ //qDebug() << "[f]size: " << size << "\n";
+// connect(dpGroup, &QPropertyAnimation::stateChanged, [=](){
+// if(dpGroup->state() == QAbstractAnimation::Stopped){
+// if(widgetOpac->opacity() != 0){
+// fade->start(QAbstractAnimation::DeleteWhenStopped);
+// connect(fade,&QPropertyAnimation::finished,[=](){
+// widgetOpac->deleteLater();
+// dpGroup->deleteLater();
+// widget->setParent(nullptr);
+// widget->deleteLater();});
+// //qDebug() << "paused\n";
+// }
+// else{
+// dpGroup->deleteLater();
+// widgetOpac->deleteLater();
+// widget->setParent(nullptr);
+// widget->deleteLater();
+// }
+// }
+// });
+}
+
+void ScrollListContainer::clear(){
+ //qDebug() << "size:" << size << "\n";
+ int n = size;
+ for(int i = 0; i < n; i++){
+ //qDebug() << "[D]size:" << size << "\n";
+ RemoveWidget();
+ }
+}
diff --git a/scrolllistcontainer.h b/scrolllistcontainer.h
new file mode 100644
index 0000000..258ff36
--- /dev/null
+++ b/scrolllistcontainer.h
@@ -0,0 +1,39 @@
+#ifndef SCROLLLISTCONTAINER_H
+#define SCROLLLISTCONTAINER_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+class ScrollListContainer : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit ScrollListContainer(QWidget *parent = nullptr);
+ void AddWidget(QWidget* widget);
+ void RemoveWidget(QWidget* widget = nullptr);
+ void clear();
+ //void RemoveWidget(QWidget* widget);
+
+private:
+ //QTimer* newWidgetFade;
+ int spacing = 3;
+ QVector widgets;
+ int size = 0;
+ QVector ys;
+
+ void paintEvent(QPaintEvent* event);
+
+signals:
+
+private slots:
+
+};
+
+#endif // SCROLLLISTCONTAINER_H
diff --git a/stackpage.cpp b/stackpage.cpp
new file mode 100644
index 0000000..1ec55cc
--- /dev/null
+++ b/stackpage.cpp
@@ -0,0 +1,104 @@
+#include "stackpage.h"
+
+StackPage::StackPage(QWidget* parent) : TabPage(parent)
+{
+ this->setMouseTracking(true);
+ //this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ QVBoxLayout* mainLayout = new QVBoxLayout;
+ mainLayout->setContentsMargins(0, 0, 0, 0);
+ this->setLayout(mainLayout);
+
+ QLabel* labNum = new QLabel;
+ QFont labFont("DengXian", 13);
+ labFont.setBold(true);
+ labNum->setText("Num Stack");
+ labNum->setFont(labFont);
+ labNum->setAlignment(Qt::AlignRight | Qt::AlignTop);
+ labNum->setStyleSheet("color:#E75E5E5E;");
+ labNum->setMaximumHeight(20);
+ mainLayout->addWidget(labNum);
+
+ numStackScrollArea = new ScrollAreaCustom(this);
+ mainLayout->addWidget(numStackScrollArea);
+
+ QLabel* labOp = new QLabel;
+ labFont.setBold(true);
+ labOp->setText("Operator Stack");
+ labOp->setFont(labFont);
+ labOp->setAlignment(Qt::AlignRight | Qt::AlignTop);
+ labOp->setStyleSheet("color:#E75E5E5E;");
+ labOp->setMaximumHeight(20);
+ mainLayout->addWidget(labOp);
+
+ opStackScrollArea = new ScrollAreaCustom(this);
+ mainLayout->addWidget(opStackScrollArea);
+
+ //qDebug() << "StackPageWidth:[" << this->x() << "," << this->y() << "," << this->width() << "," << this->height() << "]\n";
+}
+
+void StackPage::RfrStack(const QString & numDif, const QString & opDif){
+ //qDebug() << "Rfr p1\n";
+ QString numDifCpy = numDif;
+ if(!numDif.isEmpty()){
+ QTextStream numStream(&numDifCpy);
+ if(numDif[0] == 'r'){
+ numStackScrollArea->clear();
+ numDifCpy.remove(0, 1);
+ }
+ while(!numStream.atEnd()){
+ char op;
+ numStream >> op;
+ if(op == 'o'){
+ numStackScrollArea->removeWidget();
+ }
+ else if(op == 'i'){
+ double num;
+ numStream >> num;
+ QLabel* newNum = new QLabel;
+ QFont font("DengXian", 20);
+ font.setBold(true);
+ newNum->setFont(font);
+ newNum->setAlignment(Qt::AlignRight);
+ newNum->resize(newNum->width(), 30);
+ newNum->setText(QString::asprintf("%g", num));
+ numStackScrollArea->addWidget(newNum);
+ }
+ }
+ }
+ QString opDifCpy = opDif;
+ if(!opDif.isEmpty()){
+ QTextStream opStream(&opDifCpy);
+ if(opDif[0] == 'r'){
+ opStackScrollArea->clear();
+ opDifCpy.remove(0, 1);
+ }
+ while(!opStream.atEnd()){
+ //qDebug() << "opStream" << "\n";
+ char op;
+ opStream >> op;
+ //qDebug() << "op = " << op << "\n";
+ if(op == 'o'){
+ opStackScrollArea->removeWidget();
+ }
+ else if(op == 'i'){
+ char c;
+ opStream >> c;
+ //qDebug() << c << "\n";
+ QLabel* newChar = new QLabel;
+ QFont font("DengXian", 20);
+ font.setBold(false);
+ newChar->setFont(font);
+ newChar->setAlignment(Qt::AlignRight);
+ newChar->resize(newChar->width(), 30);
+ newChar->setText(QString::asprintf("%c", c));
+ opStackScrollArea->addWidget(newChar);
+ }
+ }
+ }
+}
+
+void StackPage::paintEvent(QPaintEvent *event){
+ //newScrollArea->setMinimumWidth(this->width());
+ //newScrollArea->setMinimumHeight(this->height());
+ //newScrollArea->resize(this->size());
+}
diff --git a/stackpage.h b/stackpage.h
new file mode 100644
index 0000000..b6286bd
--- /dev/null
+++ b/stackpage.h
@@ -0,0 +1,30 @@
+#ifndef STACKPAGE_H
+#define STACKPAGE_H
+
+#include "tabpage.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include "scrollareacustom.h"
+#include "qtransparentbutton.h"
+
+class StackPage : public TabPage
+{
+ Q_OBJECT
+public:
+ StackPage(QWidget* parent = nullptr);
+
+private:
+ ScrollAreaCustom* numStackScrollArea;
+ ScrollAreaCustom* opStackScrollArea;
+
+ void paintEvent(QPaintEvent* event);
+
+private slots:
+ void RfrStack(const QString &, const QString &);
+};
+
+#endif // STACKPAGE_H
diff --git a/tabbar.cpp b/tabbar.cpp
new file mode 100644
index 0000000..53e2d04
--- /dev/null
+++ b/tabbar.cpp
@@ -0,0 +1,6 @@
+#include "tabbar.h"
+
+TabBar::TabBar(QWidget *parent) : QWidget(parent)
+{
+
+}
diff --git a/tabbar.h b/tabbar.h
new file mode 100644
index 0000000..361f30c
--- /dev/null
+++ b/tabbar.h
@@ -0,0 +1,16 @@
+#ifndef TABBAR_H
+#define TABBAR_H
+
+#include
+
+class TabBar : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit TabBar(QWidget *parent = nullptr);
+
+signals:
+
+};
+
+#endif // TABBAR_H
diff --git a/tabicons.cpp b/tabicons.cpp
new file mode 100644
index 0000000..47debab
--- /dev/null
+++ b/tabicons.cpp
@@ -0,0 +1,78 @@
+#include "tabicons.h"
+
+TabIcons::TabIcons(QWidget* parent): QPushButton(parent)
+{
+ this->setMouseTracking(true);
+ QFont textFont;
+ textFont.setFamily("FuturaNo2DMed");
+ textFont.setPointSize(15);
+ QFontMetrics fm(textFont);
+ this->setMinimumSize(fm.boundingRect(this->text()).width() + 30, fm.ascent() - fm.descent() + fm.leading() + 20);
+ this->resize(fm.boundingRect(this->text()).width() + 30, fm.ascent() - fm.descent() + fm.leading());
+
+ this->setStyleSheet("background-color = background-color: rgba(255, 255, 255, 0);");
+ this->setFlat(true);
+
+ currentColor = defaultColorNotAtFocus;
+
+ //QObject::connect(this, SIGNAL(clicked()), this, SLOT(on_clicked()));
+}
+
+TabIcons::TabIcons(const QString & name, QWidget* parent) : QPushButton(parent){
+ this->setMouseTracking(true);
+ this->setText(name);
+ QFont textFont;
+ textFont.setFamily("FuturaNo2DMed");
+ textFont.setPointSize(15);
+ QFontMetrics fm(textFont);
+ this->setMinimumSize(fm.boundingRect(this->text()).width() + 30, fm.ascent() - fm.descent() + fm.leading() + 20);
+ this->resize(fm.boundingRect(this->text()).width() + 30, fm.ascent() - fm.descent() + fm.leading() + 20);
+
+ this->setStyleSheet("background-color = background-color: rgba(255, 255, 255, 0);");
+ this->setFlat(true);
+
+ currentColor = defaultColorNotAtFocus;
+ //qDebug() << "init" << this->width() << "\n";
+
+ //QObject::connect(this, SIGNAL(clicked()), this, SLOT(on_clicked()));
+}
+
+void TabIcons::paintEvent(QPaintEvent *event){
+ QPainter textPainter(this);
+ textPainter.setPen(currentColor);
+ QFont textFont("FuturaNo2DMed", 15);
+ textPainter.setFont(textFont);
+ int widthOfText = textPainter.fontMetrics().size(Qt::TextSingleLine, this->text()).width();
+ //qDebug()<<"icon!";
+ //int heightOfText = textPainter.fontMetrics().ascent() - textPainter.fontMetrics().descent() + textPainter.fontMetrics().leading();
+ //test.drawRect(this->width() / 2 - widthOfText / 2, this->height() / 2 - heightOfText / 2, widthOfText, heightOfText);
+ textPainter.drawText(this->width() / 2 - widthOfText / 2, this->height() - 5, this->text());
+ //qDebug() << "paint" << this->width() << "\n";
+}
+
+void TabIcons::enterEvent(QEnterEvent *event){
+ currentColor = hoverColor;
+ update();
+}
+
+void TabIcons::leaveEvent(QEvent *event){
+ currentColor = atFocus ? defaultColorAtFocus : defaultColorNotAtFocus;
+ update();
+}
+
+void TabIcons::mousePressEvent(QMouseEvent *event){
+ currentColor = pressColor;
+ update();
+ emit SelectPage(this);
+}
+
+void TabIcons::mouseReleaseEvent(QMouseEvent *event){
+ currentColor = atFocus ? defaultColorAtFocus : hoverColor;
+ update();
+}
+
+void TabIcons::SetFocus(bool status){
+ atFocus = status;
+ currentColor = atFocus ? defaultColorAtFocus : defaultColorNotAtFocus;
+ update();
+}
diff --git a/tabicons.h b/tabicons.h
new file mode 100644
index 0000000..30ca6dd
--- /dev/null
+++ b/tabicons.h
@@ -0,0 +1,40 @@
+#ifndef TABICONS_H
+#define TABICONS_H
+
+#include
+#include
+#include
+#include
+
+class TabIcons : public QPushButton
+{
+ Q_OBJECT
+
+private:
+ bool atFocus = false;
+
+ QColor currentColor;
+ QColor defaultColorAtFocus = QColor(0, 0, 0, 255);
+ QColor defaultColorNotAtFocus = QColor(100, 100, 100, 180);
+ QColor hoverColor = QColor(50, 50, 50, 230);
+ QColor pressColor = QColor(20, 20, 20, 230);
+
+ void paintEvent(QPaintEvent* event);
+ void enterEvent(QEnterEvent* event);
+ void leaveEvent(QEvent* event);
+ void mousePressEvent(QMouseEvent* event);
+ void mouseReleaseEvent(QMouseEvent* event);
+
+public:
+ TabIcons(QWidget* parent = nullptr);
+ TabIcons(const QString & name, QWidget* parent = nullptr);
+ void SetFocus(bool status);
+
+signals:
+ void SelectPage(TabIcons* icon);
+
+private slots:
+ void on_clicked(){emit SelectPage(this);}
+};
+
+#endif // TABICONS_H
diff --git a/tabindicator.cpp b/tabindicator.cpp
new file mode 100644
index 0000000..ea9fffd
--- /dev/null
+++ b/tabindicator.cpp
@@ -0,0 +1,14 @@
+#include "tabindicator.h"
+
+TabIndicator::TabIndicator(QWidget *parent) : QWidget(parent)
+{
+ this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ this->setMouseTracking(true);
+}
+
+void TabIndicator::paintEvent(QPaintEvent *event){
+ QPainter painter(this);
+ painter.setPen(QColor(0, 120, 215, 200));
+ painter.setBrush(QColor(0, 120, 215, 200));
+ painter.drawRect(this->rect());
+}
diff --git a/tabindicator.h b/tabindicator.h
new file mode 100644
index 0000000..c653c96
--- /dev/null
+++ b/tabindicator.h
@@ -0,0 +1,18 @@
+#ifndef TABINDICATOR_H
+#define TABINDICATOR_H
+
+#include
+#include
+
+class TabIndicator : public QWidget
+{
+ Q_OBJECT
+
+protected:
+ void paintEvent(QPaintEvent* event);
+
+public:
+ explicit TabIndicator(QWidget *parent = nullptr);
+};
+
+#endif // TABINDICATOR_H
diff --git a/tabpage.cpp b/tabpage.cpp
new file mode 100644
index 0000000..ec2780b
--- /dev/null
+++ b/tabpage.cpp
@@ -0,0 +1,6 @@
+#include "tabpage.h"
+
+TabPage::TabPage(QWidget *parent) : QWidget(parent)
+{
+ this->setMouseTracking(true);
+}
diff --git a/tabpage.h b/tabpage.h
new file mode 100644
index 0000000..8173777
--- /dev/null
+++ b/tabpage.h
@@ -0,0 +1,16 @@
+#ifndef TABPAGE_H
+#define TABPAGE_H
+
+#include
+
+class TabPage : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit TabPage(QWidget *parent = nullptr);
+
+signals:
+
+};
+
+#endif // TABPAGE_H