Add SettingsButton widget.
This commit is contained in:
parent
45c0be45b2
commit
7d9ae816d4
3 changed files with 209 additions and 3 deletions
|
|
@ -6,12 +6,15 @@
|
|||
//
|
||||
#include "ui/widgets/buttons.h"
|
||||
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/effects/cross_animation.h"
|
||||
#include "ui/effects/numbers_animation.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "ui/painter.h"
|
||||
|
||||
#include <QtGui/QtEvents>
|
||||
|
||||
namespace Ui {
|
||||
|
||||
LinkButton::LinkButton(
|
||||
|
|
@ -628,4 +631,142 @@ QImage CrossButton::prepareRippleMask() const {
|
|||
return RippleAnimation::ellipseMask(QSize(_st.cross.size, _st.cross.size));
|
||||
}
|
||||
|
||||
SettingsButton::SettingsButton(
|
||||
QWidget *parent,
|
||||
rpl::producer<QString> &&text)
|
||||
: SettingsButton(parent, std::move(text), st::defaultSettingsButton) {
|
||||
}
|
||||
|
||||
SettingsButton::SettingsButton(
|
||||
QWidget *parent,
|
||||
rpl::producer<QString> &&text,
|
||||
const style::SettingsButton &st)
|
||||
: RippleButton(parent, st.ripple)
|
||||
, _st(st) {
|
||||
std::move(
|
||||
text
|
||||
) | rpl::start_with_next([this](QString &&value) {
|
||||
setText(std::move(value));
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
SettingsButton *SettingsButton::toggleOn(rpl::producer<bool> &&toggled) {
|
||||
Expects(_toggle == nullptr);
|
||||
_toggle = std::make_unique<Ui::ToggleView>(
|
||||
isOver() ? _st.toggleOver : _st.toggle,
|
||||
false,
|
||||
[this] { rtlupdate(toggleRect()); });
|
||||
addClickHandler([this] {
|
||||
_toggle->setChecked(!_toggle->checked(), anim::type::normal);
|
||||
});
|
||||
std::move(
|
||||
toggled
|
||||
) | rpl::start_with_next([this](bool toggled) {
|
||||
_toggle->setChecked(toggled, anim::type::normal);
|
||||
}, lifetime());
|
||||
_toggle->finishAnimating();
|
||||
return this;
|
||||
}
|
||||
|
||||
bool SettingsButton::toggled() const {
|
||||
return _toggle ? _toggle->checked() : false;
|
||||
}
|
||||
|
||||
rpl::producer<bool> SettingsButton::toggledChanges() const {
|
||||
if (_toggle) {
|
||||
return _toggle->checkedChanges();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rpl::producer<bool> SettingsButton::toggledValue() const {
|
||||
if (_toggle) {
|
||||
return _toggle->checkedValue();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SettingsButton::setColorOverride(std::optional<QColor> textColorOverride) {
|
||||
_textColorOverride = textColorOverride;
|
||||
update();
|
||||
}
|
||||
|
||||
void SettingsButton::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
|
||||
auto paintOver = (isOver() || isDown()) && !isDisabled();
|
||||
p.fillRect(e->rect(), paintOver ? _st.textBgOver : _st.textBg);
|
||||
|
||||
paintRipple(p, 0, 0);
|
||||
|
||||
auto outerw = width();
|
||||
p.setFont(_st.font);
|
||||
p.setPen(_textColorOverride
|
||||
? QPen(*_textColorOverride)
|
||||
: paintOver
|
||||
? _st.textFgOver
|
||||
: _st.textFg);
|
||||
p.drawTextLeft(
|
||||
_st.padding.left(),
|
||||
_st.padding.top(),
|
||||
outerw,
|
||||
_text,
|
||||
_textWidth);
|
||||
|
||||
if (_toggle) {
|
||||
auto rect = toggleRect();
|
||||
_toggle->paint(p, rect.left(), rect.top(), outerw);
|
||||
}
|
||||
}
|
||||
|
||||
QRect SettingsButton::toggleRect() const {
|
||||
Expects(_toggle != nullptr);
|
||||
|
||||
auto size = _toggle->getSize();
|
||||
auto left = width() - _st.toggleSkip - size.width();
|
||||
auto top = (height() - size.height()) / 2;
|
||||
return { QPoint(left, top), size };
|
||||
}
|
||||
|
||||
int SettingsButton::resizeGetHeight(int newWidth) {
|
||||
updateVisibleText(newWidth);
|
||||
return _st.padding.top() + _st.height + _st.padding.bottom();
|
||||
}
|
||||
|
||||
void SettingsButton::onStateChanged(
|
||||
State was,
|
||||
StateChangeSource source) {
|
||||
if (!isDisabled() || !isDown()) {
|
||||
RippleButton::onStateChanged(was, source);
|
||||
}
|
||||
if (_toggle) {
|
||||
_toggle->setStyle(isOver() ? _st.toggleOver : _st.toggle);
|
||||
}
|
||||
setPointerCursor(!isDisabled());
|
||||
}
|
||||
|
||||
void SettingsButton::setText(QString &&text) {
|
||||
_original = std::move(text);
|
||||
_originalWidth = _st.font->width(_original);
|
||||
updateVisibleText(width());
|
||||
}
|
||||
|
||||
void SettingsButton::updateVisibleText(int newWidth) {
|
||||
auto availableWidth = newWidth
|
||||
- _st.padding.left()
|
||||
- _st.padding.right();
|
||||
if (_toggle) {
|
||||
availableWidth -= (width() - toggleRect().x());
|
||||
}
|
||||
accumulate_max(availableWidth, 0);
|
||||
if (availableWidth < _originalWidth) {
|
||||
_text = _st.font->elided(_original, availableWidth);
|
||||
_textWidth = _st.font->width(_text);
|
||||
} else {
|
||||
_text = _original;
|
||||
_textWidth = _originalWidth;
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ namespace Ui {
|
|||
|
||||
class RippleAnimation;
|
||||
class NumbersAnimation;
|
||||
class ToggleView;
|
||||
|
||||
class LinkButton : public AbstractButton {
|
||||
public:
|
||||
|
|
@ -230,4 +231,44 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class SettingsButton : public Ui::RippleButton {
|
||||
public:
|
||||
SettingsButton(
|
||||
QWidget *parent,
|
||||
rpl::producer<QString> &&text);
|
||||
SettingsButton(
|
||||
QWidget *parent,
|
||||
rpl::producer<QString> &&text,
|
||||
const style::SettingsButton &st);
|
||||
|
||||
SettingsButton *toggleOn(rpl::producer<bool> &&toggled);
|
||||
bool toggled() const;
|
||||
rpl::producer<bool> toggledChanges() const;
|
||||
rpl::producer<bool> toggledValue() const;
|
||||
|
||||
void setColorOverride(std::optional<QColor> textColorOverride);
|
||||
|
||||
protected:
|
||||
int resizeGetHeight(int newWidth) override;
|
||||
void onStateChanged(
|
||||
State was,
|
||||
StateChangeSource source) override;
|
||||
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
private:
|
||||
void setText(QString &&text);
|
||||
QRect toggleRect() const;
|
||||
void updateVisibleText(int newWidth);
|
||||
|
||||
const style::SettingsButton &_st;
|
||||
QString _original;
|
||||
QString _text;
|
||||
int _originalWidth = 0;
|
||||
int _textWidth = 0;
|
||||
std::unique_ptr<Ui::ToggleView> _toggle;
|
||||
std::optional<QColor> _textColorOverride;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
|||
|
|
@ -485,7 +485,7 @@ ImportantTooltip {
|
|||
duration: int;
|
||||
}
|
||||
|
||||
InfoProfileButton {
|
||||
SettingsButton {
|
||||
textFg: color;
|
||||
textFgOver: color;
|
||||
textBg: color;
|
||||
|
|
@ -503,8 +503,8 @@ InfoProfileButton {
|
|||
ripple: RippleAnimation;
|
||||
}
|
||||
|
||||
InfoProfileCountButton {
|
||||
button: InfoProfileButton;
|
||||
SettingsCountButton {
|
||||
button: SettingsButton;
|
||||
icon: icon;
|
||||
iconPosition: point;
|
||||
label: FlatLabel;
|
||||
|
|
@ -1183,6 +1183,30 @@ backButton: IconButton(defaultIconButton) {
|
|||
}
|
||||
}
|
||||
|
||||
defaultSettingsToggle: Toggle(defaultToggle) {
|
||||
untoggledFg: menuIconFg;
|
||||
}
|
||||
defaultSettingsToggleOver: Toggle(defaultSettingsToggle) {
|
||||
untoggledFg: menuIconFgOver;
|
||||
}
|
||||
defaultSettingsButton: SettingsButton {
|
||||
textFg: windowBoldFg;
|
||||
textFgOver: windowBoldFgOver;
|
||||
textBg: windowBg;
|
||||
textBgOver: windowBgOver;
|
||||
|
||||
font: boxTextFont;
|
||||
|
||||
height: 20px;
|
||||
padding: margins(22px, 10px, 22px, 8px);
|
||||
|
||||
toggle: defaultSettingsToggle;
|
||||
toggleOver: defaultSettingsToggleOver;
|
||||
toggleSkip: 23px;
|
||||
|
||||
ripple: defaultRippleAnimation;
|
||||
}
|
||||
|
||||
// Windows specific title
|
||||
|
||||
windowTitleButton: IconButton {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue