mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-03 21:54:05 +02:00
Improve box rounding and buttons.
This commit is contained in:
parent
feb2d3066e
commit
7b0513a1ea
11 changed files with 78 additions and 45 deletions
|
@ -1381,7 +1381,7 @@ void EditNameBox::prepare() {
|
|||
newHeight += st::contactSkip + _last->height();
|
||||
|
||||
newHeight += st::boxPadding.bottom() + st::contactPadding.bottom();
|
||||
setDimensions(st::boxWideWidth, newHeight);
|
||||
setDimensions(st::boxWidth, newHeight);
|
||||
|
||||
addButton(tr::lng_settings_save(), [=] { save(); });
|
||||
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
||||
|
|
|
@ -139,8 +139,8 @@ contactUserIcon: icon {{ "settings/settings_name", menuIconFg }};
|
|||
contactPhoneIcon: icon {{ "settings/settings_phone_number", menuIconFg }};
|
||||
contactIconPosition: point(-5px, 23px);
|
||||
|
||||
contactPadding: margins(49px, 2px, 0px, 12px);
|
||||
contactSkip: 6px;
|
||||
contactPadding: margins(49px, 2px, 0px, 14px);
|
||||
contactSkip: 9px;
|
||||
contactPhoneSkip: 30px;
|
||||
|
||||
contactsPhotoSize: 42px;
|
||||
|
|
|
@ -93,6 +93,7 @@ PeerShortInfoCover::PeerShortInfoCover(
|
|||
, _name(_widget.get(), std::move(name), _nameStyle->st)
|
||||
, _statusStyle(std::make_unique<CustomLabelStyle>(_st.status))
|
||||
, _status(_widget.get(), std::move(status), _statusStyle->st)
|
||||
, _roundMask(Images::CornersMask(_st.radius))
|
||||
, _videoPaused(std::move(videoPaused)) {
|
||||
_widget->setCursor(_cursor);
|
||||
|
||||
|
@ -145,7 +146,7 @@ PeerShortInfoCover::PeerShortInfoCover(
|
|||
_st.size);
|
||||
|
||||
_roundedTopImage = QImage(
|
||||
QSize(_st.size, st::boxRadius) * style::DevicePixelRatio(),
|
||||
QSize(_st.size, _st.radius) * style::DevicePixelRatio(),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
_roundedTopImage.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
_roundedTopImage.fill(Qt::transparent);
|
||||
|
@ -161,6 +162,10 @@ object_ptr<Ui::RpWidget> PeerShortInfoCover::takeOwned() {
|
|||
return std::move(_owned);
|
||||
}
|
||||
|
||||
gsl::span<const QImage, 4> PeerShortInfoCover::roundMask() const {
|
||||
return _roundMask;
|
||||
}
|
||||
|
||||
void PeerShortInfoCover::setScrollTop(int scrollTop) {
|
||||
_scrollTop = scrollTop;
|
||||
_widget->update();
|
||||
|
@ -176,16 +181,21 @@ rpl::lifetime &PeerShortInfoCover::lifetime() {
|
|||
|
||||
void PeerShortInfoCover::paint(QPainter &p) {
|
||||
checkStreamedIsStarted();
|
||||
const auto frame = currentVideoFrame();
|
||||
auto frame = currentVideoFrame();
|
||||
auto paused = _videoPaused && _videoPaused();
|
||||
if (frame.isNull() && _userpicImage.isNull()) {
|
||||
if (!frame.isNull()) {
|
||||
frame = Images::Round(
|
||||
std::move(frame),
|
||||
_roundMask,
|
||||
RectPart::TopLeft | RectPart::TopRight);
|
||||
} else if (_userpicImage.isNull()) {
|
||||
auto image = QImage(
|
||||
_widget->size() * style::DevicePixelRatio(),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
image.fill(Qt::black);
|
||||
_userpicImage = Images::Round(
|
||||
std::move(image),
|
||||
ImageRoundRadius::Small,
|
||||
_roundMask,
|
||||
RectPart::TopLeft | RectPart::TopRight);
|
||||
}
|
||||
|
||||
|
@ -200,7 +210,7 @@ void PeerShortInfoCover::paint(QPainter &p) {
|
|||
|
||||
void PeerShortInfoCover::paintCoverImage(QPainter &p, const QImage &image) {
|
||||
const auto roundedWidth = _st.size;
|
||||
const auto roundedHeight = st::boxRadius;
|
||||
const auto roundedHeight = _st.radius;
|
||||
const auto covered = (_st.size - _scrollTop);
|
||||
if (covered <= 0) {
|
||||
return;
|
||||
|
@ -230,7 +240,7 @@ void PeerShortInfoCover::paintCoverImage(QPainter &p, const QImage &image) {
|
|||
q.end();
|
||||
_roundedTopImage = Images::Round(
|
||||
std::move(_roundedTopImage),
|
||||
ImageRoundRadius::Small,
|
||||
_roundMask,
|
||||
RectPart::TopLeft | RectPart::TopRight);
|
||||
p.drawImage(
|
||||
QRect(0, from, roundedWidth, rounded),
|
||||
|
@ -245,7 +255,7 @@ void PeerShortInfoCover::paintBars(QPainter &p) {
|
|||
_shadowTop = Images::GenerateShadow(height, kShadowMaxAlpha, 0);
|
||||
_shadowTop = Images::Round(
|
||||
_shadowTop.scaled(QSize(_st.size, height) * factor),
|
||||
ImageRoundRadius::Small,
|
||||
_roundMask,
|
||||
RectPart::TopLeft | RectPart::TopRight);
|
||||
}
|
||||
const auto shadowRect = QRect(0, _scrollTop, _st.size, height);
|
||||
|
@ -395,8 +405,6 @@ QImage PeerShortInfoCover::currentVideoFrame() const {
|
|||
const auto request = Media::Streaming::FrameRequest{
|
||||
.resize = size * style::DevicePixelRatio(),
|
||||
.outer = size,
|
||||
.radius = ImageRoundRadius::Small,
|
||||
.corners = RectPart::TopLeft | RectPart::TopRight,
|
||||
};
|
||||
return (_videoInstance
|
||||
&& _videoInstance->player().ready()
|
||||
|
@ -420,9 +428,12 @@ void PeerShortInfoCover::applyUserpic(PeerShortInfoUserpic &&value) {
|
|||
const auto videoChanged = _videoInstance
|
||||
? (_videoInstance->shared() != value.videoDocument)
|
||||
: (value.videoDocument != nullptr);
|
||||
const auto frame = videoChanged ? currentVideoFrame() : QImage();
|
||||
auto frame = videoChanged ? currentVideoFrame() : QImage();
|
||||
if (!frame.isNull()) {
|
||||
_userpicImage = frame;
|
||||
_userpicImage = Images::Round(
|
||||
std::move(frame),
|
||||
_roundMask,
|
||||
RectPart::TopLeft | RectPart::TopRight);
|
||||
}
|
||||
} else if (_userpicImage.cacheKey() != value.photo.cacheKey()) {
|
||||
_userpicImage = std::move(value.photo);
|
||||
|
@ -771,7 +782,7 @@ void PeerShortInfoBox::refreshRoundedTopImage(const QColor &color) {
|
|||
_roundedTop.fill(color);
|
||||
_roundedTop = Images::Round(
|
||||
std::move(_roundedTop),
|
||||
ImageRoundRadius::Small,
|
||||
_cover.roundMask(),
|
||||
RectPart::TopLeft | RectPart::TopRight);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,8 @@ public:
|
|||
[[nodiscard]] not_null<Ui::RpWidget*> widget() const;
|
||||
[[nodiscard]] object_ptr<Ui::RpWidget> takeOwned();
|
||||
|
||||
[[nodiscard]] gsl::span<const QImage, 4> roundMask() const;
|
||||
|
||||
void setScrollTop(int scrollTop);
|
||||
|
||||
[[nodiscard]] rpl::producer<int> moveRequests() const;
|
||||
|
@ -106,6 +108,7 @@ private:
|
|||
std::unique_ptr<CustomLabelStyle> _statusStyle;
|
||||
object_ptr<Ui::FlatLabel> _status;
|
||||
|
||||
std::array<QImage, 4> _roundMask;
|
||||
QImage _userpicImage;
|
||||
QImage _roundedTopImage;
|
||||
QImage _barSmall;
|
||||
|
|
|
@ -41,6 +41,8 @@ struct UserpicState {
|
|||
std::vector<std::shared_ptr<Data::PhotoMedia>> photoPreloads;
|
||||
InMemoryKey userpicKey;
|
||||
PhotoId photoId = PeerData::kUnknownPhotoId;
|
||||
std::array<QImage, 4> roundMask;
|
||||
int size = 0;
|
||||
bool waitingFull = false;
|
||||
bool waitingLoad = false;
|
||||
};
|
||||
|
@ -50,16 +52,16 @@ void GenerateImage(
|
|||
QImage image,
|
||||
bool blurred = false) {
|
||||
using namespace Images;
|
||||
const auto size = st::shortInfoWidth;
|
||||
const auto size = state->size;
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
const auto options = Option::RoundSmall
|
||||
| Option::RoundSkipBottomLeft
|
||||
| Option::RoundSkipBottomRight
|
||||
| (blurred ? Option::Blur : Option());
|
||||
state->current.photo = Images::Prepare(
|
||||
std::move(image),
|
||||
QSize(size, size) * ratio,
|
||||
{ .options = options, .outer = { size, size } });
|
||||
const auto options = blurred ? Option::Blur : Option();
|
||||
state->current.photo = Images::Round(
|
||||
Images::Prepare(
|
||||
std::move(image),
|
||||
QSize(size, size) * ratio,
|
||||
{ .options = options, .outer = { size, size } }),
|
||||
state->roundMask,
|
||||
RectPart::TopLeft | RectPart::TopRight);
|
||||
}
|
||||
|
||||
void GenerateImage(
|
||||
|
@ -350,14 +352,19 @@ bool ProcessCurrent(
|
|||
}
|
||||
|
||||
[[nodiscard]] PreparedShortInfoUserpic UserpicValue(
|
||||
not_null<PeerData*> peer) {
|
||||
not_null<PeerData*> peer,
|
||||
const style::ShortInfoCover &st) {
|
||||
const auto moveRequests = std::make_shared<rpl::event_stream<int>>();
|
||||
auto move = [=](int shift) {
|
||||
moveRequests->fire_copy(shift);
|
||||
};
|
||||
const auto size = st.size;
|
||||
const auto radius = st.radius;
|
||||
auto value = [=](auto consumer) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
const auto state = lifetime.make_state<UserpicState>();
|
||||
state->size = size;
|
||||
state->roundMask = Images::CornersMask(radius);
|
||||
const auto push = [=](bool force = false) {
|
||||
if (ProcessCurrent(peer, state) || force) {
|
||||
consumer.put_next_copy(state->current);
|
||||
|
@ -421,7 +428,7 @@ object_ptr<Ui::BoxContent> PrepareShortInfoBox(
|
|||
: peer->isBroadcast()
|
||||
? PeerShortInfoType::Channel
|
||||
: PeerShortInfoType::Group;
|
||||
auto userpic = UserpicValue(peer);
|
||||
auto userpic = UserpicValue(peer, st::shortInfoCover);
|
||||
auto result = Box<PeerShortInfoBox>(
|
||||
type,
|
||||
FieldsValue(peer),
|
||||
|
@ -456,6 +463,8 @@ rpl::producer<QString> PrepareShortInfoStatus(not_null<PeerData*> peer) {
|
|||
return StatusValue(peer);
|
||||
}
|
||||
|
||||
PreparedShortInfoUserpic PrepareShortInfoUserpic(not_null<PeerData*> peer) {
|
||||
return UserpicValue(peer);
|
||||
PreparedShortInfoUserpic PrepareShortInfoUserpic(
|
||||
not_null<PeerData*> peer,
|
||||
const style::ShortInfoCover &st) {
|
||||
return UserpicValue(peer, st);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
class PeerData;
|
||||
|
||||
namespace style {
|
||||
struct ShortInfoCover;
|
||||
} // namespace style
|
||||
|
||||
namespace Ui {
|
||||
class BoxContent;
|
||||
} // namespace Ui
|
||||
|
@ -39,4 +43,5 @@ struct PreparedShortInfoUserpic {
|
|||
not_null<PeerData*> peer);
|
||||
|
||||
[[nodiscard]] PreparedShortInfoUserpic PrepareShortInfoUserpic(
|
||||
not_null<PeerData*> peer);
|
||||
not_null<PeerData*> peer,
|
||||
const style::ShortInfoCover &st);
|
||||
|
|
|
@ -916,7 +916,7 @@ void SendFilesBox::paintEvent(QPaintEvent *e) {
|
|||
p.setPen(st::boxTitleFg);
|
||||
p.drawTextLeft(
|
||||
st::boxPhotoTitlePosition.x(),
|
||||
st::boxTitlePosition.y(),
|
||||
st::boxTitlePosition.y() - st::boxTopMargin,
|
||||
width(),
|
||||
_titleText);
|
||||
}
|
||||
|
|
|
@ -553,6 +553,7 @@ groupCallPopupMenuWithCover: PopupMenu(groupCallPopupMenu) {
|
|||
}
|
||||
}
|
||||
groupCallMenuCover: ShortInfoCover(shortInfoCover) {
|
||||
radius: roundRadiusSmall;
|
||||
size: groupCallMenuCoverSize;
|
||||
namePosition: point(17px, 28px);
|
||||
statusPosition: point(17px, 8px);
|
||||
|
|
|
@ -1263,7 +1263,9 @@ base::unique_qptr<Ui::PopupMenu> Members::Controller::createRowContextMenu(
|
|||
participantPeer
|
||||
) | rpl::map([](const auto &text) { return text.text; }),
|
||||
PrepareShortInfoStatus(participantPeer),
|
||||
PrepareShortInfoUserpic(participantPeer)));
|
||||
PrepareShortInfoUserpic(
|
||||
participantPeer,
|
||||
st::groupCallMenuCover)));
|
||||
|
||||
if (const auto about = participantPeer->about(); !about.isEmpty()) {
|
||||
result->addAction(base::make_unique_q<AboutItem>(
|
||||
|
|
|
@ -199,40 +199,40 @@ infoLayerTopBarBack: IconButton(infoTopBarBack) {
|
|||
width: infoLayerTopBarHeight;
|
||||
height: infoLayerTopBarHeight;
|
||||
|
||||
iconPosition: point(12px, -1px);
|
||||
iconPosition: point(10px, -1px);
|
||||
icon: infoLayerTopBarBackIcon;
|
||||
iconOver: infoLayerTopBarBackIconOver;
|
||||
rippleAreaSize: 44px;
|
||||
rippleAreaSize: 40px;
|
||||
rippleAreaPosition: point(6px, 4px);
|
||||
}
|
||||
infoLayerTopBarMediaCancel: IconButton(infoLayerTopBarBack) {
|
||||
icon: icon {{ "info_close", boxTitleCloseFg }};
|
||||
iconOver: icon {{ "info_close", boxTitleCloseFgOver }};
|
||||
}
|
||||
infoLayerTopBarClose: IconButton(infoLayerTopBarMediaCancel) {
|
||||
width: 50px;
|
||||
iconPosition: point(6px, -1px);
|
||||
rippleAreaPosition: point(0px, 6px);
|
||||
iconPosition: point(4px, -1px);
|
||||
rippleAreaPosition: point(0px, 4px);
|
||||
}
|
||||
infoLayerTopBarMenu: IconButton(infoLayerTopBarClose) {
|
||||
width: 44px;
|
||||
width: 40px;
|
||||
icon: icon {{ "title_menu_dots", boxTitleCloseFg }};
|
||||
iconOver: icon {{ "title_menu_dots", boxTitleCloseFgOver }};
|
||||
iconPosition: point(18px, -1px);
|
||||
iconPosition: point(16px, -1px);
|
||||
}
|
||||
infoLayerTopBarNotifications: IconButton(infoLayerTopBarMenu) {
|
||||
icon: icon {{ "info_notifications", boxTitleCloseFg }};
|
||||
iconOver: icon {{ "info_notifications", boxTitleCloseFgOver }};
|
||||
iconPosition: point(5px, 11px);
|
||||
iconPosition: point(3px, 9px);
|
||||
}
|
||||
infoLayerTopBarCall: IconButton(infoLayerTopBarMenu) {
|
||||
icon: icon {{ "top_bar_call", boxTitleCloseFg }};
|
||||
iconOver: icon {{ "top_bar_call", boxTitleCloseFgOver }};
|
||||
iconPosition: point(5px, -1px);
|
||||
iconPosition: point(3px, -1px);
|
||||
}
|
||||
infoLayerTopBarSave: IconButton(infoLayerTopBarNotifications) {
|
||||
icon: icon {{ "passport_ready", windowActiveTextFg }};
|
||||
iconOver: icon {{ "passport_ready", windowActiveTextFg }};
|
||||
iconPosition: point(13px, 18px);
|
||||
iconPosition: point(11px, 16px);
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: lightButtonBgOver;
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ infoLayerTopBarForward: IconButton(infoLayerTopBarBack) {
|
|||
icon: icon {{ "info_media_forward", boxTitleCloseFg }};
|
||||
iconOver: icon {{ "info_media_forward", boxTitleCloseFgOver }};
|
||||
iconPosition: point(11px, -1px);
|
||||
rippleAreaPosition: point(1px, 6px);
|
||||
rippleAreaPosition: point(3px, 4px);
|
||||
}
|
||||
infoLayerTopBarDelete: IconButton(infoLayerTopBarForward) {
|
||||
icon: icon {{ "info_media_delete", boxTitleCloseFg }};
|
||||
|
@ -252,7 +252,7 @@ infoLayerTopBar: InfoTopBar(infoTopBar) {
|
|||
height: infoLayerTopBarHeight;
|
||||
back: infoLayerTopBarBack;
|
||||
title: boxTitle;
|
||||
titlePosition: boxTitlePosition;
|
||||
titlePosition: point(24px, 13px);
|
||||
bg: boxBg;
|
||||
mediaCancel: infoLayerTopBarMediaCancel;
|
||||
mediaActionsSkip: 6px;
|
||||
|
@ -955,7 +955,7 @@ infoScrollDateHideTimeout: historyScrollDateHideTimeout;
|
|||
infoDateFadeDuration: historyDateFadeDuration;
|
||||
|
||||
shortInfoWidth: 304px;
|
||||
shortInfoLabeledPadding: margins(20px, 16px, 20px, 0px);
|
||||
shortInfoLabeledPadding: margins(24px, 16px, 24px, 0px);
|
||||
shortInfoScroll: ScrollArea(defaultScrollArea) {
|
||||
deltat: 3px;
|
||||
deltab: 0px;
|
||||
|
@ -969,6 +969,7 @@ shortInfoScroll: ScrollArea(defaultScrollArea) {
|
|||
|
||||
ShortInfoCover {
|
||||
size: pixels;
|
||||
radius: pixels;
|
||||
name: FlatLabel;
|
||||
namePosition: point;
|
||||
status: FlatLabel;
|
||||
|
@ -981,6 +982,7 @@ ShortInfoCover {
|
|||
}
|
||||
shortInfoCover: ShortInfoCover {
|
||||
size: shortInfoWidth;
|
||||
radius: boxRadius;
|
||||
name: FlatLabel(defaultFlatLabel) {
|
||||
textFg: groupCallVideoTextFg;
|
||||
maxHeight: 19px;
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 7e1effeeebfc411fbdf0370754dc7d9735f33805
|
||||
Subproject commit 681da392eb0523e87f9c1e9b3c732757e0c18850
|
Loading…
Add table
Reference in a new issue