mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Improve design of mediaview controls over state.
This commit is contained in:
parent
df9bd91d9a
commit
29224fea66
10 changed files with 129 additions and 55 deletions
|
@ -245,6 +245,7 @@ mediaviewTextTop: 26px;
|
|||
|
||||
mediaviewControlSize: 90px;
|
||||
mediaviewIconSize: size(46px, 54px);
|
||||
mediaviewIconOver: 36px;
|
||||
|
||||
mediaviewWaitHide: 2000;
|
||||
mediaviewHideDuration: 1000;
|
||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/gl/gl_shader.h"
|
||||
#include "ui/painter.h"
|
||||
#include "media/streaming/media_streaming_common.h"
|
||||
#include "platform/platform_overlay_widget.h"
|
||||
#include "base/platform/base_platform_info.h"
|
||||
#include "core/crash_reports.h"
|
||||
#include "styles/style_media_view.h"
|
||||
|
@ -27,7 +28,7 @@ constexpr auto kFooterOffset = kSaveMsgOffset + 4;
|
|||
constexpr auto kCaptionOffset = kFooterOffset + 4;
|
||||
constexpr auto kGroupThumbsOffset = kCaptionOffset + 4;
|
||||
constexpr auto kControlsOffset = kGroupThumbsOffset + 4;
|
||||
constexpr auto kControlValues = 2 * 4 + 4 * 4;
|
||||
constexpr auto kControlValues = 4 * 4 + 4 * 4; // over + icon
|
||||
|
||||
[[nodiscard]] ShaderPart FragmentApplyControlsFade() {
|
||||
return {
|
||||
|
@ -557,28 +558,37 @@ void OverlayWidget::RendererGL::paintControlsStart() {
|
|||
|
||||
void OverlayWidget::RendererGL::paintControl(
|
||||
OverState control,
|
||||
QRect outer,
|
||||
float64 outerOpacity,
|
||||
QRect over,
|
||||
float64 overOpacity,
|
||||
QRect inner,
|
||||
float64 innerOpacity,
|
||||
const style::icon &icon) {
|
||||
const auto meta = ControlMeta(control);
|
||||
Assert(meta.icon == &icon);
|
||||
|
||||
const auto &bg = st::mediaviewControlBg->c;
|
||||
const auto bgAlpha = int(base::SafeRound(bg.alpha() * outerOpacity));
|
||||
const auto overAlpha = overOpacity * kOverBackgroundOpacity;
|
||||
const auto offset = kControlsOffset + (meta.index * kControlValues) / 4;
|
||||
const auto fgOffset = offset + 2;
|
||||
const auto bgRect = transformRect(outer);
|
||||
const auto fgOffset = offset + 4;
|
||||
const auto overRect = _controlsImage.texturedRect(
|
||||
over,
|
||||
_controlsTextures[kControlsCount]);
|
||||
const auto overGeometry = transformRect(over);
|
||||
const auto iconRect = _controlsImage.texturedRect(
|
||||
inner,
|
||||
_controlsTextures[meta.index]);
|
||||
const auto iconGeometry = transformRect(iconRect.geometry);
|
||||
const GLfloat coords[] = {
|
||||
bgRect.left(), bgRect.top(),
|
||||
bgRect.right(), bgRect.top(),
|
||||
bgRect.right(), bgRect.bottom(),
|
||||
bgRect.left(), bgRect.bottom(),
|
||||
overGeometry.left(), overGeometry.top(),
|
||||
overRect.texture.left(), overRect.texture.bottom(),
|
||||
|
||||
overGeometry.right(), overGeometry.top(),
|
||||
overRect.texture.right(), overRect.texture.bottom(),
|
||||
|
||||
overGeometry.right(), overGeometry.bottom(),
|
||||
overRect.texture.right(), overRect.texture.top(),
|
||||
|
||||
overGeometry.left(), overGeometry.bottom(),
|
||||
overRect.texture.left(), overRect.texture.top(),
|
||||
|
||||
iconGeometry.left(), iconGeometry.top(),
|
||||
iconRect.texture.left(), iconRect.texture.bottom(),
|
||||
|
@ -592,27 +602,22 @@ void OverlayWidget::RendererGL::paintControl(
|
|||
iconGeometry.left(), iconGeometry.bottom(),
|
||||
iconRect.texture.left(), iconRect.texture.top(),
|
||||
};
|
||||
if (!outer.isEmpty() && bgAlpha > 0) {
|
||||
_controlsProgram->bind();
|
||||
_controlsProgram->setUniformValue("viewport", _uniformViewport);
|
||||
if (!over.isEmpty() && overOpacity > 0) {
|
||||
_contentBuffer->write(
|
||||
offset * 4 * sizeof(GLfloat),
|
||||
coords,
|
||||
sizeof(coords));
|
||||
_fillProgram->bind();
|
||||
_fillProgram->setUniformValue("viewport", _uniformViewport);
|
||||
FillRectangle(
|
||||
*_f,
|
||||
&*_fillProgram,
|
||||
offset,
|
||||
QColor(bg.red(), bg.green(), bg.blue(), bgAlpha));
|
||||
_controlsProgram->setUniformValue("g_opacity", GLfloat(overAlpha));
|
||||
FillTexturedRectangle(*_f, &*_controlsProgram, offset);
|
||||
} else {
|
||||
_contentBuffer->write(
|
||||
fgOffset * 4 * sizeof(GLfloat),
|
||||
coords + (fgOffset - offset) * 4,
|
||||
sizeof(coords) - (fgOffset - offset) * 4 * sizeof(GLfloat));
|
||||
}
|
||||
_controlsProgram->bind();
|
||||
_controlsProgram->setUniformValue("g_opacity", GLfloat(innerOpacity));
|
||||
_controlsProgram->setUniformValue("viewport", _uniformViewport);
|
||||
FillTexturedRectangle(*_f, &*_controlsProgram, fgOffset);
|
||||
}
|
||||
|
||||
|
@ -645,6 +650,8 @@ void OverlayWidget::RendererGL::validateControls() {
|
|||
maxWidth = std::max(meta.icon->width(), maxWidth);
|
||||
fullHeight += meta.icon->height();
|
||||
}
|
||||
maxWidth = std::max(st::mediaviewIconOver, maxWidth);
|
||||
fullHeight += st::mediaviewIconOver;
|
||||
auto image = QImage(
|
||||
QSize(maxWidth, fullHeight) * _factor,
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
|
@ -661,6 +668,15 @@ void OverlayWidget::RendererGL::validateControls() {
|
|||
meta.icon->size() * _factor);
|
||||
height += meta.icon->height();
|
||||
}
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(OverBackgroundColor());
|
||||
p.drawEllipse(
|
||||
QRect(0, height, st::mediaviewIconOver, st::mediaviewIconOver));
|
||||
_controlsTextures[index++] = QRect(
|
||||
QPoint(0, height) * _factor,
|
||||
QSize(st::mediaviewIconOver, st::mediaviewIconOver) * _factor);
|
||||
height += st::mediaviewIconOver;
|
||||
}
|
||||
_controlsImage.setImage(std::move(image));
|
||||
}
|
||||
|
|
|
@ -60,8 +60,8 @@ private:
|
|||
void paintControlsStart() override;
|
||||
void paintControl(
|
||||
OverState control,
|
||||
QRect outer,
|
||||
float64 outerOpacity,
|
||||
QRect over,
|
||||
float64 overOpacity,
|
||||
QRect inner,
|
||||
float64 innerOpacity,
|
||||
const style::icon &icon) override;
|
||||
|
@ -135,7 +135,9 @@ private:
|
|||
|
||||
static constexpr auto kControlsCount = 5;
|
||||
[[nodiscard]] static Control ControlMeta(OverState control);
|
||||
std::array<QRect, kControlsCount> _controlsTextures;
|
||||
|
||||
// Last one is for the over circle image.
|
||||
std::array<QRect, kControlsCount + 1> _controlsTextures;
|
||||
|
||||
QRect _shadowTopTexture;
|
||||
QRect _shadowBottomTexture;
|
||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "ui/painter.h"
|
||||
#include "media/view/media_view_pip.h"
|
||||
#include "platform/platform_overlay_widget.h"
|
||||
#include "styles/style_media_view.h"
|
||||
|
||||
namespace Media::View {
|
||||
|
@ -173,22 +174,20 @@ void OverlayWidget::RendererSW::paintControlsStart() {
|
|||
|
||||
void OverlayWidget::RendererSW::paintControl(
|
||||
OverState control,
|
||||
QRect outer,
|
||||
float64 outerOpacity,
|
||||
QRect over,
|
||||
float64 overOpacity,
|
||||
QRect inner,
|
||||
float64 innerOpacity,
|
||||
const style::icon &icon) {
|
||||
if (!outer.isEmpty() && !outer.intersects(_clipOuter)) {
|
||||
if (!over.isEmpty() && !over.intersects(_clipOuter)) {
|
||||
return;
|
||||
}
|
||||
if (!outer.isEmpty() && outerOpacity > 0) {
|
||||
_p->setOpacity(outerOpacity);
|
||||
for (const auto &rect : *_clip) {
|
||||
const auto fill = outer.intersected(rect);
|
||||
if (!fill.isEmpty()) {
|
||||
_p->fillRect(fill, st::mediaviewControlBg);
|
||||
}
|
||||
if (!over.isEmpty() && overOpacity > 0) {
|
||||
if (_overControlImage.isNull()) {
|
||||
validateOverControlImage();
|
||||
}
|
||||
_p->setOpacity(overOpacity);
|
||||
_p->drawImage(over.topLeft(), _overControlImage);
|
||||
}
|
||||
if (inner.intersects(_clipOuter)) {
|
||||
_p->setOpacity(innerOpacity);
|
||||
|
@ -220,4 +219,22 @@ void OverlayWidget::RendererSW::paintRoundedCorners(int radius) {
|
|||
// The RpWindow rounding overlay will do the job.
|
||||
}
|
||||
|
||||
void OverlayWidget::RendererSW::validateOverControlImage() {
|
||||
const auto size = QSize(st::mediaviewIconOver, st::mediaviewIconOver);
|
||||
const auto alpha = base::SafeRound(kOverBackgroundOpacity * 255);
|
||||
_overControlImage = QImage(
|
||||
size * style::DevicePixelRatio(),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
_overControlImage.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
_overControlImage.fill(Qt::transparent);
|
||||
|
||||
Painter p(&_overControlImage);
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
auto color = OverBackgroundColor();
|
||||
color.setAlpha(alpha);
|
||||
p.setBrush(color);
|
||||
p.drawEllipse(QRect(QPoint(), size));
|
||||
}
|
||||
|
||||
} // namespace Media::View
|
||||
|
|
|
@ -43,8 +43,8 @@ private:
|
|||
void paintControlsStart() override;
|
||||
void paintControl(
|
||||
OverState control,
|
||||
QRect outer,
|
||||
float64 outerOpacity,
|
||||
QRect over,
|
||||
float64 overOpacity,
|
||||
QRect inner,
|
||||
float64 innerOpacity,
|
||||
const style::icon &icon) override;
|
||||
|
@ -53,6 +53,8 @@ private:
|
|||
void paintGroupThumbs(QRect outer, float64 opacity) override;
|
||||
void paintRoundedCorners(int radius) override;
|
||||
|
||||
void validateOverControlImage();
|
||||
|
||||
[[nodiscard]] static QRect TransformRect(QRectF geometry, int rotation);
|
||||
|
||||
const not_null<OverlayWidget*> _owner;
|
||||
|
@ -62,6 +64,8 @@ private:
|
|||
const QRegion *_clip = nullptr;
|
||||
QRect _clipOuter;
|
||||
|
||||
QImage _overControlImage;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Media::View
|
||||
|
|
|
@ -30,8 +30,8 @@ public:
|
|||
virtual void paintControlsStart() = 0;
|
||||
virtual void paintControl(
|
||||
OverState control,
|
||||
QRect outer,
|
||||
float64 outerOpacity,
|
||||
QRect over,
|
||||
float64 overOpacity,
|
||||
QRect inner,
|
||||
float64 innerOpacity,
|
||||
const style::icon &icon) = 0;
|
||||
|
|
|
@ -781,10 +781,15 @@ void OverlayWidget::updateGeometryToScreen(bool inMove) {
|
|||
}
|
||||
|
||||
void OverlayWidget::updateControlsGeometry() {
|
||||
const auto overRect = QRect(
|
||||
QPoint(),
|
||||
QSize(st::mediaviewIconOver, st::mediaviewIconOver));
|
||||
const auto navSkip = st::mediaviewHeaderTop;
|
||||
_leftNav = QRect(0, navSkip, st::mediaviewControlSize, height() - 2 * navSkip);
|
||||
_leftNavOver = style::centerrect(_leftNav, overRect);
|
||||
_leftNavIcon = style::centerrect(_leftNav, st::mediaviewLeft);
|
||||
_rightNav = QRect(width() - st::mediaviewControlSize, navSkip, st::mediaviewControlSize, height() - 2 * navSkip);
|
||||
_rightNavOver = style::centerrect(_rightNav, overRect);
|
||||
_rightNavIcon = style::centerrect(_rightNav, st::mediaviewRight);
|
||||
|
||||
_saveMsg.moveTo((width() - _saveMsg.width()) / 2, (height() - _saveMsg.height()) / 2);
|
||||
|
@ -1055,6 +1060,9 @@ void OverlayWidget::updateControls() {
|
|||
|
||||
updateThemePreviewGeometry();
|
||||
|
||||
const auto overRect = QRect(
|
||||
QPoint(),
|
||||
QSize(st::mediaviewIconOver, st::mediaviewIconOver));
|
||||
_saveVisible = contentCanBeSaved();
|
||||
_rotateVisible = !_themePreviewShown;
|
||||
const auto navRect = [&](int i) {
|
||||
|
@ -1064,10 +1072,13 @@ void OverlayWidget::updateControls() {
|
|||
st::mediaviewIconSize.height());
|
||||
};
|
||||
_saveNav = navRect(_rotateVisible ? 3 : 2);
|
||||
_saveNavOver = style::centerrect(_saveNav, overRect);
|
||||
_saveNavIcon = style::centerrect(_saveNav, st::mediaviewSave);
|
||||
_rotateNav = navRect(2);
|
||||
_rotateNavOver = style::centerrect(_rotateNav, overRect);
|
||||
_rotateNavIcon = style::centerrect(_rotateNav, st::mediaviewRotate);
|
||||
_moreNav = navRect(1);
|
||||
_moreNavOver = style::centerrect(_moreNav, overRect);
|
||||
_moreNavIcon = style::centerrect(_moreNav, st::mediaviewMore);
|
||||
|
||||
const auto dNow = QDateTime::currentDateTime();
|
||||
|
@ -1374,11 +1385,11 @@ bool OverlayWidget::updateControlsAnimation(crl::time now) {
|
|||
_helper->setControlsOpacity(_controlsOpacity.current());
|
||||
const auto content = finalContentRect();
|
||||
const auto toUpdate = QRegion()
|
||||
+ (_over == OverLeftNav ? _leftNav : _leftNavIcon)
|
||||
+ (_over == OverRightNav ? _rightNav : _rightNavIcon)
|
||||
+ _saveNavIcon
|
||||
+ _rotateNavIcon
|
||||
+ _moreNavIcon
|
||||
+ (_over == OverLeftNav ? _leftNavOver : _leftNavIcon)
|
||||
+ (_over == OverRightNav ? _rightNavOver : _rightNavIcon)
|
||||
+ (_over == OverSave ? _saveNavOver : _saveNavIcon)
|
||||
+ (_over == OverRotate ? _rotateNavOver : _rotateNavIcon)
|
||||
+ (_over == OverMore ? _moreNavOver : _moreNavIcon)
|
||||
+ _headerNav
|
||||
+ _nameNav
|
||||
+ _dateNav
|
||||
|
@ -4159,7 +4170,7 @@ void OverlayWidget::paintControls(
|
|||
struct Control {
|
||||
OverState state = OverNone;
|
||||
bool visible = false;
|
||||
const QRect &outer;
|
||||
const QRect &over;
|
||||
const QRect &inner;
|
||||
const style::icon &icon;
|
||||
bool nonbright = false;
|
||||
|
@ -4170,33 +4181,33 @@ void OverlayWidget::paintControls(
|
|||
{
|
||||
OverLeftNav,
|
||||
_leftNavVisible,
|
||||
_leftNav,
|
||||
_leftNavOver,
|
||||
_leftNavIcon,
|
||||
st::mediaviewLeft,
|
||||
true },
|
||||
{
|
||||
OverRightNav,
|
||||
_rightNavVisible,
|
||||
_rightNav,
|
||||
_rightNavOver,
|
||||
_rightNavIcon,
|
||||
st::mediaviewRight,
|
||||
true },
|
||||
{
|
||||
OverSave,
|
||||
_saveVisible,
|
||||
kEmpty,
|
||||
_saveNavOver,
|
||||
_saveNavIcon,
|
||||
st::mediaviewSave },
|
||||
{
|
||||
OverRotate,
|
||||
_rotateVisible,
|
||||
kEmpty,
|
||||
_rotateNavOver,
|
||||
_rotateNavIcon,
|
||||
st::mediaviewRotate },
|
||||
{
|
||||
OverMore,
|
||||
true,
|
||||
kEmpty,
|
||||
_moreNavOver,
|
||||
_moreNavIcon,
|
||||
st::mediaviewMore },
|
||||
};
|
||||
|
@ -4211,7 +4222,7 @@ void OverlayWidget::paintControls(
|
|||
const auto icon = controlOpacity(progress, control.nonbright);
|
||||
renderer->paintControl(
|
||||
control.state,
|
||||
control.outer,
|
||||
control.over,
|
||||
bg * opacity,
|
||||
control.inner,
|
||||
icon * opacity,
|
||||
|
|
|
@ -495,9 +495,12 @@ private:
|
|||
std::unique_ptr<Collage> _collage;
|
||||
std::optional<WebPageCollage> _collageData;
|
||||
|
||||
QRect _leftNav, _leftNavIcon, _rightNav, _rightNavIcon;
|
||||
QRect _leftNav, _leftNavOver, _leftNavIcon;
|
||||
QRect _rightNav, _rightNavOver, _rightNavIcon;
|
||||
QRect _headerNav, _nameNav, _dateNav;
|
||||
QRect _rotateNav, _rotateNavIcon, _saveNav, _saveNavIcon, _moreNav, _moreNavIcon;
|
||||
QRect _rotateNav, _rotateNavOver, _rotateNavIcon;
|
||||
QRect _saveNav, _saveNavOver, _saveNavIcon;
|
||||
QRect _moreNav, _moreNavOver, _moreNavIcon;
|
||||
bool _leftNavVisible = false;
|
||||
bool _rightNavVisible = false;
|
||||
bool _saveVisible = false;
|
||||
|
|
|
@ -13,6 +13,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/abstract_button.h"
|
||||
#include "styles/style_media_view.h"
|
||||
|
||||
namespace Media::View {
|
||||
|
||||
QColor OverBackgroundColor() {
|
||||
auto c1 = st::mediaviewBg->c;
|
||||
auto c2 = QColor(255, 255, 255);
|
||||
const auto mix = [&](int a, int b) {
|
||||
constexpr auto k1 = 0.15 * 0.85 / (1. - 0.85 * 0.85);
|
||||
constexpr auto k2 = 0.15 / (1. - 0.85 * 0.85);
|
||||
return int(a * k1 + b * k2);
|
||||
};
|
||||
return QColor(
|
||||
mix(c1.red(), c2.red()),
|
||||
mix(c1.green(), c2.green()),
|
||||
mix(c1.blue(), c2.blue()));
|
||||
}
|
||||
|
||||
} // namespace Media::View
|
||||
|
||||
namespace Platform {
|
||||
namespace {
|
||||
|
||||
|
@ -120,8 +138,9 @@ object_ptr<Ui::AbstractButton> DefaultOverlayWidgetHelper::Buttons::create(
|
|||
current = maximized ? &st::mediaviewTitleRestore : icon;
|
||||
}
|
||||
const auto alpha = progress * kOverBackgroundOpacity;
|
||||
const auto ialpha = anim::interpolate(0, 255, alpha);
|
||||
state->frame.fill(QColor(255, 255, 255, ialpha));
|
||||
auto color = OverBackgroundColor();
|
||||
color.setAlpha(anim::interpolate(0, 255, alpha));
|
||||
state->frame.fill(color);
|
||||
|
||||
auto q = QPainter(&state->frame);
|
||||
const auto normal = maximized
|
||||
|
|
|
@ -19,7 +19,8 @@ namespace Media::View {
|
|||
|
||||
inline constexpr auto kMaximizedIconOpacity = 0.6;
|
||||
inline constexpr auto kNormalIconOpacity = 0.9;
|
||||
inline constexpr auto kOverBackgroundOpacity = 0.15;
|
||||
inline constexpr auto kOverBackgroundOpacity = 0.2775;
|
||||
[[nodiscard]] QColor OverBackgroundColor();
|
||||
|
||||
} // namespace Media::View
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue