2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-31 06:26:18 +00:00

Media::Player::Widget added instead of PlayerWidget.

New media player bar widget added. Switching between floating
media player panel and media player widget. New volume controller.
This commit is contained in:
John Preston
2016-10-12 22:34:25 +03:00
parent 8f135d7e00
commit 9eb8a93719
98 changed files with 2305 additions and 1841 deletions

View File

@@ -0,0 +1,129 @@
/*
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/continuous_slider.h"
namespace Ui {
ContinuousSlider::ContinuousSlider(QWidget *parent) : TWidget(parent)
, _a_value(animation(this, &ContinuousSlider::step_value)) {
setCursor(style::cur_pointer);
}
float64 ContinuousSlider::value() const {
return a_value.current();
}
void ContinuousSlider::setDisabled(bool disabled) {
if (_disabled != disabled) {
_disabled = disabled;
setCursor(_disabled ? style::cur_default : style::cur_pointer);
update();
}
}
void ContinuousSlider::setValue(float64 value, bool animated) {
if (animated) {
a_value.start(value);
_a_value.start();
} else {
a_value = anim::fvalue(value, value);
_a_value.stop();
}
update();
}
void ContinuousSlider::setFadeOpacity(float64 opacity) {
_fadeOpacity = opacity;
update();
}
void ContinuousSlider::step_value(float64 ms, bool timer) {
float64 dt = ms / (2 * AudioVoiceMsgUpdateView);
if (dt >= 1) {
_a_value.stop();
a_value.finish();
} else {
a_value.update(qMin(dt, 1.), anim::linear);
}
if (timer) update();
}
void ContinuousSlider::mouseMoveEvent(QMouseEvent *e) {
if (_mouseDown) {
updateDownValueFromPos(e->pos());
}
}
float64 ContinuousSlider::computeValue(const QPoint &pos) const {
auto seekRect = myrtlrect(getSeekRect());
auto result = isHorizontal() ?
(pos.x() - seekRect.x()) / float64(seekRect.width()) :
(1. - (pos.y() - seekRect.y()) / float64(seekRect.height()));
return snap(result, 0., 1.);
}
void ContinuousSlider::mousePressEvent(QMouseEvent *e) {
_mouseDown = true;
_downValue = computeValue(e->pos());
update();
if (_changeProgressCallback) {
_changeProgressCallback(_downValue);
}
}
void ContinuousSlider::mouseReleaseEvent(QMouseEvent *e) {
if (_mouseDown) {
_mouseDown = false;
if (_changeFinishedCallback) {
_changeFinishedCallback(_downValue);
}
a_value = anim::fvalue(_downValue, _downValue);
_a_value.stop();
update();
}
}
void ContinuousSlider::updateDownValueFromPos(const QPoint &pos) {
_downValue = computeValue(pos);
update();
if (_changeProgressCallback) {
_changeProgressCallback(_downValue);
}
}
void ContinuousSlider::enterEvent(QEvent *e) {
setOver(true);
}
void ContinuousSlider::leaveEvent(QEvent *e) {
setOver(false);
}
void ContinuousSlider::setOver(bool over) {
if (_over == over) return;
_over = over;
auto from = _over ? 0. : 1., to = _over ? 1. : 0.;
_a_over.start([this] { update(); }, from, to, getOverDuration());
}
} // namespace Ui

View File

@@ -0,0 +1,109 @@
/*
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 ContinuousSlider : public TWidget {
public:
ContinuousSlider(QWidget *parent);
enum class Direction {
Horizontal,
Vertical,
};
void setDirection(Direction direction) {
_direction = direction;
update();
}
float64 value() const;
void setValue(float64 value, bool animated);
void setFadeOpacity(float64 opacity);
void setDisabled(bool disabled);
using Callback = base::lambda_unique<void(float64)>;
void setChangeProgressCallback(Callback &&callback) {
_changeProgressCallback = std_::move(callback);
}
void setChangeFinishedCallback(Callback &&callback) {
_changeFinishedCallback = std_::move(callback);
}
bool isChanging() const {
return _mouseDown;
}
protected:
void mouseMoveEvent(QMouseEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void enterEvent(QEvent *e) override;
void leaveEvent(QEvent *e) override;
float64 fadeOpacity() const {
return _fadeOpacity;
}
float64 getCurrentValue(uint64 ms) {
_a_value.step(ms);
return _mouseDown ? _downValue : a_value.current();
}
float64 getCurrentOverFactor(uint64 ms) {
return _a_over.current(ms, _over ? 1. : 0.);
}
bool isDisabled() const {
return _disabled;
}
Direction getDirection() const {
return _direction;
}
bool isHorizontal() const {
return (_direction == Direction::Horizontal);
}
private:
virtual QRect getSeekRect() const = 0;
virtual float64 getOverDuration() const = 0;
void step_value(float64 ms, bool timer);
void setOver(bool over);
float64 computeValue(const QPoint &pos) const;
void updateDownValueFromPos(const QPoint &pos);
Direction _direction = Direction::Horizontal;
bool _disabled = false;
Callback _changeProgressCallback;
Callback _changeFinishedCallback;
bool _over = false;
FloatAnimation _a_over;
anim::fvalue a_value = { 0., 0. };
Animation _a_value;
bool _mouseDown = false;
float64 _downValue = 0.;
float64 _fadeOpacity = 1.;
};
} // namespace Ui

View File

@@ -0,0 +1,73 @@
/*
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/filled_slider.h"
#include "styles/style_widgets.h"
namespace Ui {
FilledSlider::FilledSlider(QWidget *parent, const style::FilledSlider &st) : ContinuousSlider(parent)
, _st(st) {
}
QRect FilledSlider::getSeekRect() const {
return QRect(0, 0, width(), height());
}
float64 FilledSlider::getOverDuration() const {
return _st.duration;
}
void FilledSlider::paintEvent(QPaintEvent *e) {
Painter p(this);
p.setPen(Qt::NoPen);
p.setRenderHint(QPainter::HighQualityAntialiasing);
auto masterOpacity = fadeOpacity();
auto ms = getms();
auto disabled = isDisabled();
auto over = getCurrentOverFactor(ms);
auto lineWidth = _st.lineWidth + ((_st.fullWidth - _st.lineWidth) * over);
auto lineWidthRounded = qFloor(lineWidth);
auto lineWidthPartial = lineWidth - lineWidthRounded;
auto seekRect = getSeekRect();
auto value = getCurrentValue(ms);
auto from = seekRect.x(), mid = disabled ? from : qRound(from + value * seekRect.width()), end = from + seekRect.width();
if (mid > from) {
p.setOpacity(masterOpacity);
p.fillRect(from, height() - lineWidthRounded, (mid - from), lineWidthRounded, _st.activeFg);
if (lineWidthPartial > 0.01) {
p.setOpacity(masterOpacity * lineWidthPartial);
p.fillRect(from, height() - lineWidthRounded - 1, (mid - from), 1, _st.activeFg);
}
}
if (end > mid && over > 0) {
p.setOpacity(masterOpacity * over);
p.fillRect(mid, height() - lineWidthRounded, (end - mid), lineWidthRounded, _st.inactiveFg);
if (lineWidthPartial > 0.01) {
p.setOpacity(masterOpacity * over * lineWidthPartial);
p.fillRect(mid, height() - lineWidthRounded - 1, (end - mid), 1, _st.inactiveFg);
}
}
}
} // namespace Ui

View File

@@ -0,0 +1,46 @@
/*
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
#include "ui/widgets/continuous_slider.h"
namespace style {
struct FilledSlider;
} // namespace style
namespace Ui {
class FilledSlider : public ContinuousSlider {
public:
FilledSlider(QWidget *parent, const style::FilledSlider &st);
protected:
void paintEvent(QPaintEvent *e) override;
private:
QRect getSeekRect() const override;
float64 getOverDuration() const override;
const style::FilledSlider &_st;
};
} // namespace Ui

View File

@@ -25,148 +25,78 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
namespace Ui {
MediaSlider::MediaSlider(QWidget *parent, const style::MediaSlider &st) : TWidget(parent)
, _st(st)
, _a_value(animation(this, &MediaSlider::step_value)) {
setCursor(style::cur_pointer);
MediaSlider::MediaSlider(QWidget *parent, const style::MediaSlider &st) : ContinuousSlider(parent)
, _st(st) {
}
float64 MediaSlider::value() const {
return a_value.current();
QRect MediaSlider::getSeekRect() const {
return isHorizontal()
? QRect(_st.seekSize.width() / 2, 0, width() - _st.seekSize.width(), height())
: QRect(0, _st.seekSize.height() / 2, width(), height() - _st.seekSize.width());
}
void MediaSlider::setDisabled(bool disabled) {
if (_disabled != disabled) {
_disabled = disabled;
setCursor(_disabled ? style::cur_default : style::cur_pointer);
update();
}
}
void MediaSlider::setValue(float64 value, bool animated) {
if (animated) {
a_value.start(value);
_a_value.start();
} else {
a_value = anim::fvalue(value, value);
_a_value.stop();
}
update();
}
void MediaSlider::setFadeOpacity(float64 opacity) {
_fadeOpacity = opacity;
update();
}
void MediaSlider::step_value(float64 ms, bool timer) {
float64 dt = ms / (2 * AudioVoiceMsgUpdateView);
if (dt >= 1) {
_a_value.stop();
a_value.finish();
} else {
a_value.update(qMin(dt, 1.), anim::linear);
}
if (timer) update();
}
int MediaSlider::lineLeft() const {
return (_st.seekSize.width() / 2);
}
int MediaSlider::lineWidth() const {
return (width() - _st.seekSize.width());
float64 MediaSlider::getOverDuration() const {
return _st.duration;
}
void MediaSlider::paintEvent(QPaintEvent *e) {
Painter p(this);
int radius = _st.width / 2;
p.setOpacity(_fadeOpacity);
p.setPen(Qt::NoPen);
p.setRenderHint(QPainter::HighQualityAntialiasing);
auto horizontal = isHorizontal();
auto ms = getms();
_a_value.step(ms);
auto over = _a_over.current(ms, _over ? 1. : 0.);
int skip = lineLeft();
int length = lineWidth();
float64 prg = _mouseDown ? _downValue : a_value.current();
int32 from = skip, mid = _disabled ? 0 : qRound(from + prg * length), end = from + length;
auto masterOpacity = fadeOpacity();
auto radius = _st.width / 2;
auto disabled = isDisabled();
auto over = getCurrentOverFactor(ms);
auto seekRect = getSeekRect();
auto value = getCurrentValue(ms);
// invert colors and value for vertical
if (!horizontal) value = 1. - value;
auto markerFrom = (horizontal ? seekRect.x() : seekRect.y());
auto markerLength = (horizontal ? seekRect.width() : seekRect.height());
auto from = _alwaysDisplayMarker ? 0 : markerFrom;
auto length = _alwaysDisplayMarker ? (horizontal ? width() : height()) : markerLength;
auto mid = disabled ? from : qRound(from + value * length);
auto end = from + length;
if (mid > from) {
p.setClipRect(0, 0, mid, height());
p.setOpacity(_fadeOpacity * (over * _st.activeOpacity + (1. - over) * _st.inactiveOpacity));
p.setBrush(_st.activeFg);
p.drawRoundedRect(from, (height() - _st.width) / 2, mid + radius - from, _st.width, radius, radius);
auto fromClipRect = horizontal ? QRect(0, 0, mid, height()) : QRect(0, 0, width(), mid);
auto fromRect = horizontal
? QRect(from, (height() - _st.width) / 2, mid + radius - from, _st.width)
: QRect((width() - _st.width) / 2, from, _st.width, mid + radius - from);
p.setClipRect(fromClipRect);
p.setOpacity(masterOpacity * (over * _st.activeOpacity + (1. - over) * _st.inactiveOpacity));
p.setBrush(horizontal ? _st.activeFg : _st.inactiveFg);
p.drawRoundedRect(fromRect, radius, radius);
}
if (end > mid) {
p.setClipRect(mid, 0, width() - mid, height());
p.setOpacity(_fadeOpacity);
p.setBrush(_st.inactiveFg);
p.drawRoundedRect(mid - radius, (height() - _st.width) / 2, end - (mid - radius), _st.width, radius, radius);
auto endClipRect = horizontal ? QRect(mid, 0, width() - mid, height()) : QRect(0, mid, width(), height() - mid);
auto endRect = horizontal
? QRect(mid - radius, (height() - _st.width) / 2, end - (mid - radius), _st.width)
: QRect((width() - _st.width) / 2, mid - radius, _st.width, end - (mid - radius));
p.setClipRect(endClipRect);
p.setOpacity(masterOpacity);
p.setBrush(horizontal ? _st.inactiveFg : _st.activeFg);
p.drawRoundedRect(endRect, radius, radius);
}
if (!_disabled && over > 0) {
int x = mid - skip;
p.setClipRect(rect());
p.setOpacity(_fadeOpacity * _st.activeOpacity);
auto seekButton = QRect(x, (height() - _st.seekSize.height()) / 2, _st.seekSize.width(), _st.seekSize.height());
int remove = ((1. - over) * _st.seekSize.width()) / 2.;
if (remove * 2 < _st.seekSize.width()) {
auto markerSizeRatio = disabled ? 0. : (_alwaysDisplayMarker ? 1. : over);
if (markerSizeRatio > 0) {
auto position = qRound(markerFrom + value * markerLength) - (horizontal ? seekRect.x() : seekRect.y());
auto seekButton = horizontal
? QRect(position, (height() - _st.seekSize.height()) / 2, _st.seekSize.width(), _st.seekSize.height())
: QRect((width() - _st.seekSize.width()) / 2, position, _st.seekSize.width(), _st.seekSize.height());
auto size = horizontal ? _st.seekSize.width() : _st.seekSize.height();
auto remove = static_cast<int>(((1. - markerSizeRatio) * size) / 2.);
if (remove * 2 < size) {
p.setClipRect(rect());
p.setOpacity(masterOpacity * _st.activeOpacity);
p.setBrush(_st.activeFg);
p.drawEllipse(seekButton.marginsRemoved(QMargins(remove, remove, remove, remove)));
}
}
}
void MediaSlider::mouseMoveEvent(QMouseEvent *e) {
if (_mouseDown) {
updateDownValueFromPos(e->pos().x());
}
}
void MediaSlider::mousePressEvent(QMouseEvent *e) {
_mouseDown = true;
_downValue = snap((e->pos().x() - lineLeft()) / float64(lineWidth()), 0., 1.);
update();
if (_changeProgressCallback) {
_changeProgressCallback(_downValue);
}
}
void MediaSlider::mouseReleaseEvent(QMouseEvent *e) {
if (_mouseDown) {
_mouseDown = false;
if (_changeFinishedCallback) {
_changeFinishedCallback(_downValue);
}
a_value = anim::fvalue(_downValue, _downValue);
_a_value.stop();
update();
}
}
void MediaSlider::updateDownValueFromPos(int pos) {
_downValue = snap((pos - lineLeft()) / float64(lineWidth()), 0., 1.);
update();
if (_changeProgressCallback) {
_changeProgressCallback(_downValue);
}
}
void MediaSlider::enterEvent(QEvent *e) {
setOver(true);
}
void MediaSlider::leaveEvent(QEvent *e) {
setOver(false);
}
void MediaSlider::setOver(bool over) {
if (_over == over) return;
_over = over;
auto from = _over ? 0. : 1., to = _over ? 1. : 0.;
_a_over.start([this] { update(); }, from, to, _st.duration);
}
} // namespace Ui

View File

@@ -20,62 +20,32 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "ui/widgets/continuous_slider.h"
namespace style {
struct MediaSlider;
} // namespace style
namespace Ui {
class MediaSlider : public TWidget {
class MediaSlider : public ContinuousSlider {
public:
MediaSlider(QWidget *parent, const style::MediaSlider &st);
float64 value() const;
void setValue(float64 value, bool animated);
void setFadeOpacity(float64 opacity);
void setDisabled(bool disabled);
using Callback = base::lambda_unique<void(float64)>;
void setChangeProgressCallback(Callback &&callback) {
_changeProgressCallback = std_::move(callback);
}
void setChangeFinishedCallback(Callback &&callback) {
_changeFinishedCallback = std_::move(callback);
void setAlwaysDisplayMarker(bool alwaysDisplayMarker) {
_alwaysDisplayMarker = alwaysDisplayMarker;
update();
}
protected:
void paintEvent(QPaintEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void mousePressEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
void enterEvent(QEvent *e) override;
void leaveEvent(QEvent *e) override;
private:
void step_value(float64 ms, bool timer);
void setOver(bool over);
void updateDownValueFromPos(int pos);
int lineLeft() const;
int lineWidth() const;
QRect getSeekRect() const override;
float64 getOverDuration() const override;
const style::MediaSlider &_st;
bool _disabled = false;
Callback _changeProgressCallback;
Callback _changeFinishedCallback;
bool _over = false;
FloatAnimation _a_over;
anim::fvalue a_value = { 0., 0. };
Animation _a_value;
bool _mouseDown = false;
float64 _downValue = 0.;
float64 _fadeOpacity = 1.;
bool _alwaysDisplayMarker = false;
};

View File

@@ -0,0 +1,56 @@
/*
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/shadow.h"
namespace Ui {
void ToggleableShadow::setMode(Mode mode) {
if (mode == Mode::ShownFast || mode == Mode::HiddenFast) {
if (!_a_opacity.animating()) {
_a_opacity.finish();
update();
}
}
if (_shown && (mode == Mode::Hidden || mode == Mode::HiddenFast)) {
_shown = false;
if (mode == Mode::Hidden) {
_a_opacity.start([this] { update(); }, 1., 0., st::shadowToggleDuration);
}
} else if (!_shown && (mode == Mode::Shown || mode == Mode::ShownFast)) {
_shown = true;
if (mode == Mode::Shown) {
_a_opacity.start([this] { update(); }, 0., 1., st::shadowToggleDuration);
}
}
}
void ToggleableShadow::paintEvent(QPaintEvent *e) {
Painter p(this);
if (_a_opacity.animating(getms())) {
p.setOpacity(_a_opacity.current());
} else if (!_shown) {
return;
}
p.fillRect(e->rect(), _color);
}
} // namespace Ui

View File

@@ -0,0 +1,47 @@
#pragma once
namespace Ui {
class PlainShadow : public TWidget {
public:
PlainShadow(QWidget *parent, const style::color &color) : TWidget(parent), _color(color) {
}
protected:
void paintEvent(QPaintEvent *e) override {
Painter(this).fillRect(e->rect(), _color->b);
}
private:
const style::color &_color;
};
class ToggleableShadow : public TWidget {
public:
ToggleableShadow(QWidget *parent, const style::color &color) : TWidget(parent), _color(color) {
}
enum class Mode {
Shown,
ShownFast,
Hidden,
HiddenFast
};
void setMode(Mode mode);
bool isFullyShown() const {
return _shown && !_a_opacity.animating();
}
protected:
void paintEvent(QPaintEvent *e) override;
private:
const style::color &_color;
FloatAnimation _a_opacity;
bool _shown = true;
};
} // namespace Ui

View File

@@ -27,19 +27,20 @@ namespace Ui {
template <typename Widget>
class WidgetSlideWrap : public TWidget {
public:
using UpdateCallback = base::lambda_unique<void()>;
WidgetSlideWrap(QWidget *parent, Widget *entity
, style::margins entityPadding
, base::lambda_unique<void()> &&updateCallback
, UpdateCallback &&updateCallback
, int duration = st::widgetSlideDuration) : TWidget(parent)
, _entity(entity)
, _padding(entityPadding)
, _duration(duration)
, _updateCallback(std_::move(updateCallback))
, _a_height(animation(this, &WidgetSlideWrap<Widget>::step_height)) {
entity->setParent(this);
entity->moveToLeft(_padding.left(), _padding.top());
_realSize = entity->rect().marginsAdded(_padding).size();
entity->installEventFilter(this);
, _entity(entity)
, _padding(entityPadding)
, _duration(duration)
, _updateCallback(std_::move(updateCallback))
, _a_height(animation(this, &WidgetSlideWrap<Widget>::step_height)) {
_entity->setParent(this);
_entity->moveToLeft(_padding.left(), _padding.top());
_realSize = _entity->rect().marginsAdded(_padding).size();
_entity->installEventFilter(this);
resize(_realSize);
}
@@ -91,6 +92,7 @@ public:
}
void showFast() {
show();
_a_height.stop();
resize(_realSize);
if (_updateCallback) {
@@ -152,7 +154,7 @@ private:
bool _inResizeToWidth = false;
style::margins _padding;
int _duration;
base::lambda_unique<void()> _updateCallback;
UpdateCallback _updateCallback;
style::size _realSize;
int _forceHeight = -1;

View File

@@ -43,6 +43,14 @@ MediaSlider {
duration: int;
}
FilledSlider {
fullWidth: pixels;
lineWidth: pixels;
activeFg: color;
inactiveFg: color;
duration: int;
}
widgetSlideDuration: 200;
discreteSliderHeight: 39px;