PeriDyno 1.0.0
Loading...
Searching...
No Matches
PAnimationQSlider.cpp
Go to the documentation of this file.
1#include "PAnimationQSlider.h"
2
3#include <QPalette>
4#include <QDebug>
5#include <QHBoxLayout>
6#include <QPainter>
7#include <cmath>
8namespace dyno
9{
11 QSlider(parent)
12 {
13 this->setRange(1, 1000);
14
15 m_displayLabel = new QLabel(this);
16 m_displayLabel->setFixedSize(QSize(30, 20));
17
18 m_displayLabel->setAlignment(Qt::AlignCenter);
19
20 this->setTickInterval(50);
21
22 this->setOrientation(Qt::Horizontal);
23 this->setMinimumWidth(180);
24 this->setTickPosition(QSlider::TicksAbove);
25 }
26
27 PAnimationQSlider::PAnimationQSlider(int minimum, int maximum, QWidget* parent /*= nullptr*/)
28 {
29 this->setRange(minimum, maximum);
30
31 m_displayLabel = new QLabel(this);
32 m_displayLabel->setFixedSize(QSize(30, 20));
33 m_displayLabel->setAlignment(Qt::AlignCenter);
34 m_displayLabel->setStyleSheet("background: transparent;");
35
36 this->setTickInterval(50);
37
38 this->setOrientation(Qt::Horizontal);
39 this->setMinimumWidth(180);
40 this->setTickPosition(QSlider::TicksAbove);
41 }
42
47
48 //To find a integer in a form of 2^n*5^m that is no smaller than val
49 int CalculteInterval(int val)
50 {
51 val = std::max(val, 1);
52 int m = ceil(log(double(val)) / log(double(5)));
53 int n = ceil(log2(double(val)));
54
55 int minDiff = INT_MAX;
56 int ret = pow(5, m) * pow(2, n);
57 for (int i = 0; i <= m; i++)
58 {
59 int a = (int)pow(5, i);
60 for (int j = 0; j <= n; j++)
61 {
62 int b = pow(2, j);
63 int diff = a * b - val;
64 if (diff >= 0 && diff < minDiff)
65 {
66 ret = a * b;
67 minDiff = ret;
68 }
69 }
70 }
71
72 return ret;
73 };
74
76 {
77 auto rect = this->geometry();
78 int numTicks = std::max(rect.width() / mMinimumTickWidth, 1);
79
80 int minVal = this->minimum();
81
82 int inverval = CalculteInterval((val - minVal) / (std::min(numTicks, mMaximumTickNum)));
83 setRange(minVal, val);
84 setSingleStep(inverval);
85 setTickInterval(inverval);
86 }
87
89 {
90 auto rect = this->geometry();
91 int numTicks = std::max(rect.width() / mMinimumTickWidth, 1);
92
93 int maxVal = this->maximum();
94
95 int inverval = CalculteInterval((maxVal - val) / (std::min(numTicks, mMaximumTickNum)));
96 setRange(val, maxVal);
97 setSingleStep(inverval);
98 setTickInterval(inverval);
99 }
100
101 void PAnimationQSlider::paintEvent(QPaintEvent* ev)
102 {
103 QSlider::paintEvent(ev);
104 auto painter = new QPainter(this);
105 painter->setPen(QPen(QColor(123,123,123),2));
106
107 auto rect = this->geometry();
108
109 int numTicks = std::max((maximum() - minimum()) / tickInterval(), 1);
110
111 QFontMetrics fontMetrics = QFontMetrics(this->font());
112
113 if (this->orientation() == Qt::Horizontal) {
114
115 int fontHeight = fontMetrics.height();
116
117 for (int i = 0; i <= numTicks; i++) {
118
119 int tickNum = minimum() + (tickInterval() * i);
120
121 auto tickX = (((rect.width() - 10.0f) / (maximum() - minimum()))* tickInterval() * i) - (fontMetrics.horizontalAdvance(QString::number(tickNum)) / 2);
122
123 auto tickY = (rect.height() + fontHeight) / 2;
124
125 auto tickMarkX = (((rect.width() - 10.0f) / (maximum() - minimum())) * tickInterval() * i);
126
127 painter->drawText(QPoint(tickX + 19, tickY - 7), QString::number(tickNum));
128 painter->drawLine(QPoint(tickMarkX + 6, rect.height() - 12), QPoint(tickMarkX + 6, rect.height()));
129 }
130 }
131 else if (this->orientation() == Qt::Vertical) {
132 //do something else for vertical here, I haven't implemented it because I don't need it
133 }
134 else {
135 return;
136 }
137
138 //painter->drawRect(rect);
139
140 painter->end();
141 }
142
143 void PAnimationQSlider::mousePressEvent(QMouseEvent* event)
144 {
145 QSlider::mousePressEvent(event);
146 }
147
149 {
150
151 m_displayLabel->setVisible(false);
152 QSlider::mouseReleaseEvent(event);
153 }
154
155 void PAnimationQSlider::mouseMoveEvent(QMouseEvent* event)
156 {
157 QFontMetrics fontMetrics = QFontMetrics(this->font());
158 int labelWidth = fontMetrics.horizontalAdvance(QString::number(this->value()))+fontMetrics.horizontalAdvance("0"); // 背景标签的宽度为当前帧数字符串宽度加1个字符的宽度
159
160 m_displayLabel->move(12 + (this->width() - 10) * (this->value() - this->minimum()) / (this->maximum() - this->minimum()), 2); //向下偏移2个单位以对齐slider的sub-page
161 m_displayLabel->setText(QString::number(this->value()));
162 m_displayLabel->setFixedWidth((labelWidth));
163
164 m_displayLabel->setVisible(true);
165 m_displayLabel->setStyleSheet("QLabel{background:#2b2b2b;color:#ffffff;}"); //背景标签颜色及帧数文字颜色
166 m_displayLabel->setAlignment(Qt::AlignVCenter);
167 m_displayLabel->setFixedHeight(20); //修改高度以对其Slider的Sub-page
168 QSlider::mouseMoveEvent(event);
169 }
170
171 void PAnimationQSlider::resizeEvent(QResizeEvent* event)
172 {
173 auto rect = this->geometry();
174 int numTicks = std::max(rect.width() / mMinimumTickWidth, 1);
175
176 int inverval = CalculteInterval(maximum() / (std::min(numTicks, mMaximumTickNum)));
177
178 setSingleStep(inverval);
179 setTickInterval(inverval);
180 }
181}
void mousePressEvent(QMouseEvent *event) override
void mouseMoveEvent(QMouseEvent *event) override
void paintEvent(QPaintEvent *ev) override
void mouseReleaseEvent(QMouseEvent *event) override
PAnimationQSlider(QWidget *parent=nullptr)
void resizeEvent(QResizeEvent *event)
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
int CalculteInterval(int val)
DYN_FUNC Complex< Real > log(const Complex< Real > &)
Definition Complex.inl:305
DYN_FUNC Complex< Real > pow(const Complex< Real > &, const Real &)
Definition Complex.inl:370
static int orientation(double x1, double y1, double x2, double y2, double &twice_signed_area)
DYN_FUNC T minimum(const T &v0, const T &v1)
Definition SimpleMath.h:120
DYN_FUNC T maximum(const T &v0, const T &v1)
Definition SimpleMath.h:160