Improve design of video player and PiP controls.
After Width: | Height: | Size: 281 B |
After Width: | Height: | Size: 476 B |
After Width: | Height: | Size: 695 B |
After Width: | Height: | Size: 359 B |
After Width: | Height: | Size: 639 B |
After Width: | Height: | Size: 919 B |
After Width: | Height: | Size: 341 B |
After Width: | Height: | Size: 594 B |
After Width: | Height: | Size: 879 B |
After Width: | Height: | Size: 183 B |
After Width: | Height: | Size: 361 B |
After Width: | Height: | Size: 566 B |
After Width: | Height: | Size: 215 B |
After Width: | Height: | Size: 400 B |
After Width: | Height: | Size: 593 B |
After Width: | Height: | Size: 319 B |
After Width: | Height: | Size: 530 B |
After Width: | Height: | Size: 877 B |
After Width: | Height: | Size: 253 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 747 B |
After Width: | Height: | Size: 361 B |
After Width: | Height: | Size: 574 B |
After Width: | Height: | Size: 845 B |
After Width: | Height: | Size: 242 B |
After Width: | Height: | Size: 452 B |
After Width: | Height: | Size: 662 B |
After Width: | Height: | Size: 334 B |
After Width: | Height: | Size: 631 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 659 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 445 B |
After Width: | Height: | Size: 854 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 482 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 341 B |
After Width: | Height: | Size: 668 B |
After Width: | Height: | Size: 962 B |
|
@ -2104,6 +2104,8 @@ bool OverlayWidget::initStreaming(bool continueStreaming) {
|
||||||
|| (!_streamed->instance.player().active()
|
|| (!_streamed->instance.player().active()
|
||||||
&& !_streamed->instance.player().finished())) {
|
&& !_streamed->instance.player().finished())) {
|
||||||
startStreamingPlayer();
|
startStreamingPlayer();
|
||||||
|
} else {
|
||||||
|
updatePlaybackState();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "styles/style_window.h"
|
#include "styles/style_window.h"
|
||||||
#include "styles/style_mediaview.h"
|
#include "styles/style_mediaview.h"
|
||||||
#include "styles/style_layers.h" // st::boxTitleClose
|
|
||||||
#include "styles/style_calls.h" // st::callShadow
|
#include "styles/style_calls.h" // st::callShadow
|
||||||
|
|
||||||
#include <QtGui/QWindow>
|
#include <QtGui/QWindow>
|
||||||
|
@ -292,6 +291,14 @@ void PipPanel::setPosition(Position position) {
|
||||||
setPositionDefault();
|
setPositionDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect PipPanel::inner() const {
|
||||||
|
return rect().marginsRemoved(_padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PipPanel::dragging() const {
|
||||||
|
return _dragState.has_value();
|
||||||
|
}
|
||||||
|
|
||||||
rpl::producer<> PipPanel::saveGeometryRequests() const {
|
rpl::producer<> PipPanel::saveGeometryRequests() const {
|
||||||
return _saveGeometryRequests.events();
|
return _saveGeometryRequests.events();
|
||||||
}
|
}
|
||||||
|
@ -433,7 +440,7 @@ void PipPanel::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto request = FrameRequest();
|
auto request = FrameRequest();
|
||||||
const auto inner = rect().marginsRemoved(_padding);
|
const auto inner = this->inner();
|
||||||
request.resize = request.outer = inner.size() * style::DevicePixelRatio();
|
request.resize = request.outer = inner.size() * style::DevicePixelRatio();
|
||||||
request.corners = RectPart(0)
|
request.corners = RectPart(0)
|
||||||
| ((_attached & (RectPart::Left | RectPart::Top))
|
| ((_attached & (RectPart::Left | RectPart::Top))
|
||||||
|
@ -453,7 +460,6 @@ void PipPanel::paintEvent(QPaintEvent *e) {
|
||||||
const auto sides = RectPart::AllSides & ~_attached;
|
const auto sides = RectPart::AllSides & ~_attached;
|
||||||
Ui::Shadow::paint(p, inner, width(), st::callShadow);
|
Ui::Shadow::paint(p, inner, width(), st::callShadow);
|
||||||
}
|
}
|
||||||
p.translate(_padding.left(), _padding.top());
|
|
||||||
_paint(p, request);
|
_paint(p, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,7 +521,7 @@ void PipPanel::updateOverState(QPoint point) {
|
||||||
setCursor([&] {
|
setCursor([&] {
|
||||||
switch (_overState) {
|
switch (_overState) {
|
||||||
case RectPart::Center:
|
case RectPart::Center:
|
||||||
return style::cur_default;
|
return style::cur_pointer;
|
||||||
case RectPart::TopLeft:
|
case RectPart::TopLeft:
|
||||||
case RectPart::BottomRight:
|
case RectPart::BottomRight:
|
||||||
return style::cur_sizefdiag;
|
return style::cur_sizefdiag;
|
||||||
|
@ -655,6 +661,11 @@ void PipPanel::moveAnimated(QPoint to) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipPanel::updateDecorations() {
|
void PipPanel::updateDecorations() {
|
||||||
|
const auto guard = gsl::finally([&] {
|
||||||
|
if (!_dragState) {
|
||||||
|
_saveGeometryRequests.fire({});
|
||||||
|
}
|
||||||
|
});
|
||||||
const auto position = countPosition();
|
const auto position = countPosition();
|
||||||
const auto center = position.geometry.center();
|
const auto center = position.geometry.center();
|
||||||
const auto use = Ui::Platform::TranslucentWindowsSupported(center);
|
const auto use = Ui::Platform::TranslucentWindowsSupported(center);
|
||||||
|
@ -665,7 +676,7 @@ void PipPanel::updateDecorations() {
|
||||||
(position.attached & RectPart::Right) ? 0 : full.right(),
|
(position.attached & RectPart::Right) ? 0 : full.right(),
|
||||||
(position.attached & RectPart::Bottom) ? 0 : full.bottom());
|
(position.attached & RectPart::Bottom) ? 0 : full.bottom());
|
||||||
_snapped = position.snapped;
|
_snapped = position.snapped;
|
||||||
if (_padding == padding || _attached == position.attached) {
|
if (_padding == padding && _attached == position.attached) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto newGeometry = position.geometry.marginsAdded(padding);
|
const auto newGeometry = position.geometry.marginsAdded(padding);
|
||||||
|
@ -675,9 +686,6 @@ void PipPanel::updateDecorations() {
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
||||||
setGeometry(newGeometry);
|
setGeometry(newGeometry);
|
||||||
update();
|
update();
|
||||||
if (!_dragState) {
|
|
||||||
_saveGeometryRequests.fire({});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pip::Pip(
|
Pip::Pip(
|
||||||
|
@ -690,18 +698,6 @@ Pip::Pip(
|
||||||
, _panel(
|
, _panel(
|
||||||
_delegate->pipParentWidget(),
|
_delegate->pipParentWidget(),
|
||||||
[=](QPainter &p, const FrameRequest &request) { paint(p, request); })
|
[=](QPainter &p, const FrameRequest &request) { paint(p, request); })
|
||||||
, _playPauseResume(
|
|
||||||
std::in_place,
|
|
||||||
&_panel,
|
|
||||||
object_ptr<Ui::IconButton>(&_panel, st::mediaviewPlayButton))
|
|
||||||
, _pictureInPicture(
|
|
||||||
std::in_place,
|
|
||||||
&_panel,
|
|
||||||
object_ptr<Ui::IconButton>(&_panel, st::mediaviewFullScreenButton))
|
|
||||||
, _close(
|
|
||||||
std::in_place,
|
|
||||||
&_panel,
|
|
||||||
object_ptr<Ui::IconButton>(&_panel, st::boxTitleClose))
|
|
||||||
, _closeAndContinue(std::move(closeAndContinue))
|
, _closeAndContinue(std::move(closeAndContinue))
|
||||||
, _destroy(std::move(destroy)) {
|
, _destroy(std::move(destroy)) {
|
||||||
setupPanel();
|
setupPanel();
|
||||||
|
@ -725,39 +721,131 @@ void Pip::setupPanel() {
|
||||||
}, _panel.lifetime());
|
}, _panel.lifetime());
|
||||||
|
|
||||||
_panel.events(
|
_panel.events(
|
||||||
) | rpl::filter([=](not_null<QEvent*> e) {
|
) | rpl::start_with_next([=](not_null<QEvent*> e) {
|
||||||
return e->type() == QEvent::Close;
|
switch (e->type()) {
|
||||||
}) | rpl::start_with_next([=] {
|
case QEvent::Close: handleClose(); break;
|
||||||
crl::on_main(&_panel, [=] {
|
case QEvent::Leave: handleLeave(); break;
|
||||||
_destroy();
|
case QEvent::MouseMove:
|
||||||
});
|
handleMouseMove(static_cast<QMouseEvent*>(e.get())->pos());
|
||||||
|
break;
|
||||||
|
case QEvent::MouseButtonPress:
|
||||||
|
handleMousePress(static_cast<QMouseEvent*>(e.get())->button());
|
||||||
|
break;
|
||||||
|
case QEvent::MouseButtonRelease:
|
||||||
|
handleMouseRelease(static_cast<QMouseEvent*>(e.get())->button());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}, _panel.lifetime());
|
}, _panel.lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pip::setupButtons() {
|
void Pip::handleClose() {
|
||||||
_panel.sizeValue(
|
crl::on_main(&_panel, [=] {
|
||||||
) | rpl::start_with_next([=](QSize size) {
|
_destroy();
|
||||||
_close->moveToLeft(0, 0, size.width());
|
});
|
||||||
const auto skip = st::mediaviewFullScreenLeft;
|
}
|
||||||
const auto sum = _playPauseResume->width() + skip + _pictureInPicture->width();
|
|
||||||
const auto left = (size.width() - sum) / 2;
|
|
||||||
const auto top = size.height() - _playPauseResume->height() - skip;
|
|
||||||
_playPauseResume->moveToLeft(left, top);
|
|
||||||
_pictureInPicture->moveToRight(left, top);
|
|
||||||
}, _panel.lifetime());
|
|
||||||
|
|
||||||
_close->entity()->addClickHandler([=] {
|
void Pip::handleLeave() {
|
||||||
_panel.close();
|
setOverState(OverState::None);
|
||||||
});
|
}
|
||||||
_pictureInPicture->entity()->addClickHandler([=] {
|
|
||||||
_closeAndContinue();
|
void Pip::handleMouseMove(QPoint position) {
|
||||||
});
|
setOverState(computeState(position));
|
||||||
_playPauseResume->entity()->addClickHandler([=] {
|
}
|
||||||
playbackPauseResume();
|
|
||||||
});
|
void Pip::setOverState(OverState state) {
|
||||||
_close->show(anim::type::instant);
|
if (_over == state) {
|
||||||
_pictureInPicture->show(anim::type::instant);
|
return;
|
||||||
_playPauseResume->show(anim::type::instant);
|
}
|
||||||
|
const auto was = _over;
|
||||||
|
_over = state;
|
||||||
|
const auto nowShown = (_over != OverState::None);
|
||||||
|
if ((was != OverState::None) != nowShown) {
|
||||||
|
_controlsShown.start(
|
||||||
|
[=] { _panel.update(); },
|
||||||
|
nowShown ? 0. : 1.,
|
||||||
|
nowShown ? 1. : 0.,
|
||||||
|
st::fadeWrapDuration,
|
||||||
|
anim::linear);
|
||||||
|
}
|
||||||
|
const auto check = [&](Button &button) {
|
||||||
|
const auto now = (_over == button.state);
|
||||||
|
if ((was == button.state) != now) {
|
||||||
|
button.active.start(
|
||||||
|
[=, &button] { _panel.update(button.icon); },
|
||||||
|
now ? 0. : 1.,
|
||||||
|
now ? 1. : 0.,
|
||||||
|
st::fadeWrapDuration,
|
||||||
|
anim::linear);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
check(_close);
|
||||||
|
check(_enlarge);
|
||||||
|
check(_play);
|
||||||
|
_panel.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pip::handleMousePress(Qt::MouseButton button) {
|
||||||
|
if (button != Qt::LeftButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_pressed = _over;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pip::handleMouseRelease(Qt::MouseButton button) {
|
||||||
|
const auto pressed = base::take(_pressed);
|
||||||
|
if (button != Qt::LeftButton
|
||||||
|
|| _panel.dragging()
|
||||||
|
|| !pressed
|
||||||
|
|| *pressed != _over) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (_over) {
|
||||||
|
case OverState::Close: _panel.close(); break;
|
||||||
|
case OverState::Enlarge: _closeAndContinue(); break;
|
||||||
|
case OverState::Other: playbackPauseResume(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pip::setupButtons() {
|
||||||
|
_close.state = OverState::Close;
|
||||||
|
_enlarge.state = OverState::Enlarge;
|
||||||
|
_playback.state = OverState::Playback;
|
||||||
|
_play.state = OverState::Other;
|
||||||
|
_panel.sizeValue(
|
||||||
|
) | rpl::map([=] {
|
||||||
|
return _panel.inner();
|
||||||
|
}) | rpl::start_with_next([=](QRect rect) {
|
||||||
|
const auto skip = st::pipControlSkip;
|
||||||
|
_close.area = QRect(
|
||||||
|
rect.x(),
|
||||||
|
rect.y(),
|
||||||
|
st::pipCloseIcon.width() + 2 * skip,
|
||||||
|
st::pipCloseIcon.height() + 2 * skip);
|
||||||
|
_close.icon = _close.area.marginsRemoved({ skip, skip, skip, skip });
|
||||||
|
_enlarge.area = _enlarge.icon = QRect(
|
||||||
|
rect.x() + rect.width() - 2 * skip - st::pipEnlargeIcon.width(),
|
||||||
|
rect.y(),
|
||||||
|
st::pipEnlargeIcon.width() + 2 * skip,
|
||||||
|
st::pipEnlargeIcon.height() + 2 * skip);
|
||||||
|
_enlarge.icon = _enlarge.area.marginsRemoved(
|
||||||
|
{ skip, skip, skip, skip });
|
||||||
|
_play.icon = QRect(
|
||||||
|
rect.x() + (rect.width() - st::pipPlayIcon.width()) / 2,
|
||||||
|
(rect.y()
|
||||||
|
+ rect.height()
|
||||||
|
- st::pipPlayBottom
|
||||||
|
- st::pipPlayIcon.height()),
|
||||||
|
st::pipPlayIcon.width(),
|
||||||
|
st::pipPlayIcon.height());
|
||||||
|
const auto playbackHeight = 2 * st::pipPlaybackSkip
|
||||||
|
+ st::pipPlaybackWidth;
|
||||||
|
_playback.area = QRect(
|
||||||
|
rect.x(),
|
||||||
|
rect.y() + rect.height() - playbackHeight,
|
||||||
|
rect.width(),
|
||||||
|
playbackHeight);
|
||||||
|
}, _panel.lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pip::saveGeometry() {
|
void Pip::saveGeometry() {
|
||||||
|
@ -768,9 +856,7 @@ void Pip::updatePlayPauseResumeState(const Player::TrackState &state) {
|
||||||
auto showPause = Player::ShowPauseIcon(state.state);
|
auto showPause = Player::ShowPauseIcon(state.state);
|
||||||
if (showPause != _showPause) {
|
if (showPause != _showPause) {
|
||||||
_showPause = showPause;
|
_showPause = showPause;
|
||||||
_playPauseResume->entity()->setIconOverride(
|
_panel.update();
|
||||||
_showPause ? &st::mediaviewPauseIcon : nullptr,
|
|
||||||
_showPause ? &st::mediaviewPauseIconOver : nullptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -788,10 +874,47 @@ void Pip::setupStreaming() {
|
||||||
|
|
||||||
void Pip::paint(QPainter &p, FrameRequest request) {
|
void Pip::paint(QPainter &p, FrameRequest request) {
|
||||||
const auto image = videoFrameForDirectPaint(request);
|
const auto image = videoFrameForDirectPaint(request);
|
||||||
p.drawImage(QRect{ QPoint(), request.outer / style::DevicePixelRatio() }, image);
|
p.drawImage(
|
||||||
|
QRect{
|
||||||
|
_panel.inner().topLeft(),
|
||||||
|
request.outer / style::DevicePixelRatio() },
|
||||||
|
image);
|
||||||
if (_instance.player().ready()) {
|
if (_instance.player().ready()) {
|
||||||
_instance.markFrameShown();
|
_instance.markFrameShown();
|
||||||
}
|
}
|
||||||
|
paintControls(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pip::paintControls(QPainter &p) {
|
||||||
|
const auto shown = _controlsShown.value(
|
||||||
|
(_over != OverState::None) ? 1. : 0.);
|
||||||
|
if (!shown) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p.setOpacity(shown);
|
||||||
|
|
||||||
|
const auto outer = _panel.width();
|
||||||
|
const auto drawOne = [&](
|
||||||
|
const Button &button,
|
||||||
|
const style::icon &icon,
|
||||||
|
const style::icon &iconOver) {
|
||||||
|
const auto over = button.active.value(
|
||||||
|
(_over == button.state) ? 1. : 0.);
|
||||||
|
if (over < 1.) {
|
||||||
|
icon.paint(p, button.icon.x(), button.icon.y(), outer);
|
||||||
|
}
|
||||||
|
if (over > 0.) {
|
||||||
|
p.setOpacity(over * shown);
|
||||||
|
iconOver.paint(p, button.icon.x(), button.icon.y(), outer);
|
||||||
|
p.setOpacity(shown);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
drawOne(
|
||||||
|
_play,
|
||||||
|
_showPause ? st::pipPauseIcon : st::pipPlayIcon,
|
||||||
|
_showPause ? st::pipPauseIconOver : st::pipPlayIconOver);
|
||||||
|
drawOne(_close, st::pipCloseIcon, st::pipCloseIconOver);
|
||||||
|
drawOne(_enlarge, st::pipEnlargeIcon, st::pipEnlargeIconOver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pip::handleStreamingUpdate(Streaming::Update &&update) {
|
void Pip::handleStreamingUpdate(Streaming::Update &&update) {
|
||||||
|
@ -906,6 +1029,20 @@ QImage Pip::videoFrameForDirectPaint(const FrameRequest &request) const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pip::OverState Pip::computeState(QPoint position) const {
|
||||||
|
if (!_panel.inner().contains(position)) {
|
||||||
|
return OverState::None;
|
||||||
|
} else if (_close.area.contains(position)) {
|
||||||
|
return OverState::Close;
|
||||||
|
} else if (_enlarge.area.contains(position)) {
|
||||||
|
return OverState::Enlarge;
|
||||||
|
} else if (_playback.area.contains(position)) {
|
||||||
|
return OverState::Playback;
|
||||||
|
} else {
|
||||||
|
return OverState::Other;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Pip::waitingAnimationCallback() {
|
void Pip::waitingAnimationCallback() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,8 @@ public:
|
||||||
void setAspectRatio(QSize ratio);
|
void setAspectRatio(QSize ratio);
|
||||||
[[nodiscard]] Position countPosition() const;
|
[[nodiscard]] Position countPosition() const;
|
||||||
void setPosition(Position position);
|
void setPosition(Position position);
|
||||||
|
[[nodiscard]] QRect inner() const;
|
||||||
|
[[nodiscard]] bool dragging() const;
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> saveGeometryRequests() const;
|
[[nodiscard]] rpl::producer<> saveGeometryRequests() const;
|
||||||
|
|
||||||
|
@ -113,6 +115,19 @@ public:
|
||||||
FnMut<void()> destroy);
|
FnMut<void()> destroy);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class OverState {
|
||||||
|
None,
|
||||||
|
Close,
|
||||||
|
Enlarge,
|
||||||
|
Playback,
|
||||||
|
Other,
|
||||||
|
};
|
||||||
|
struct Button {
|
||||||
|
QRect area;
|
||||||
|
QRect icon;
|
||||||
|
OverState state = OverState::None;
|
||||||
|
Ui::Animations::Simple active;
|
||||||
|
};
|
||||||
using FrameRequest = Streaming::FrameRequest;
|
using FrameRequest = Streaming::FrameRequest;
|
||||||
|
|
||||||
void setupPanel();
|
void setupPanel();
|
||||||
|
@ -132,16 +147,30 @@ private:
|
||||||
[[nodiscard]] QImage videoFrame(const FrameRequest &request) const;
|
[[nodiscard]] QImage videoFrame(const FrameRequest &request) const;
|
||||||
[[nodiscard]] QImage videoFrameForDirectPaint(
|
[[nodiscard]] QImage videoFrameForDirectPaint(
|
||||||
const FrameRequest &request) const;
|
const FrameRequest &request) const;
|
||||||
|
[[nodiscard]] OverState computeState(QPoint position) const;
|
||||||
|
void setOverState(OverState state);
|
||||||
|
|
||||||
|
void handleMouseMove(QPoint position);
|
||||||
|
void handleMousePress(Qt::MouseButton button);
|
||||||
|
void handleMouseRelease(Qt::MouseButton button);
|
||||||
|
void handleLeave();
|
||||||
|
void handleClose();
|
||||||
|
|
||||||
|
void paintControls(QPainter &p);
|
||||||
|
|
||||||
const not_null<Delegate*> _delegate;
|
const not_null<Delegate*> _delegate;
|
||||||
Streaming::Instance _instance;
|
Streaming::Instance _instance;
|
||||||
PipPanel _panel;
|
PipPanel _panel;
|
||||||
QSize _size;
|
QSize _size;
|
||||||
|
|
||||||
base::unique_qptr<Ui::FadeWrap<Ui::IconButton>> _playPauseResume;
|
|
||||||
base::unique_qptr< Ui::FadeWrap<Ui::IconButton>> _pictureInPicture;
|
|
||||||
base::unique_qptr< Ui::FadeWrap<Ui::IconButton>> _close;
|
|
||||||
bool _showPause = false;
|
bool _showPause = false;
|
||||||
|
OverState _over = OverState::None;
|
||||||
|
std::optional<OverState> _pressed;
|
||||||
|
Button _close;
|
||||||
|
Button _enlarge;
|
||||||
|
Button _playback;
|
||||||
|
Button _play;
|
||||||
|
Ui::Animations::Simple _controlsShown;
|
||||||
|
|
||||||
FnMut<void()> _closeAndContinue;
|
FnMut<void()> _closeAndContinue;
|
||||||
FnMut<void()> _destroy;
|
FnMut<void()> _destroy;
|
||||||
|
|
|
@ -31,10 +31,9 @@ PlaybackControls::PlaybackControls(
|
||||||
, _playbackProgress(std::make_unique<PlaybackProgress>())
|
, _playbackProgress(std::make_unique<PlaybackProgress>())
|
||||||
, _volumeToggle(this, st::mediaviewVolumeToggle)
|
, _volumeToggle(this, st::mediaviewVolumeToggle)
|
||||||
, _volumeController(this, st::mediaviewPlayback)
|
, _volumeController(this, st::mediaviewPlayback)
|
||||||
, _speedController(this, st::mediaviewPlayback)
|
, _menuToggle(this, st::mediaviewMenuToggle)
|
||||||
, _speedLabel(this, st::mediaviewPlayProgressLabel)
|
|
||||||
, _fullScreenToggle(this, st::mediaviewFullScreenButton)
|
, _fullScreenToggle(this, st::mediaviewFullScreenButton)
|
||||||
, _pictureInPicture(this, st::mediaviewFullScreenButton)
|
, _pictureInPicture(this, st::mediaviewPipButton)
|
||||||
, _playedAlready(this, st::mediaviewPlayProgressLabel)
|
, _playedAlready(this, st::mediaviewPlayProgressLabel)
|
||||||
, _toPlayLeft(this, st::mediaviewPlayProgressLabel)
|
, _toPlayLeft(this, st::mediaviewPlayProgressLabel)
|
||||||
, _fadeAnimation(std::make_unique<Ui::FadeAnimation>(this)) {
|
, _fadeAnimation(std::make_unique<Ui::FadeAnimation>(this)) {
|
||||||
|
@ -46,9 +45,6 @@ PlaybackControls::PlaybackControls(
|
||||||
fadeUpdated(opacity);
|
fadeUpdated(opacity);
|
||||||
});
|
});
|
||||||
|
|
||||||
_pictureInPicture->setIconOverride(
|
|
||||||
&st::mediaviewFullScreenOutIcon,
|
|
||||||
&st::mediaviewFullScreenOutIconOver);
|
|
||||||
_pictureInPicture->addClickHandler([=] {
|
_pictureInPicture->addClickHandler([=] {
|
||||||
_delegate->playbackControlsToPictureInPicture();
|
_delegate->playbackControlsToPictureInPicture();
|
||||||
});
|
});
|
||||||
|
@ -68,14 +64,6 @@ PlaybackControls::PlaybackControls(
|
||||||
updateVolumeToggleIcon();
|
updateVolumeToggleIcon();
|
||||||
});
|
});
|
||||||
|
|
||||||
_speedController->setPseudoDiscrete(
|
|
||||||
7,
|
|
||||||
[=](int index) { return (index + 2) / 4.; },
|
|
||||||
_delegate->playbackControlsCurrentSpeed(),
|
|
||||||
[=](float64 speed) { updatePlaybackSpeed(speed); });
|
|
||||||
updatePlaybackSpeed(_delegate->playbackControlsCurrentSpeed());
|
|
||||||
_speedController->setAlwaysDisplayMarker(false);
|
|
||||||
|
|
||||||
_playPauseResume->addClickHandler([=] {
|
_playPauseResume->addClickHandler([=] {
|
||||||
if (_showPause) {
|
if (_showPause) {
|
||||||
_delegate->playbackControlsPause();
|
_delegate->playbackControlsPause();
|
||||||
|
@ -142,7 +130,6 @@ void PlaybackControls::startFading(Callback start) {
|
||||||
showChildren();
|
showChildren();
|
||||||
_playbackSlider->disablePaint(true);
|
_playbackSlider->disablePaint(true);
|
||||||
_volumeController->disablePaint(true);
|
_volumeController->disablePaint(true);
|
||||||
_speedController->disablePaint(true);
|
|
||||||
_childrenHidden = false;
|
_childrenHidden = false;
|
||||||
}
|
}
|
||||||
start();
|
start();
|
||||||
|
@ -150,8 +137,7 @@ void PlaybackControls::startFading(Callback start) {
|
||||||
for (const auto child : children()) {
|
for (const auto child : children()) {
|
||||||
if (child->isWidgetType()
|
if (child->isWidgetType()
|
||||||
&& child != _playbackSlider
|
&& child != _playbackSlider
|
||||||
&& child != _volumeController
|
&& child != _volumeController) {
|
||||||
&& child != _speedController) {
|
|
||||||
static_cast<QWidget*>(child)->hide();
|
static_cast<QWidget*>(child)->hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +147,6 @@ void PlaybackControls::startFading(Callback start) {
|
||||||
}
|
}
|
||||||
_playbackSlider->disablePaint(false);
|
_playbackSlider->disablePaint(false);
|
||||||
_volumeController->disablePaint(false);
|
_volumeController->disablePaint(false);
|
||||||
_speedController->disablePaint(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaybackControls::showAnimated() {
|
void PlaybackControls::showAnimated() {
|
||||||
|
@ -183,14 +168,10 @@ void PlaybackControls::fadeFinished() {
|
||||||
void PlaybackControls::fadeUpdated(float64 opacity) {
|
void PlaybackControls::fadeUpdated(float64 opacity) {
|
||||||
_playbackSlider->setFadeOpacity(opacity);
|
_playbackSlider->setFadeOpacity(opacity);
|
||||||
_volumeController->setFadeOpacity(opacity);
|
_volumeController->setFadeOpacity(opacity);
|
||||||
_speedController->setFadeOpacity(opacity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaybackControls::updatePlaybackSpeed(float64 speed) {
|
void PlaybackControls::updatePlaybackSpeed(float64 speed) {
|
||||||
_delegate->playbackControlsSpeedChanged(speed);
|
_delegate->playbackControlsSpeedChanged(speed);
|
||||||
//const auto percent = int(std::round(speed * 100.));
|
|
||||||
//_speedLabel->setText(QString::number(percent) + '%');
|
|
||||||
_speedLabel->setText(QString::number(speed) + 'x');
|
|
||||||
resizeEvent(nullptr);
|
resizeEvent(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,19 +186,15 @@ void PlaybackControls::updateVolumeToggleIcon() {
|
||||||
_volumeToggle->setIconOverride([&] {
|
_volumeToggle->setIconOverride([&] {
|
||||||
return (volume <= 0.)
|
return (volume <= 0.)
|
||||||
? nullptr
|
? nullptr
|
||||||
: (volume < 1 / 3.)
|
: (volume < 1 / 2.)
|
||||||
? &st::mediaviewVolumeIcon1
|
? &st::mediaviewVolumeIcon1
|
||||||
: (volume < 2 / 3.)
|
: &st::mediaviewVolumeIcon2;
|
||||||
? &st::mediaviewVolumeIcon2
|
|
||||||
: &st::mediaviewVolumeIcon3;
|
|
||||||
}(), [&] {
|
}(), [&] {
|
||||||
return (volume <= 0.)
|
return (volume <= 0.)
|
||||||
? nullptr
|
? nullptr
|
||||||
: (volume < 1 / 3.)
|
: (volume < 1 / 2.)
|
||||||
? &st::mediaviewVolumeIcon1Over
|
? &st::mediaviewVolumeIcon1Over
|
||||||
: (volume < 2 / 3.)
|
: &st::mediaviewVolumeIcon2Over;
|
||||||
? &st::mediaviewVolumeIcon2Over
|
|
||||||
: &st::mediaviewVolumeIcon3Over;
|
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,14 +226,8 @@ void PlaybackControls::setLoadingProgress(int ready, int total) {
|
||||||
const auto percent = int(std::round(progress * 100));
|
const auto percent = int(std::round(progress * 100));
|
||||||
if (_loadingPercent != percent) {
|
if (_loadingPercent != percent) {
|
||||||
_loadingPercent = percent;
|
_loadingPercent = percent;
|
||||||
_downloadProgress->setText(tr::lng_mediaview_video_loading(
|
_downloadProgress->setText(QString::number(percent) + '%');
|
||||||
tr::now,
|
updateDownloadProgressPosition();
|
||||||
lt_percent,
|
|
||||||
QString::number(percent) + '%'));
|
|
||||||
if (_playbackSlider->width() > _downloadProgress->width()) {
|
|
||||||
const auto left = (_playbackSlider->width() - _downloadProgress->width()) / 2;
|
|
||||||
_downloadProgress->move(_playbackSlider->x() + left, st::mediaviewPlayProgressTop);
|
|
||||||
}
|
|
||||||
refreshFadeCache();
|
refreshFadeCache();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -337,44 +308,48 @@ void PlaybackControls::setInFullScreen(bool inFullScreen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaybackControls::resizeEvent(QResizeEvent *e) {
|
void PlaybackControls::resizeEvent(QResizeEvent *e) {
|
||||||
const auto skip = st::mediaviewFullScreenLeft;
|
const auto textSkip = st::mediaviewPlayProgressSkip;
|
||||||
|
const auto textLeft = st::mediaviewPlayProgressLeft;
|
||||||
auto playbackWidth = width() - 2 * skip;
|
const auto textTop = st::mediaviewPlaybackTop + (_playbackSlider->height() - _playedAlready->height()) / 2;
|
||||||
|
_playedAlready->moveToLeft(textLeft + textSkip, textTop);
|
||||||
|
_toPlayLeft->moveToRight(textLeft + textSkip, textTop);
|
||||||
|
const auto remove = 2 * textLeft + 4 * textSkip + _playedAlready->width() + _toPlayLeft->width();
|
||||||
|
auto playbackWidth = width() - remove;
|
||||||
_playbackSlider->resize(playbackWidth, st::mediaviewPlayback.seekSize.height());
|
_playbackSlider->resize(playbackWidth, st::mediaviewPlayback.seekSize.height());
|
||||||
_playbackSlider->moveToLeft(st::mediaviewPlayPauseLeft, st::mediaviewPlaybackTop);
|
_playbackSlider->moveToLeft(textLeft + 2 * textSkip + _playedAlready->width(), st::mediaviewPlaybackTop);
|
||||||
|
|
||||||
_playedAlready->moveToLeft(st::mediaviewPlayPauseLeft, st::mediaviewPlayProgressTop);
|
_playPauseResume->moveToLeft(
|
||||||
_toPlayLeft->moveToRight(st::mediaviewPlayPauseLeft, st::mediaviewPlayProgressTop);
|
(width() - _playPauseResume->width()) / 2,
|
||||||
if (_downloadProgress) {
|
st::mediaviewPlayButtonTop);
|
||||||
const auto left = (_playbackSlider->width() - _downloadProgress->width()) / 2;
|
|
||||||
_downloadProgress->move(_playbackSlider->x() + left, st::mediaviewPlayProgressTop);
|
auto right = st::mediaviewMenuToggleSkip;
|
||||||
|
_menuToggle->moveToRight(right, st::mediaviewButtonsTop);
|
||||||
|
right += _menuToggle->width() + st::mediaviewPipButtonSkip;
|
||||||
|
_pictureInPicture->moveToRight(right, st::mediaviewButtonsTop);
|
||||||
|
right += _pictureInPicture->width() + st::mediaviewFullScreenButtonSkip;
|
||||||
|
_fullScreenToggle->moveToRight(right, st::mediaviewButtonsTop);
|
||||||
|
|
||||||
|
updateDownloadProgressPosition();
|
||||||
|
|
||||||
|
auto left = st::mediaviewVolumeToggleSkip;
|
||||||
|
_volumeToggle->moveToLeft(left, st::mediaviewVolumeTop);
|
||||||
|
left += _volumeToggle->width() + st::mediaviewVolumeSkip;
|
||||||
|
_volumeController->resize(
|
||||||
|
st::mediaviewVolumeWidth,
|
||||||
|
st::mediaviewPlayback.seekSize.height());
|
||||||
|
_volumeController->moveToLeft(left, st::mediaviewVolumeTop + (_volumeToggle->height() - _volumeController->height()) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlaybackControls::updateDownloadProgressPosition() {
|
||||||
|
if (!_downloadProgress) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
const auto left = _playPauseResume->x() + _playPauseResume->width();
|
||||||
auto left = skip;
|
const auto right = _fullScreenToggle->x();
|
||||||
const auto playTop = height() - _playPauseResume->height() - skip;
|
const auto available = right - left;
|
||||||
_playPauseResume->moveToLeft(left, playTop);
|
const auto x = left + (available - _downloadProgress->width()) / 2;
|
||||||
left += _playPauseResume->width() + skip;
|
const auto y = _playPauseResume->y() + (_playPauseResume->height() - _downloadProgress->height()) / 2;
|
||||||
|
_downloadProgress->move(x, y);
|
||||||
_fullScreenToggle->moveToLeft(left, playTop);
|
|
||||||
left += _fullScreenToggle->width() + skip;
|
|
||||||
|
|
||||||
_pictureInPicture->moveToLeft(left, playTop);
|
|
||||||
|
|
||||||
auto right = skip;
|
|
||||||
const auto volumeTop = playTop + (_fullScreenToggle->height() - _volumeController->height()) / 2;
|
|
||||||
const auto volumeIconTop = playTop + (_fullScreenToggle->height() - _volumeToggle->height()) / 2;
|
|
||||||
_volumeController->resize(st::mediaviewVolumeWidth, st::mediaviewPlayback.seekSize.height());
|
|
||||||
_volumeController->moveToRight(right, volumeTop);
|
|
||||||
right += _volumeController->width();
|
|
||||||
_volumeToggle->moveToRight(right, volumeIconTop);
|
|
||||||
right += _volumeToggle->width() + 2 * skip;
|
|
||||||
|
|
||||||
const auto speedTop = volumeTop;
|
|
||||||
const auto speedLabelTop = playTop + (_fullScreenToggle->height() - _speedLabel->height()) / 2;
|
|
||||||
_speedController->resize(st::mediaviewVolumeWidth, st::mediaviewPlayback.seekSize.height());
|
|
||||||
_speedController->moveToRight(right, volumeTop);
|
|
||||||
right += _speedController->width() + st::semiboldFont->spacew * 3;
|
|
||||||
_speedLabel->moveToRight(right, speedLabelTop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaybackControls::paintEvent(QPaintEvent *e) {
|
void PlaybackControls::paintEvent(QPaintEvent *e) {
|
||||||
|
@ -387,7 +362,6 @@ void PlaybackControls::paintEvent(QPaintEvent *e) {
|
||||||
showChildren();
|
showChildren();
|
||||||
_playbackSlider->setFadeOpacity(1.);
|
_playbackSlider->setFadeOpacity(1.);
|
||||||
_volumeController->setFadeOpacity(1.);
|
_volumeController->setFadeOpacity(1.);
|
||||||
_speedController->setFadeOpacity(1.);
|
|
||||||
_childrenHidden = false;
|
_childrenHidden = false;
|
||||||
}
|
}
|
||||||
App::roundRect(p, rect(), st::mediaviewSaveMsgBg, MediaviewSaveCorners);
|
App::roundRect(p, rect(), st::mediaviewSaveMsgBg, MediaviewSaveCorners);
|
||||||
|
|
|
@ -75,6 +75,7 @@ private:
|
||||||
|
|
||||||
void updatePlaybackSpeed(float64 speed);
|
void updatePlaybackSpeed(float64 speed);
|
||||||
void updateVolumeToggleIcon();
|
void updateVolumeToggleIcon();
|
||||||
|
void updateDownloadProgressPosition();
|
||||||
|
|
||||||
void updatePlayPauseResumeState(const Player::TrackState &state);
|
void updatePlayPauseResumeState(const Player::TrackState &state);
|
||||||
void updateTimeTexts(const Player::TrackState &state);
|
void updateTimeTexts(const Player::TrackState &state);
|
||||||
|
@ -98,8 +99,7 @@ private:
|
||||||
std::unique_ptr<PlaybackProgress> _receivedTillProgress;
|
std::unique_ptr<PlaybackProgress> _receivedTillProgress;
|
||||||
object_ptr<Ui::IconButton> _volumeToggle;
|
object_ptr<Ui::IconButton> _volumeToggle;
|
||||||
object_ptr<Ui::MediaSlider> _volumeController;
|
object_ptr<Ui::MediaSlider> _volumeController;
|
||||||
object_ptr<Ui::MediaSlider> _speedController;
|
object_ptr<Ui::IconButton> _menuToggle;
|
||||||
object_ptr<Ui::LabelSimple> _speedLabel;
|
|
||||||
object_ptr<Ui::IconButton> _fullScreenToggle;
|
object_ptr<Ui::IconButton> _fullScreenToggle;
|
||||||
object_ptr<Ui::IconButton> _pictureInPicture;
|
object_ptr<Ui::IconButton> _pictureInPicture;
|
||||||
object_ptr<Ui::LabelSimple> _playedAlready;
|
object_ptr<Ui::LabelSimple> _playedAlready;
|
||||||
|
|
|
@ -20,61 +20,85 @@ mediaviewPlayback: MediaSlider {
|
||||||
activeFgDisabled: mediaviewPlaybackActive;
|
activeFgDisabled: mediaviewPlaybackActive;
|
||||||
inactiveFgDisabled: mediaviewPlaybackInactive;
|
inactiveFgDisabled: mediaviewPlaybackInactive;
|
||||||
receivedTillFg: mediaviewPlaybackInactiveOver;
|
receivedTillFg: mediaviewPlaybackInactiveOver;
|
||||||
seekSize: size(11px, 11px);
|
seekSize: size(12px, 12px);
|
||||||
|
duration: mediaviewOverDuration;
|
||||||
|
}
|
||||||
|
mediaviewPlaybackTop: 52px;
|
||||||
|
|
||||||
|
mediaviewControlsButton: IconButton {
|
||||||
|
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||||
|
color: mediaviewPlaybackIconRipple;
|
||||||
|
}
|
||||||
|
rippleAreaPosition: point(0px, 0px);
|
||||||
duration: mediaviewOverDuration;
|
duration: mediaviewOverDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaviewControllerSize: size(480px, 100px);
|
mediaviewControllerSize: size(481px, 75px);
|
||||||
mediaviewPlayProgressLabel: LabelSimple(defaultLabelSimple) {
|
mediaviewPlayProgressLabel: LabelSimple(defaultLabelSimple) {
|
||||||
font: semiboldFont;
|
font: semiboldFont;
|
||||||
textFg: mediaviewPlaybackProgressFg;
|
textFg: mediaviewPlaybackProgressFg;
|
||||||
}
|
}
|
||||||
mediaviewPlayProgressTop: 11px;
|
mediaviewPlayProgressSkip: 8px;
|
||||||
mediaviewPlayButton: IconButton {
|
mediaviewPlayProgressLeft: 8px;
|
||||||
width: 25px;
|
mediaviewPlayButtonTop: 5px;
|
||||||
height: 24px;
|
mediaviewPlayButton: IconButton(mediaviewControlsButton) {
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
rippleAreaSize: 42px;
|
||||||
|
|
||||||
icon: icon {{ "media_play", mediaviewPlaybackIconFg, point(3px, 0px) }};
|
icon: icon {{ "player_play", mediaviewPlaybackIconFg }};
|
||||||
iconOver: icon {{ "media_play", mediaviewPlaybackIconFgOver, point(3px, 0px) }};
|
iconOver: icon {{ "player_play", mediaviewPlaybackIconFgOver }};
|
||||||
iconPosition: point(3px, 1px);
|
iconPosition: point(9px, 9px);
|
||||||
|
|
||||||
duration: mediaviewOverDuration;
|
|
||||||
}
|
}
|
||||||
mediaviewPauseIcon: icon {{ "media_pause", mediaviewPlaybackIconFg, point(1px, 1px) }};
|
mediaviewPauseIcon: icon {{ "player_pause", mediaviewPlaybackIconFg }};
|
||||||
mediaviewPauseIconOver: icon {{ "media_pause", mediaviewPlaybackIconFgOver, point(1px, 1px) }};
|
mediaviewPauseIconOver: icon {{ "player_pause", mediaviewPlaybackIconFgOver }};
|
||||||
mediaviewPlayPauseLeft: 17px;
|
|
||||||
mediaviewFullScreenLeft: 17px;
|
|
||||||
mediaviewVolumeLeft: 7px;
|
|
||||||
|
|
||||||
mediaviewFullScreenButton: IconButton(mediaviewPlayButton) {
|
mediaviewButtonsTop: 7px;
|
||||||
icon: icon {{ "media_fullscreen_to", mediaviewPlaybackIconFg, point(0px, 0px) }};
|
|
||||||
iconOver: icon {{ "media_fullscreen_to", mediaviewPlaybackIconFgOver, point(0px, 0px) }};
|
mediaviewMenuToggleSkip: 4px;
|
||||||
iconPosition: point(0px, 1px);
|
mediaviewMenuToggle: IconButton(mediaviewControlsButton) {
|
||||||
|
width: 34px;
|
||||||
|
height: 34px;
|
||||||
|
rippleAreaSize: 34px;
|
||||||
|
icon: icon {{ "player_more", mediaviewPlaybackIconFg }};
|
||||||
|
iconOver: icon {{ "player_more", mediaviewPlaybackIconFgOver }};
|
||||||
|
iconPosition: point(5px, 5px);
|
||||||
}
|
}
|
||||||
mediaviewFullScreenOutIcon: icon {{ "media_fullscreen_from", mediaviewPlaybackIconFg, point(0px, 0px) }};
|
|
||||||
mediaviewFullScreenOutIconOver: icon {{ "media_fullscreen_from", mediaviewPlaybackIconFgOver, point(0px, 0px) }};
|
|
||||||
|
|
||||||
mediaviewPlaybackTop: 28px;
|
mediaviewPipButtonSkip: 5px;
|
||||||
|
mediaviewPipButton: IconButton(mediaviewMenuToggle) {
|
||||||
|
icon: icon {{ "player_pip", mediaviewPlaybackIconFg }};
|
||||||
|
iconOver: icon {{ "player_pip", mediaviewPlaybackIconFgOver }};
|
||||||
|
}
|
||||||
|
|
||||||
mediaviewVolumeWidth: 60px;
|
mediaviewFullScreenButtonSkip: 8px;
|
||||||
mediaviewControllerRadius: roundRadiusLarge;
|
mediaviewFullScreenButton: IconButton(mediaviewMenuToggle) {
|
||||||
|
icon: icon {{ "player_fullscreen", mediaviewPlaybackIconFg }};
|
||||||
|
iconOver: icon {{ "player_fullscreen", mediaviewPlaybackIconFgOver }};
|
||||||
|
}
|
||||||
|
mediaviewFullScreenOutIcon: icon {{ "player_minimize", mediaviewPlaybackIconFg }};
|
||||||
|
mediaviewFullScreenOutIconOver: icon {{ "player_minimize", mediaviewPlaybackIconFgOver }};
|
||||||
|
|
||||||
mediaviewVolumeIcon0: icon {{ "player_volume0", mediaviewPlaybackIconFg }};
|
mediaviewVolumeWidth: 75px;
|
||||||
mediaviewVolumeIcon0Over: icon {{ "player_volume0", mediaviewPlaybackIconFgOver }};
|
mediaviewControllerRadius: 9px;
|
||||||
mediaviewVolumeIcon1: icon {{ "player_volume1", mediaviewPlaybackIconFg }};
|
|
||||||
mediaviewVolumeIcon1Over: icon {{ "player_volume1", mediaviewPlaybackIconFgOver }};
|
|
||||||
mediaviewVolumeIcon2: icon {{ "player_volume2", mediaviewPlaybackIconFg }};
|
|
||||||
mediaviewVolumeIcon2Over: icon {{ "player_volume2", mediaviewPlaybackIconFgOver }};
|
|
||||||
mediaviewVolumeIcon3: icon {{ "player_volume3", mediaviewPlaybackIconFg }};
|
|
||||||
mediaviewVolumeIcon3Over: icon {{ "player_volume3", mediaviewPlaybackIconFgOver }};
|
|
||||||
mediaviewVolumeToggle: IconButton {
|
|
||||||
width: 31px;
|
|
||||||
height: 29px;
|
|
||||||
|
|
||||||
|
mediaviewVolumeIcon0: icon {{ "player_volume_off", mediaviewPlaybackIconFg }};
|
||||||
|
mediaviewVolumeIcon0Over: icon {{ "player_volume_off", mediaviewPlaybackIconFgOver }};
|
||||||
|
mediaviewVolumeIcon1: icon {{ "player_volume_small", mediaviewPlaybackIconFg }};
|
||||||
|
mediaviewVolumeIcon1Over: icon {{ "player_volume_small", mediaviewPlaybackIconFgOver }};
|
||||||
|
mediaviewVolumeIcon2: icon {{ "player_volume_on", mediaviewPlaybackIconFg }};
|
||||||
|
mediaviewVolumeIcon2Over: icon {{ "player_volume_on", mediaviewPlaybackIconFgOver }};
|
||||||
|
mediaviewVolumeTop: 10px;
|
||||||
|
mediaviewVolumeToggleSkip: 11px;
|
||||||
|
mediaviewVolumeToggle: IconButton(mediaviewControlsButton) {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
rippleAreaSize: 30px;
|
||||||
icon: mediaviewVolumeIcon0;
|
icon: mediaviewVolumeIcon0;
|
||||||
iconOver: mediaviewVolumeIcon0Over;
|
iconOver: mediaviewVolumeIcon0Over;
|
||||||
iconPosition: point(8px, 8px);
|
iconPosition: point(3px, 3px);
|
||||||
}
|
}
|
||||||
|
mediaviewVolumeSkip: 4px;
|
||||||
|
|
||||||
mediaviewLeft: icon {{ "mediaview_next-flip_horizontal", mediaviewControlFg }};
|
mediaviewLeft: icon {{ "mediaview_next-flip_horizontal", mediaviewControlFg }};
|
||||||
mediaviewRight: icon {{ "mediaview_next", mediaviewControlFg }};
|
mediaviewRight: icon {{ "mediaview_next", mediaviewControlFg }};
|
||||||
|
@ -229,4 +253,16 @@ pipDefaultSize: 320px;
|
||||||
pipMinimalSize: 100px;
|
pipMinimalSize: 100px;
|
||||||
pipBorderSkip: 20px;
|
pipBorderSkip: 20px;
|
||||||
pipBorderSnapArea: 16px;
|
pipBorderSnapArea: 16px;
|
||||||
pipResizeArea: 10px;
|
pipResizeArea: 10px;
|
||||||
|
pipControlSkip: 6px;
|
||||||
|
pipPlaybackWidth: 2px;
|
||||||
|
pipPlaybackSkip: 4px;
|
||||||
|
pipPlayBottom: 16px;
|
||||||
|
pipPlayIcon: icon {{ "player_pip_play", mediaviewPipControlsFg }};
|
||||||
|
pipPlayIconOver: icon {{ "player_pip_play", mediaviewPipControlsFgOver }};
|
||||||
|
pipPauseIcon: icon {{ "player_pip_pause", mediaviewPipControlsFg }};
|
||||||
|
pipPauseIconOver: icon {{ "player_pip_pause", mediaviewPipControlsFgOver }};
|
||||||
|
pipCloseIcon: icon {{ "player_pip_close", mediaviewPlaybackIconFg }};
|
||||||
|
pipCloseIconOver: icon {{ "player_pip_close", mediaviewPlaybackIconFgOver }};
|
||||||
|
pipEnlargeIcon: icon {{ "player_pip_enlarge", mediaviewPlaybackIconFg }};
|
||||||
|
pipEnlargeIconOver: icon {{ "player_pip_enlarge", mediaviewPlaybackIconFgOver }};
|
||||||
|
|