mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Init top bar blobs geometry safely.
This commit is contained in:
parent
9f2903f81d
commit
7f7ac64c6d
3 changed files with 85 additions and 86 deletions
|
@ -226,13 +226,6 @@ TopBar::TopBar(
|
||||||
, _mute(this, st::callBarMuteToggle)
|
, _mute(this, st::callBarMuteToggle)
|
||||||
, _info(this)
|
, _info(this)
|
||||||
, _hangup(this, st::callBarHangup)
|
, _hangup(this, st::callBarHangup)
|
||||||
, _blobs(base::make_unique_q<Ui::RpWidget>(parent))
|
|
||||||
, _blobsPaint(std::make_unique<Ui::Paint::LinearBlobs>(
|
|
||||||
LinearBlobs() | ranges::to_vector,
|
|
||||||
kBlobLevelDuration1,
|
|
||||||
kBlobLevelDuration2,
|
|
||||||
1.))
|
|
||||||
, _blobsLevelTimer([=] { _blobsLastLevel = 0.; })
|
|
||||||
, _gradients(Colors(), QPointF(), QPointF())
|
, _gradients(Colors(), QPointF(), QPointF())
|
||||||
, _updateDurationTimer([=] { updateDurationText(); }) {
|
, _updateDurationTimer([=] { updateDurationText(); }) {
|
||||||
initControls();
|
initControls();
|
||||||
|
@ -350,30 +343,56 @@ void TopBar::initControls() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
updateDurationText();
|
updateDurationText();
|
||||||
|
|
||||||
initBlobs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopBar::initBlobs() {
|
void TopBar::initBlobsUnder(
|
||||||
|
QWidget *blobsParent,
|
||||||
|
rpl::producer<QRect> barGeometry) {
|
||||||
const auto group = _groupCall.get();
|
const auto group = _groupCall.get();
|
||||||
if (!group) {
|
if (!group) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &hideDuration = kBlobLevelDuration1 * 2;
|
static constexpr auto kHideDuration = kBlobLevelDuration1 * 2;
|
||||||
const auto hideLastTime = _blobs->lifetime().make_state<crl::time>(0);
|
|
||||||
const auto lastTime = _blobs->lifetime().make_state<crl::time>(0);
|
|
||||||
const auto blobsRect =
|
|
||||||
_blobs->lifetime().make_state<QRect>(_blobs->rect());
|
|
||||||
|
|
||||||
_blobsAnimation.init([=](crl::time now) {
|
struct State {
|
||||||
if (const auto last = *hideLastTime; (last > 0)
|
Ui::Paint::LinearBlobs paint = {
|
||||||
&& (now - last >= hideDuration)) {
|
LinearBlobs() | ranges::to_vector,
|
||||||
_blobsAnimation.stop();
|
kBlobLevelDuration1,
|
||||||
|
kBlobLevelDuration2,
|
||||||
|
1.
|
||||||
|
};
|
||||||
|
Ui::Animations::Simple hideAnimation;
|
||||||
|
Ui::Animations::Basic animation;
|
||||||
|
base::Timer levelTimer;
|
||||||
|
crl::time hideLastTime = 0;
|
||||||
|
crl::time lastTime = 0;
|
||||||
|
float lastLevel = 0.;
|
||||||
|
float levelBeforeLast = 0.;
|
||||||
|
int maxHeight = st::groupCallMinorBlobMinRadius
|
||||||
|
+ st::groupCallMinorBlobMaxRadius;
|
||||||
|
};
|
||||||
|
|
||||||
|
_blobs = base::make_unique_q<Ui::RpWidget>(blobsParent);
|
||||||
|
|
||||||
|
const auto state = _blobs->lifetime().make_state<State>();
|
||||||
|
state->levelTimer.setCallback([=] {
|
||||||
|
state->levelBeforeLast = state->lastLevel;
|
||||||
|
state->lastLevel = 0.;
|
||||||
|
if (state->levelBeforeLast == 0.) {
|
||||||
|
state->paint.setLevel(0.);
|
||||||
|
state->levelTimer.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
state->animation.init([=](crl::time now) {
|
||||||
|
if (const auto last = state->hideLastTime; (last > 0)
|
||||||
|
&& (now - last >= kHideDuration)) {
|
||||||
|
state->animation.stop();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_blobsPaint->updateLevel(now - *lastTime);
|
state->paint.updateLevel(now - state->lastTime);
|
||||||
*lastTime = now;
|
state->lastTime = now;
|
||||||
|
|
||||||
_blobs->update();
|
_blobs->update();
|
||||||
return true;
|
return true;
|
||||||
|
@ -408,44 +427,32 @@ void TopBar::initBlobs() {
|
||||||
hideBlobs
|
hideBlobs
|
||||||
) | rpl::start_with_next([=](bool hide) {
|
) | rpl::start_with_next([=](bool hide) {
|
||||||
if (hide) {
|
if (hide) {
|
||||||
_blobsPaint->setLevel(0.);
|
state->paint.setLevel(0.);
|
||||||
}
|
}
|
||||||
*hideLastTime = hide ? crl::now() : 0;
|
state->hideLastTime = hide ? crl::now() : 0;
|
||||||
if (!hide && !_blobsAnimation.animating()) {
|
if (!hide && !state->animation.animating()) {
|
||||||
_blobsAnimation.start();
|
state->animation.start();
|
||||||
}
|
}
|
||||||
if (hide) {
|
if (hide) {
|
||||||
_blobsLevelTimer.cancel();
|
state->levelTimer.cancel();
|
||||||
} else {
|
} else {
|
||||||
_blobsLastLevel = 0.;
|
state->lastLevel = 0.;
|
||||||
_blobsLevelTimer.callEach(kBlobUpdateInterval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto from = hide ? 0. : 1.;
|
const auto from = hide ? 0. : 1.;
|
||||||
const auto to = hide ? 1. : 0.;
|
const auto to = hide ? 1. : 0.;
|
||||||
_blobsHideAnimation.start([=](float64 value) {
|
state->hideAnimation.start([=](float64) {
|
||||||
blobsRect->setHeight(anim::interpolate(0, -20, value));
|
_blobs->update();
|
||||||
}, from, to, hideDuration);
|
}, from, to, kHideDuration);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
///
|
std::move(
|
||||||
|
barGeometry
|
||||||
const auto parent = static_cast<Ui::RpWidget*>(parentWidget());
|
|
||||||
geometryValue(
|
|
||||||
) | rpl::start_with_next([=](QRect rect) {
|
) | rpl::start_with_next([=](QRect rect) {
|
||||||
_blobs->resize(rect.width(), rect.height());
|
_blobs->resize(
|
||||||
|
rect.width(),
|
||||||
{
|
std::min(state->maxHeight, rect.height()));
|
||||||
const auto &r = _blobs->rect();
|
_blobs->moveToLeft(rect.x(), rect.y() + rect.height());
|
||||||
*blobsRect = QRect(
|
|
||||||
r.x(),
|
|
||||||
r.y(),
|
|
||||||
r.width() + st::groupCallBlobWidthAdditional,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto relativePos = mapTo(parent, rect.topLeft());
|
|
||||||
_blobs->moveToLeft(relativePos.x(), relativePos.y() + rect.height());
|
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
shownValue(
|
shownValue(
|
||||||
|
@ -455,44 +462,42 @@ void TopBar::initBlobs() {
|
||||||
|
|
||||||
_blobs->paintRequest(
|
_blobs->paintRequest(
|
||||||
) | rpl::start_with_next([=](QRect clip) {
|
) | rpl::start_with_next([=](QRect clip) {
|
||||||
Painter p(_blobs);
|
const auto hidden = state->hideAnimation.value(
|
||||||
|
state->hideLastTime ? 1. : 0.);
|
||||||
const auto alpha = 1. - _blobsHideAnimation.value(0.);
|
if (hidden == 1.) {
|
||||||
if (alpha < 1.) {
|
return;
|
||||||
p.setOpacity(alpha);
|
|
||||||
}
|
}
|
||||||
_blobsPaint->paint(p, _groupBrush, *blobsRect, 0, 0);
|
|
||||||
}, _blobs->lifetime());
|
|
||||||
|
|
||||||
rpl::single(
|
Painter p(_blobs);
|
||||||
) | rpl::then(
|
if (hidden > 0.) {
|
||||||
events(
|
p.setOpacity(1. - hidden);
|
||||||
) | rpl::filter([](not_null<QEvent*> e) {
|
}
|
||||||
return e->type() == QEvent::ZOrderChange;
|
const auto top = -_blobs->height() * hidden;
|
||||||
}) | rpl::to_empty
|
const auto drawUnder = QRect(
|
||||||
) | rpl::start_with_next([=] {
|
0,
|
||||||
crl::on_main(_blobs.get(), [=] {
|
top,
|
||||||
_blobs->raise();
|
_blobs->width() + st::groupCallBlobWidthAdditional,
|
||||||
});
|
0);
|
||||||
}, lifetime());
|
state->paint.paint(p, _groupBrush, drawUnder, 0, 0);
|
||||||
|
}, _blobs->lifetime());
|
||||||
|
|
||||||
group->levelUpdates(
|
group->levelUpdates(
|
||||||
) | rpl::filter([=](const LevelUpdate &update) {
|
) | rpl::filter([=](const LevelUpdate &update) {
|
||||||
return !*hideLastTime && (update.value > _blobsLastLevel);
|
return !state->hideLastTime && (update.value > state->lastLevel);
|
||||||
}) | rpl::start_with_next([=](const LevelUpdate &update) {
|
}) | rpl::start_with_next([=](const LevelUpdate &update) {
|
||||||
_blobsLastLevel = update.value;
|
if (state->lastLevel == 0.) {
|
||||||
_blobsPaint->setLevel(_blobsLastLevel);
|
state->levelTimer.callEach(kBlobUpdateInterval);
|
||||||
|
}
|
||||||
|
state->lastLevel = update.value;
|
||||||
|
state->paint.setLevel(update.value);
|
||||||
}, _blobs->lifetime());
|
}, _blobs->lifetime());
|
||||||
|
|
||||||
_blobs->setAttribute(Qt::WA_TransparentForMouseEvents);
|
_blobs->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
_blobs->show();
|
_blobs->show();
|
||||||
_blobsAnimation.start();
|
|
||||||
|
|
||||||
crl::on_main([=] {
|
if (!state->hideLastTime) {
|
||||||
const auto r = rect();
|
state->animation.start();
|
||||||
const auto relativePos = mapTo(parent, r.topLeft());
|
}
|
||||||
_blobs->moveToLeft(relativePos.x(), relativePos.y() + r.height());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopBar::subscribeToMembersChanges(not_null<GroupCall*> call) {
|
void TopBar::subscribeToMembersChanges(not_null<GroupCall*> call) {
|
||||||
|
|
|
@ -20,9 +20,6 @@ class IconButton;
|
||||||
class AbstractButton;
|
class AbstractButton;
|
||||||
class LabelSimple;
|
class LabelSimple;
|
||||||
class FlatLabel;
|
class FlatLabel;
|
||||||
namespace Paint {
|
|
||||||
class LinearBlobs;
|
|
||||||
} // namespace Paint
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Main {
|
namespace Main {
|
||||||
|
@ -41,9 +38,12 @@ class TopBar : public Ui::RpWidget {
|
||||||
public:
|
public:
|
||||||
TopBar(QWidget *parent, const base::weak_ptr<Call> &call);
|
TopBar(QWidget *parent, const base::weak_ptr<Call> &call);
|
||||||
TopBar(QWidget *parent, const base::weak_ptr<GroupCall> &call);
|
TopBar(QWidget *parent, const base::weak_ptr<GroupCall> &call);
|
||||||
|
|
||||||
~TopBar();
|
~TopBar();
|
||||||
|
|
||||||
|
void initBlobsUnder(
|
||||||
|
QWidget *blobsParent,
|
||||||
|
rpl::producer<QRect> barGeometry);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
@ -55,7 +55,6 @@ private:
|
||||||
const base::weak_ptr<GroupCall> &groupCall);
|
const base::weak_ptr<GroupCall> &groupCall);
|
||||||
|
|
||||||
void initControls();
|
void initControls();
|
||||||
void initBlobs();
|
|
||||||
void updateInfoLabels();
|
void updateInfoLabels();
|
||||||
void setInfoLabels();
|
void setInfoLabels();
|
||||||
void updateDurationText();
|
void updateDurationText();
|
||||||
|
@ -79,17 +78,11 @@ private:
|
||||||
object_ptr<Ui::AbstractButton> _info;
|
object_ptr<Ui::AbstractButton> _info;
|
||||||
object_ptr<Ui::IconButton> _hangup;
|
object_ptr<Ui::IconButton> _hangup;
|
||||||
base::unique_qptr<Ui::RpWidget> _blobs;
|
base::unique_qptr<Ui::RpWidget> _blobs;
|
||||||
std::unique_ptr<Ui::Paint::LinearBlobs> _blobsPaint;
|
|
||||||
float _blobsLastLevel = 0.;
|
|
||||||
base::Timer _blobsLevelTimer;
|
|
||||||
|
|
||||||
QBrush _groupBrush;
|
QBrush _groupBrush;
|
||||||
anim::linear_gradients<MuteState> _gradients;
|
anim::linear_gradients<MuteState> _gradients;
|
||||||
Ui::Animations::Simple _switchStateAnimation;
|
Ui::Animations::Simple _switchStateAnimation;
|
||||||
|
|
||||||
Ui::Animations::Simple _blobsHideAnimation;
|
|
||||||
Ui::Animations::Basic _blobsAnimation;
|
|
||||||
|
|
||||||
base::Timer _updateDurationTimer;
|
base::Timer _updateDurationTimer;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1000,6 +1000,7 @@ void MainWidget::createCallTopBar() {
|
||||||
(_currentCall
|
(_currentCall
|
||||||
? object_ptr<Calls::TopBar>(this, _currentCall)
|
? object_ptr<Calls::TopBar>(this, _currentCall)
|
||||||
: object_ptr<Calls::TopBar>(this, _currentGroupCall)));
|
: object_ptr<Calls::TopBar>(this, _currentGroupCall)));
|
||||||
|
_callTopBar->entity()->initBlobsUnder(this, _callTopBar->geometryValue());
|
||||||
_callTopBar->heightValue(
|
_callTopBar->heightValue(
|
||||||
) | rpl::start_with_next([this](int value) {
|
) | rpl::start_with_next([this](int value) {
|
||||||
callTopBarHeightUpdated(value);
|
callTopBarHeightUpdated(value);
|
||||||
|
|
Loading…
Add table
Reference in a new issue