mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Improve volume slider design in group calls.
This commit is contained in:
parent
55e494f55a
commit
ec234cdc43
6 changed files with 139 additions and 65 deletions
|
@ -490,6 +490,7 @@ groupCallMenu: Menu(defaultMenu) {
|
||||||
itemFgShortcutDisabled: groupCallMemberNotJoinedStatus;
|
itemFgShortcutDisabled: groupCallMemberNotJoinedStatus;
|
||||||
|
|
||||||
separatorFg: groupCallMenuBgOver;
|
separatorFg: groupCallMenuBgOver;
|
||||||
|
separatorPadding: margins(0px, 4px, 0px, 4px);
|
||||||
|
|
||||||
arrow: icon {{ "dropdown_submenu_arrow", groupCallMemberNotJoinedStatus }};
|
arrow: icon {{ "dropdown_submenu_arrow", groupCallMemberNotJoinedStatus }};
|
||||||
|
|
||||||
|
@ -513,6 +514,12 @@ groupCallPopupMenu: PopupMenu(defaultPopupMenu) {
|
||||||
menu: groupCallMenu;
|
menu: groupCallMenu;
|
||||||
animation: groupCallPanelAnimation;
|
animation: groupCallPanelAnimation;
|
||||||
}
|
}
|
||||||
|
groupCallPopupMenuWithVolume: PopupMenu(groupCallPopupMenu) {
|
||||||
|
scrollPadding: margins(0px, 3px, 0px, 8px);
|
||||||
|
menu: Menu(groupCallMenu) {
|
||||||
|
widthMin: 210px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
groupCallRecordingTimerPadding: margins(0px, 4px, 0px, 4px);
|
groupCallRecordingTimerPadding: margins(0px, 4px, 0px, 4px);
|
||||||
groupCallRecordingTimerFont: font(12px);
|
groupCallRecordingTimerFont: font(12px);
|
||||||
|
@ -1071,6 +1078,8 @@ groupCallMuteCrossLine: CrossLineAnimation {
|
||||||
|
|
||||||
groupCallMenuSpeakerArcsSkip: 1px;
|
groupCallMenuSpeakerArcsSkip: 1px;
|
||||||
groupCallMenuVolumeSkip: 5px;
|
groupCallMenuVolumeSkip: 5px;
|
||||||
|
groupCallMenuVolumePadding: margins(17px, 6px, 17px, 5px);
|
||||||
|
groupCallMenuVolumeMargin: margins(55px, 0px, 15px, 0px);
|
||||||
groupCallMenuVolumeSlider: MediaSlider(defaultContinuousSlider) {
|
groupCallMenuVolumeSlider: MediaSlider(defaultContinuousSlider) {
|
||||||
activeFg: groupCallMembersFg;
|
activeFg: groupCallMembersFg;
|
||||||
inactiveFg: groupCallMemberInactiveIcon;
|
inactiveFg: groupCallMemberInactiveIcon;
|
||||||
|
@ -1078,6 +1087,8 @@ groupCallMenuVolumeSlider: MediaSlider(defaultContinuousSlider) {
|
||||||
inactiveFgOver: groupCallMemberInactiveIcon;
|
inactiveFgOver: groupCallMemberInactiveIcon;
|
||||||
activeFgDisabled: groupCallMemberInactiveIcon;
|
activeFgDisabled: groupCallMemberInactiveIcon;
|
||||||
receivedTillFg: groupCallMemberInactiveIcon;
|
receivedTillFg: groupCallMemberInactiveIcon;
|
||||||
|
width: 7px;
|
||||||
|
seekSize: size(7px, 7px);
|
||||||
}
|
}
|
||||||
|
|
||||||
groupCallSpeakerArcsAnimation: ArcsAnimation {
|
groupCallSpeakerArcsAnimation: ArcsAnimation {
|
||||||
|
|
|
@ -1236,12 +1236,10 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
|
||||||
not_null<PeerListRow*> row) {
|
not_null<PeerListRow*> row) {
|
||||||
const auto participantPeer = row->peer();
|
const auto participantPeer = row->peer();
|
||||||
const auto real = static_cast<Row*>(row.get());
|
const auto real = static_cast<Row*>(row.get());
|
||||||
|
|
||||||
auto result = base::make_unique_q<Ui::PopupMenu>(
|
|
||||||
parent,
|
|
||||||
st::groupCallPopupMenu);
|
|
||||||
|
|
||||||
const auto muteState = real->state();
|
const auto muteState = real->state();
|
||||||
|
const auto muted = (muteState == Row::State::Muted)
|
||||||
|
|| (muteState == Row::State::RaisedHand);
|
||||||
|
const auto addVolumeItem = !muted || isMe(participantPeer);
|
||||||
const auto admin = IsGroupCallAdmin(_peer, participantPeer);
|
const auto admin = IsGroupCallAdmin(_peer, participantPeer);
|
||||||
const auto session = &_peer->session();
|
const auto session = &_peer->session();
|
||||||
const auto getCurrentWindow = [=]() -> Window::SessionController* {
|
const auto getCurrentWindow = [=]() -> Window::SessionController* {
|
||||||
|
@ -1262,6 +1260,12 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
|
||||||
}
|
}
|
||||||
return getCurrentWindow();
|
return getCurrentWindow();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto result = base::make_unique_q<Ui::PopupMenu>(
|
||||||
|
parent,
|
||||||
|
(addVolumeItem
|
||||||
|
? st::groupCallPopupMenuWithVolume
|
||||||
|
: st::groupCallPopupMenu));
|
||||||
const auto weakMenu = Ui::MakeWeak(result.get());
|
const auto weakMenu = Ui::MakeWeak(result.get());
|
||||||
const auto performOnMainWindow = [=](auto callback) {
|
const auto performOnMainWindow = [=](auto callback) {
|
||||||
if (const auto window = getWindow()) {
|
if (const auto window = getWindow()) {
|
||||||
|
@ -1442,7 +1446,8 @@ void Members::Controller::addMuteActionsToContextMenu(
|
||||||
|
|
||||||
auto mutesFromVolume = rpl::never<bool>() | rpl::type_erased();
|
auto mutesFromVolume = rpl::never<bool>() | rpl::type_erased();
|
||||||
|
|
||||||
if (!muted || _call->joinAs() == participantPeer) {
|
const auto addVolumeItem = !muted || isMe(participantPeer);
|
||||||
|
if (addVolumeItem) {
|
||||||
auto otherParticipantStateValue
|
auto otherParticipantStateValue
|
||||||
= _call->otherParticipantStateValue(
|
= _call->otherParticipantStateValue(
|
||||||
) | rpl::filter([=](const Group::ParticipantState &data) {
|
) | rpl::filter([=](const Group::ParticipantState &data) {
|
||||||
|
@ -1451,7 +1456,7 @@ void Members::Controller::addMuteActionsToContextMenu(
|
||||||
|
|
||||||
auto volumeItem = base::make_unique_q<MenuVolumeItem>(
|
auto volumeItem = base::make_unique_q<MenuVolumeItem>(
|
||||||
menu->menu(),
|
menu->menu(),
|
||||||
st::groupCallPopupMenu.menu,
|
st::groupCallPopupMenuWithVolume.menu,
|
||||||
otherParticipantStateValue,
|
otherParticipantStateValue,
|
||||||
row->volume(),
|
row->volume(),
|
||||||
Group::kMaxVolume,
|
Group::kMaxVolume,
|
||||||
|
@ -1491,6 +1496,10 @@ void Members::Controller::addMuteActionsToContextMenu(
|
||||||
}, volumeItem->lifetime());
|
}, volumeItem->lifetime());
|
||||||
|
|
||||||
menu->addAction(std::move(volumeItem));
|
menu->addAction(std::move(volumeItem));
|
||||||
|
|
||||||
|
if (!isMe(participantPeer)) {
|
||||||
|
menu->addSeparator();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto muteAction = [&]() -> QAction* {
|
const auto muteAction = [&]() -> QAction* {
|
||||||
|
|
|
@ -36,10 +36,6 @@ constexpr auto kVolumeStickedValues =
|
||||||
{ 175. / kMaxVolumePercent, 2. / kMaxVolumePercent },
|
{ 175. / kMaxVolumePercent, 2. / kMaxVolumePercent },
|
||||||
}};
|
}};
|
||||||
|
|
||||||
QString VolumeString(int volumePercent) {
|
|
||||||
return u"%1%"_q.arg(volumePercent);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
MenuVolumeItem::MenuVolumeItem(
|
MenuVolumeItem::MenuVolumeItem(
|
||||||
|
@ -75,20 +71,21 @@ MenuVolumeItem::MenuVolumeItem(
|
||||||
sizeValue(
|
sizeValue(
|
||||||
) | rpl::start_with_next([=](const QSize &size) {
|
) | rpl::start_with_next([=](const QSize &size) {
|
||||||
const auto geometry = QRect(QPoint(), size);
|
const auto geometry = QRect(QPoint(), size);
|
||||||
_itemRect = geometry - _st.itemPadding;
|
_itemRect = geometry - st::groupCallMenuVolumePadding;
|
||||||
_speakerRect = QRect(_itemRect.topLeft(), _stCross.icon.size());
|
_speakerRect = QRect(_itemRect.topLeft(), _stCross.icon.size());
|
||||||
_arcPosition = _speakerRect.center()
|
_arcPosition = _speakerRect.center()
|
||||||
+ QPoint(0, st::groupCallMenuSpeakerArcsSkip);
|
+ QPoint(0, st::groupCallMenuSpeakerArcsSkip);
|
||||||
_volumeRect = QRect(
|
const auto sliderLeft = _arcPosition.x()
|
||||||
_arcPosition.x()
|
+ st::groupCallMenuVolumeSkip
|
||||||
+ st::groupCallMenuVolumeSkip
|
+ _arcs->maxWidth()
|
||||||
+ _arcs->finishedWidth(),
|
+ st::groupCallMenuVolumeSkip;
|
||||||
|
_slider->setGeometry(
|
||||||
|
st::groupCallMenuVolumeMargin.left(),
|
||||||
_speakerRect.y(),
|
_speakerRect.y(),
|
||||||
_st.itemStyle.font->width(VolumeString(kMaxVolumePercent)),
|
(geometry.width()
|
||||||
|
- st::groupCallMenuVolumeMargin.left()
|
||||||
|
- st::groupCallMenuVolumeMargin.right()),
|
||||||
_speakerRect.height());
|
_speakerRect.height());
|
||||||
|
|
||||||
_slider->setGeometry(_itemRect
|
|
||||||
- style::margins(0, contentHeight() / 2, 0, 0));
|
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
setCloudVolume(startVolume);
|
setCloudVolume(startVolume);
|
||||||
|
@ -110,15 +107,12 @@ MenuVolumeItem::MenuVolumeItem(
|
||||||
unmuteColor(),
|
unmuteColor(),
|
||||||
muteColor(),
|
muteColor(),
|
||||||
muteProgress);
|
muteProgress);
|
||||||
p.setPen(mutePen);
|
|
||||||
p.setFont(_st.itemStyle.font);
|
|
||||||
p.drawText(_volumeRect, VolumeString(volume), style::al_left);
|
|
||||||
|
|
||||||
_crossLineMute->paint(
|
_crossLineMute->paint(
|
||||||
p,
|
p,
|
||||||
_speakerRect.topLeft(),
|
_speakerRect.topLeft(),
|
||||||
muteProgress,
|
muteProgress,
|
||||||
(!muteProgress) ? std::nullopt : std::optional<QColor>(mutePen));
|
(muteProgress > 0) ? std::make_optional(mutePen) : std::nullopt);
|
||||||
|
|
||||||
{
|
{
|
||||||
p.translate(_arcPosition);
|
p.translate(_arcPosition);
|
||||||
|
@ -133,7 +127,7 @@ MenuVolumeItem::MenuVolumeItem(
|
||||||
_toggleMuteLocallyRequests.fire_copy(newMuted);
|
_toggleMuteLocallyRequests.fire_copy(newMuted);
|
||||||
|
|
||||||
_crossLineAnimation.start(
|
_crossLineAnimation.start(
|
||||||
[=] { update(_speakerRect.united(_volumeRect)); },
|
[=] { update(_speakerRect); },
|
||||||
_localMuted ? 0. : 1.,
|
_localMuted ? 0. : 1.,
|
||||||
_localMuted ? 1. : 0.,
|
_localMuted ? 1. : 0.,
|
||||||
st::callPanelDuration);
|
st::callPanelDuration);
|
||||||
|
@ -141,8 +135,8 @@ MenuVolumeItem::MenuVolumeItem(
|
||||||
if (value > 0) {
|
if (value > 0) {
|
||||||
_changeVolumeLocallyRequests.fire(value * _maxVolume);
|
_changeVolumeLocallyRequests.fire(value * _maxVolume);
|
||||||
}
|
}
|
||||||
update(_volumeRect);
|
|
||||||
_arcs->setValue(value);
|
_arcs->setValue(value);
|
||||||
|
updateSliderColor(value);
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto returnVolume = [=] {
|
const auto returnVolume = [=] {
|
||||||
|
@ -169,6 +163,7 @@ MenuVolumeItem::MenuVolumeItem(
|
||||||
if (!_cloudMuted && !muted) {
|
if (!_cloudMuted && !muted) {
|
||||||
_changeVolumeRequests.fire_copy(newVolume);
|
_changeVolumeRequests.fire_copy(newVolume);
|
||||||
}
|
}
|
||||||
|
updateSliderColor(value);
|
||||||
});
|
});
|
||||||
|
|
||||||
std::move(
|
std::move(
|
||||||
|
@ -209,30 +204,15 @@ MenuVolumeItem::MenuVolumeItem(
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuVolumeItem::initArcsAnimation() {
|
void MenuVolumeItem::initArcsAnimation() {
|
||||||
const auto volumeLeftWas = lifetime().make_state<int>(0);
|
|
||||||
const auto lastTime = lifetime().make_state<int>(0);
|
const auto lastTime = lifetime().make_state<int>(0);
|
||||||
_arcsAnimation.init([=](crl::time now) {
|
_arcsAnimation.init([=](crl::time now) {
|
||||||
_arcs->update(now);
|
_arcs->update(now);
|
||||||
update(_speakerRect);
|
update(_speakerRect);
|
||||||
|
|
||||||
const auto wasRect = _volumeRect;
|
|
||||||
_volumeRect.moveLeft(anim::interpolate(
|
|
||||||
*volumeLeftWas,
|
|
||||||
_arcPosition.x()
|
|
||||||
+ st::groupCallMenuVolumeSkip
|
|
||||||
+ _arcs->finishedWidth(),
|
|
||||||
std::clamp(
|
|
||||||
(now - (*lastTime))
|
|
||||||
/ float64(st::groupCallSpeakerArcsAnimation.duration),
|
|
||||||
0.,
|
|
||||||
1.)));
|
|
||||||
update(_speakerRect.united(wasRect.united(_volumeRect)));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
_arcs->startUpdateRequests(
|
_arcs->startUpdateRequests(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
if (!_arcsAnimation.animating()) {
|
if (!_arcsAnimation.animating()) {
|
||||||
*volumeLeftWas = _volumeRect.left();
|
|
||||||
*lastTime = crl::now();
|
*lastTime = crl::now();
|
||||||
_arcsAnimation.start();
|
_arcsAnimation.start();
|
||||||
}
|
}
|
||||||
|
@ -269,8 +249,30 @@ void MenuVolumeItem::setCloudVolume(int volume) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuVolumeItem::setSliderVolume(int volume) {
|
void MenuVolumeItem::setSliderVolume(int volume) {
|
||||||
_slider->setValue(float64(volume) / _maxVolume);
|
const auto value = float64(volume) / _maxVolume;
|
||||||
update(_volumeRect);
|
_slider->setValue(value);
|
||||||
|
updateSliderColor(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MenuVolumeItem::updateSliderColor(float64 value) {
|
||||||
|
value = std::clamp(value, 0., 1.);
|
||||||
|
const auto color = [](int rgb) {
|
||||||
|
return QColor(
|
||||||
|
int((rgb & 0xFF0000) >> 16),
|
||||||
|
int((rgb & 0x00FF00) >> 8),
|
||||||
|
int(rgb & 0x0000FF));
|
||||||
|
};
|
||||||
|
const auto colors = std::array<QColor, 4>{ {
|
||||||
|
color(0xF66464),
|
||||||
|
color(0xD0B738),
|
||||||
|
color(0x24CD80),
|
||||||
|
color(0x3BBCEC),
|
||||||
|
} };
|
||||||
|
_slider->setActiveFgOverride((value < 0.25)
|
||||||
|
? anim::color(colors[0], colors[1], value / 0.25)
|
||||||
|
: (value < 0.5)
|
||||||
|
? anim::color(colors[1], colors[2], (value - 0.25) / 0.25)
|
||||||
|
: anim::color(colors[2], colors[3], (value - 0.5) / 0.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<QAction*> MenuVolumeItem::action() const {
|
not_null<QAction*> MenuVolumeItem::action() const {
|
||||||
|
@ -282,9 +284,9 @@ bool MenuVolumeItem::isEnabled() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
int MenuVolumeItem::contentHeight() const {
|
int MenuVolumeItem::contentHeight() const {
|
||||||
return _st.itemPadding.top()
|
return st::groupCallMenuVolumePadding.top()
|
||||||
+ _st.itemPadding.bottom()
|
+ st::groupCallMenuVolumePadding.bottom()
|
||||||
+ _stCross.icon.height() * 2;
|
+ _stCross.icon.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<bool> MenuVolumeItem::toggleMuteRequests() const {
|
rpl::producer<bool> MenuVolumeItem::toggleMuteRequests() const {
|
||||||
|
|
|
@ -52,6 +52,7 @@ private:
|
||||||
|
|
||||||
void setCloudVolume(int volume);
|
void setCloudVolume(int volume);
|
||||||
void setSliderVolume(int volume);
|
void setSliderVolume(int volume);
|
||||||
|
void updateSliderColor(float64 value);
|
||||||
|
|
||||||
QColor unmuteColor() const;
|
QColor unmuteColor() const;
|
||||||
QColor muteColor() const;
|
QColor muteColor() const;
|
||||||
|
@ -64,7 +65,6 @@ private:
|
||||||
|
|
||||||
QRect _itemRect;
|
QRect _itemRect;
|
||||||
QRect _speakerRect;
|
QRect _speakerRect;
|
||||||
QRect _volumeRect;
|
|
||||||
QPoint _arcPosition;
|
QPoint _arcPosition;
|
||||||
|
|
||||||
const base::unique_qptr<Ui::MediaSlider> _slider;
|
const base::unique_qptr<Ui::MediaSlider> _slider;
|
||||||
|
|
|
@ -223,6 +223,11 @@ void MediaSlider::addDivider(float64 atValue, const QSize &size) {
|
||||||
_dividers.push_back(Divider{ atValue, size });
|
_dividers.push_back(Divider{ atValue, size });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaSlider::setActiveFgOverride(std::optional<QColor> color) {
|
||||||
|
_activeFgOverride = color;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
void MediaSlider::paintEvent(QPaintEvent *e) {
|
void MediaSlider::paintEvent(QPaintEvent *e) {
|
||||||
if (_paintDisabled) {
|
if (_paintDisabled) {
|
||||||
return;
|
return;
|
||||||
|
@ -250,17 +255,27 @@ void MediaSlider::paintEvent(QPaintEvent *e) {
|
||||||
: value;
|
: value;
|
||||||
|
|
||||||
const auto markerFrom = (horizontal ? seekRect.x() : seekRect.y());
|
const auto markerFrom = (horizontal ? seekRect.x() : seekRect.y());
|
||||||
const auto markerLength = (horizontal ? seekRect.width() : seekRect.height());
|
const auto markerLength = horizontal
|
||||||
|
? seekRect.width()
|
||||||
|
: seekRect.height();
|
||||||
const auto from = 0;
|
const auto from = 0;
|
||||||
const auto length = (horizontal ? width() : height());
|
const auto length = (horizontal ? width() : height());
|
||||||
const auto mid = qRound(from + value * length);
|
const auto mid = qRound(from + value * length);
|
||||||
const auto till = std::max(mid, qRound(from + receivedTill * length));
|
const auto till = std::max(mid, qRound(from + receivedTill * length));
|
||||||
const auto end = from + length;
|
const auto end = from + length;
|
||||||
const auto activeFg = disabled ? _st.activeFgDisabled : anim::brush(_st.activeFg, _st.activeFgOver, over);
|
const auto activeFg = disabled
|
||||||
|
? _st.activeFgDisabled
|
||||||
|
: _activeFgOverride
|
||||||
|
? QBrush(*_activeFgOverride)
|
||||||
|
: anim::brush(_st.activeFg, _st.activeFgOver, over);
|
||||||
const auto receivedTillFg = _st.receivedTillFg;
|
const auto receivedTillFg = _st.receivedTillFg;
|
||||||
const auto inactiveFg = disabled ? _st.inactiveFgDisabled : anim::brush(_st.inactiveFg, _st.inactiveFgOver, over);
|
const auto inactiveFg = disabled
|
||||||
|
? _st.inactiveFgDisabled
|
||||||
|
: anim::brush(_st.inactiveFg, _st.inactiveFgOver, over);
|
||||||
if (mid > from) {
|
if (mid > from) {
|
||||||
const auto fromClipRect = horizontal ? QRect(0, 0, mid, height()) : QRect(0, 0, width(), mid);
|
const auto fromClipRect = horizontal
|
||||||
|
? QRect(0, 0, mid, height())
|
||||||
|
: QRect(0, 0, width(), mid);
|
||||||
const auto till = std::min(mid + radius, end);
|
const auto till = std::min(mid + radius, end);
|
||||||
const auto fromRect = horizontal
|
const auto fromRect = horizontal
|
||||||
? QRect(from, (height() - _st.width) / 2, till - from, _st.width)
|
? QRect(from, (height() - _st.width) / 2, till - from, _st.width)
|
||||||
|
@ -274,17 +289,31 @@ void MediaSlider::paintEvent(QPaintEvent *e) {
|
||||||
auto clipRect = QRect(mid, 0, till - mid, height());
|
auto clipRect = QRect(mid, 0, till - mid, height());
|
||||||
const auto left = std::max(mid - radius, from);
|
const auto left = std::max(mid - radius, from);
|
||||||
const auto right = std::min(till + radius, end);
|
const auto right = std::min(till + radius, end);
|
||||||
const auto rect = QRect(left, (height() - _st.width) / 2, right - left, _st.width);
|
const auto rect = QRect(
|
||||||
|
left,
|
||||||
|
(height() - _st.width) / 2,
|
||||||
|
right - left,
|
||||||
|
_st.width);
|
||||||
p.setClipRect(clipRect);
|
p.setClipRect(clipRect);
|
||||||
p.setBrush(receivedTillFg);
|
p.setBrush(receivedTillFg);
|
||||||
p.drawRoundedRect(rect, radius, radius);
|
p.drawRoundedRect(rect, radius, radius);
|
||||||
}
|
}
|
||||||
if (end > till) {
|
if (end > till) {
|
||||||
const auto endClipRect = horizontal ? QRect(till, 0, width() - till, height()) : QRect(0, till, width(), height() - till);
|
const auto endClipRect = horizontal
|
||||||
|
? QRect(till, 0, width() - till, height())
|
||||||
|
: QRect(0, till, width(), height() - till);
|
||||||
const auto begin = std::max(till - radius, from);
|
const auto begin = std::max(till - radius, from);
|
||||||
const auto endRect = horizontal
|
const auto endRect = horizontal
|
||||||
? QRect(begin, (height() - _st.width) / 2, end - begin, _st.width)
|
? QRect(
|
||||||
: QRect((width() - _st.width) / 2, begin, _st.width, end - begin);
|
begin,
|
||||||
|
(height() - _st.width) / 2,
|
||||||
|
end - begin,
|
||||||
|
_st.width)
|
||||||
|
: QRect(
|
||||||
|
(width() - _st.width) / 2,
|
||||||
|
begin,
|
||||||
|
_st.width,
|
||||||
|
end - begin);
|
||||||
p.setClipRect(endClipRect);
|
p.setClipRect(endClipRect);
|
||||||
p.setBrush(horizontal ? inactiveFg : activeFg);
|
p.setBrush(horizontal ? inactiveFg : activeFg);
|
||||||
p.drawRoundedRect(endRect, radius, radius);
|
p.drawRoundedRect(endRect, radius, radius);
|
||||||
|
@ -316,24 +345,46 @@ void MediaSlider::paintEvent(QPaintEvent *e) {
|
||||||
p.drawRoundedRect(rect, dividerRadius, dividerRadius);
|
p.drawRoundedRect(rect, dividerRadius, dividerRadius);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto markerSizeRatio = disabled ? 0. : (_alwaysDisplayMarker ? 1. : over);
|
const auto markerSizeRatio = disabled
|
||||||
|
? 0.
|
||||||
|
: (_alwaysDisplayMarker ? 1. : over);
|
||||||
if (markerSizeRatio > 0) {
|
if (markerSizeRatio > 0) {
|
||||||
const auto position = qRound(markerFrom + value * markerLength) - (horizontal ? (_st.seekSize.width() / 2) : (_st.seekSize.height() / 2));
|
const auto position = qRound(markerFrom + value * markerLength)
|
||||||
|
- (horizontal
|
||||||
|
? (_st.seekSize.width() / 2)
|
||||||
|
: (_st.seekSize.height() / 2));
|
||||||
const auto seekButton = horizontal
|
const auto seekButton = horizontal
|
||||||
? QRect(position, (height() - _st.seekSize.height()) / 2, _st.seekSize.width(), _st.seekSize.height())
|
? QRect(
|
||||||
: QRect((width() - _st.seekSize.width()) / 2, position, _st.seekSize.width(), _st.seekSize.height());
|
position,
|
||||||
const auto size = horizontal ? _st.seekSize.width() : _st.seekSize.height();
|
(height() - _st.seekSize.height()) / 2,
|
||||||
const auto remove = static_cast<int>(((1. - markerSizeRatio) * size) / 2.);
|
_st.seekSize.width(),
|
||||||
|
_st.seekSize.height())
|
||||||
|
: QRect(
|
||||||
|
(width() - _st.seekSize.width()) / 2,
|
||||||
|
position,
|
||||||
|
_st.seekSize.width(),
|
||||||
|
_st.seekSize.height());
|
||||||
|
const auto size = horizontal
|
||||||
|
? _st.seekSize.width()
|
||||||
|
: _st.seekSize.height();
|
||||||
|
const auto remove = static_cast<int>(
|
||||||
|
((1. - markerSizeRatio) * size) / 2.);
|
||||||
if (remove * 2 < size) {
|
if (remove * 2 < size) {
|
||||||
p.setClipRect(rect());
|
p.setClipRect(rect());
|
||||||
p.setBrush(activeFg);
|
p.setBrush(activeFg);
|
||||||
const auto xshift = horizontal
|
const auto xshift = horizontal
|
||||||
? std::max(seekButton.x() + seekButton.width() - remove - width(), 0) + std::min(seekButton.x() + remove, 0)
|
? std::max(
|
||||||
|
seekButton.x() + seekButton.width() - remove - width(),
|
||||||
|
0) + std::min(seekButton.x() + remove, 0)
|
||||||
: 0;
|
: 0;
|
||||||
const auto yshift = horizontal
|
const auto yshift = horizontal
|
||||||
? 0
|
? 0
|
||||||
: std::max(seekButton.y() + seekButton.height() - remove - height(), 0) + std::min(seekButton.y() + remove, 0);
|
: std::max(
|
||||||
p.drawEllipse(seekButton.marginsRemoved(QMargins(remove, remove, remove, remove)).translated(-xshift, -yshift));
|
seekButton.y() + seekButton.height() - remove - height(),
|
||||||
|
0) + std::min(seekButton.y() + remove, 0);
|
||||||
|
p.drawEllipse(seekButton.marginsRemoved(
|
||||||
|
QMargins(remove, remove, remove, remove)
|
||||||
|
).translated(-xshift, -yshift));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,7 +178,7 @@ public:
|
||||||
callback(convert(index));
|
callback(convert(index));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
void setActiveFgOverride(std::optional<QColor> color);
|
||||||
void addDivider(float64 atValue, const QSize &size);
|
void addDivider(float64 atValue, const QSize &size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -198,6 +198,7 @@ private:
|
||||||
bool _paintDisabled = false;
|
bool _paintDisabled = false;
|
||||||
|
|
||||||
std::vector<Divider> _dividers;
|
std::vector<Divider> _dividers;
|
||||||
|
std::optional<QColor> _activeFgOverride;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue