mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-08-31 06:26:18 +00:00
Advanced notifications settings box layout done.
This commit is contained in:
161
Telegram/SourceFiles/ui/widgets/discrete_slider.cpp
Normal file
161
Telegram/SourceFiles/ui/widgets/discrete_slider.cpp
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It 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.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "ui/widgets/discrete_slider.h"
|
||||
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
DiscreteSlider::DiscreteSlider(QWidget *parent) : TWidget(parent)
|
||||
, _a_left(animation(this, &DiscreteSlider::step_left)) {
|
||||
setCursor(style::cur_pointer);
|
||||
}
|
||||
|
||||
void DiscreteSlider::setActiveSection(int index) {
|
||||
setSelectedSection(index);
|
||||
if (_activeIndex != index) {
|
||||
_activeIndex = index;
|
||||
emit sectionActivated();
|
||||
}
|
||||
}
|
||||
|
||||
void DiscreteSlider::setActiveSectionFast(int index) {
|
||||
setActiveSection(index);
|
||||
a_left.finish();
|
||||
_a_left.stop();
|
||||
update();
|
||||
}
|
||||
|
||||
void DiscreteSlider::addSection(const QString &label) {
|
||||
auto section = Section(label);
|
||||
_sections.push_back(section);
|
||||
}
|
||||
|
||||
void DiscreteSlider::resizeSections(int newWidth) {
|
||||
auto count = _sections.size();
|
||||
if (!count) return;
|
||||
|
||||
auto skips = count - 1;
|
||||
auto sectionsWidth = newWidth - skips * st::discreteSliderSkip;
|
||||
auto sectionWidth = sectionsWidth / float64(count);
|
||||
auto x = 0.;
|
||||
for (int i = 0; i != count; ++i) {
|
||||
auto §ion = _sections[i];
|
||||
auto skip = i * st::discreteSliderThickness;
|
||||
section.left = qFloor(x) + skip;
|
||||
x += sectionWidth;
|
||||
section.width = qRound(x) - (section.left - skip);
|
||||
}
|
||||
a_left = anim::ivalue(_sections[_activeIndex].left, _sections[_activeIndex].left);
|
||||
_a_left.stop();
|
||||
}
|
||||
|
||||
void DiscreteSlider::mousePressEvent(QMouseEvent *e) {
|
||||
setSelectedSection(getIndexFromPosition(e->pos()));
|
||||
_pressed = true;
|
||||
}
|
||||
|
||||
void DiscreteSlider::mouseMoveEvent(QMouseEvent *e) {
|
||||
if (!_pressed) return;
|
||||
setSelectedSection(getIndexFromPosition(e->pos()));
|
||||
}
|
||||
|
||||
void DiscreteSlider::mouseReleaseEvent(QMouseEvent *e) {
|
||||
if (!_pressed) return;
|
||||
_pressed = false;
|
||||
setActiveSection(getIndexFromPosition(e->pos()));
|
||||
}
|
||||
|
||||
void DiscreteSlider::setSelectedSection(int index) {
|
||||
if (index < 0) return;
|
||||
|
||||
if (_selected != index) {
|
||||
_selected = index;
|
||||
a_left.start(_sections[_selected].left);
|
||||
_a_left.start();
|
||||
}
|
||||
}
|
||||
|
||||
void DiscreteSlider::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
int activeLeft = a_left.current();
|
||||
|
||||
p.setFont(st::discreteSliderLabelFont);
|
||||
p.setPen(st::discreteSliderLabelFg);
|
||||
for (int i = 0, count = _sections.size(); i != count; ++i) {
|
||||
auto §ion = _sections.at(i);
|
||||
auto from = section.left, tofill = section.width;
|
||||
if (activeLeft > from) {
|
||||
auto fill = qMin(tofill, activeLeft - from);
|
||||
p.fillRect(myrtlrect(from, st::discreteSliderTop, fill, st::discreteSliderThickness), st::discreteSliderInactiveFg);
|
||||
from += fill;
|
||||
tofill -= fill;
|
||||
}
|
||||
if (activeLeft + section.width > from) {
|
||||
if (auto fill = qMin(tofill, activeLeft + section.width - from)) {
|
||||
p.fillRect(myrtlrect(from, st::discreteSliderTop, fill, st::discreteSliderThickness), st::discreteSliderActiveFg);
|
||||
from += fill;
|
||||
tofill -= fill;
|
||||
}
|
||||
}
|
||||
if (tofill) {
|
||||
p.fillRect(myrtlrect(from, st::discreteSliderTop, tofill, st::discreteSliderThickness), st::discreteSliderInactiveFg);
|
||||
}
|
||||
p.drawTextLeft(section.left + (section.width - section.labelWidth) / 2, st::discreteSliderLabelTop, width(), section.label, section.labelWidth);
|
||||
}
|
||||
}
|
||||
|
||||
int DiscreteSlider::resizeGetHeight(int newWidth) {
|
||||
resizeSections(newWidth);
|
||||
return st::discreteSliderHeight;
|
||||
}
|
||||
|
||||
int DiscreteSlider::getIndexFromPosition(QPoint pos) {
|
||||
int count = _sections.size();
|
||||
for (int i = 0; i != count; ++i) {
|
||||
if (_sections[i].left + _sections[i].width > pos.x()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return count - 1;
|
||||
}
|
||||
|
||||
void DiscreteSlider::step_left(float64 ms, bool timer) {
|
||||
auto dt = ms / st::discreteSliderDuration;
|
||||
if (dt >= 1) {
|
||||
a_left.finish();
|
||||
_a_left.stop();
|
||||
} else {
|
||||
a_left.update(dt, anim::linear);
|
||||
}
|
||||
if (timer) {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
DiscreteSlider::Section::Section(const QString &label)
|
||||
: label(label)
|
||||
, labelWidth(st::discreteSliderLabelFont->width(label)) {
|
||||
}
|
||||
|
||||
} // namespace Ui
|
72
Telegram/SourceFiles/ui/widgets/discrete_slider.h
Normal file
72
Telegram/SourceFiles/ui/widgets/discrete_slider.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It 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.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class DiscreteSlider : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DiscreteSlider(QWidget *parent);
|
||||
|
||||
int activeSection() const {
|
||||
return _activeIndex;
|
||||
}
|
||||
void setActiveSection(int index);
|
||||
void setActiveSectionFast(int index);
|
||||
void addSection(const QString &label);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
void mousePressEvent(QMouseEvent *e) override;
|
||||
void mouseMoveEvent(QMouseEvent *e) override;
|
||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
|
||||
signals:
|
||||
void sectionActivated();
|
||||
|
||||
private:
|
||||
void resizeSections(int newWidth);
|
||||
int getIndexFromPosition(QPoint pos);
|
||||
void setSelectedSection(int index);
|
||||
void step_left(float64 ms, bool timer);
|
||||
|
||||
struct Section {
|
||||
Section(const QString &label);
|
||||
|
||||
int left, width;
|
||||
QString label;
|
||||
int labelWidth;
|
||||
};
|
||||
QList<Section> _sections;
|
||||
int _activeIndex = 0;
|
||||
|
||||
bool _pressed = false;
|
||||
int _selected = 0;
|
||||
anim::ivalue a_left = { 0 };
|
||||
Animation _a_left;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
@@ -34,3 +34,14 @@ defaultLabelSimple: LabelSimple {
|
||||
}
|
||||
|
||||
widgetSlideDuration: 200;
|
||||
|
||||
discreteSliderHeight: 39px;
|
||||
discreteSliderTop: 5px;
|
||||
discreteSliderSkip: 3px;
|
||||
discreteSliderThickness: 3px;
|
||||
discreteSliderActiveFg: #4bb5e7;
|
||||
discreteSliderInactiveFg: #e1eaef;
|
||||
discreteSliderLabelTop: 17px;
|
||||
discreteSliderLabelFont: normalFont;
|
||||
discreteSliderLabelFg: #1485c2;
|
||||
discreteSliderDuration: 200;
|
||||
|
Reference in New Issue
Block a user