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/buttons.h"
|
||||||
|
|
||||||
|
#include "ui/widgets/checkbox.h"
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/effects/cross_animation.h"
|
#include "ui/effects/cross_animation.h"
|
||||||
#include "ui/effects/numbers_animation.h"
|
#include "ui/effects/numbers_animation.h"
|
||||||
#include "ui/image/image_prepare.h"
|
#include "ui/image/image_prepare.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
|
|
||||||
|
#include <QtGui/QtEvents>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
LinkButton::LinkButton(
|
LinkButton::LinkButton(
|
||||||
|
|
@ -628,4 +631,142 @@ QImage CrossButton::prepareRippleMask() const {
|
||||||
return RippleAnimation::ellipseMask(QSize(_st.cross.size, _st.cross.size));
|
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
|
} // namespace Ui
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ namespace Ui {
|
||||||
|
|
||||||
class RippleAnimation;
|
class RippleAnimation;
|
||||||
class NumbersAnimation;
|
class NumbersAnimation;
|
||||||
|
class ToggleView;
|
||||||
|
|
||||||
class LinkButton : public AbstractButton {
|
class LinkButton : public AbstractButton {
|
||||||
public:
|
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
|
} // namespace Ui
|
||||||
|
|
|
||||||
|
|
@ -485,7 +485,7 @@ ImportantTooltip {
|
||||||
duration: int;
|
duration: int;
|
||||||
}
|
}
|
||||||
|
|
||||||
InfoProfileButton {
|
SettingsButton {
|
||||||
textFg: color;
|
textFg: color;
|
||||||
textFgOver: color;
|
textFgOver: color;
|
||||||
textBg: color;
|
textBg: color;
|
||||||
|
|
@ -503,8 +503,8 @@ InfoProfileButton {
|
||||||
ripple: RippleAnimation;
|
ripple: RippleAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
InfoProfileCountButton {
|
SettingsCountButton {
|
||||||
button: InfoProfileButton;
|
button: SettingsButton;
|
||||||
icon: icon;
|
icon: icon;
|
||||||
iconPosition: point;
|
iconPosition: point;
|
||||||
label: FlatLabel;
|
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
|
// Windows specific title
|
||||||
|
|
||||||
windowTitleButton: IconButton {
|
windowTitleButton: IconButton {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue