mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-25 04:38:23 +00:00
Add fast chat photo upload to info profile.
This commit is contained in:
parent
8dd3f24285
commit
aecc119bac
Telegram
Resources/icons
SourceFiles
boxes/peers
info/profile
ui
window
BIN
Telegram/Resources/icons/upload_chat_photo.png
Normal file
BIN
Telegram/Resources/icons/upload_chat_photo.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 425 B |
BIN
Telegram/Resources/icons/upload_chat_photo@2x.png
Normal file
BIN
Telegram/Resources/icons/upload_chat_photo@2x.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 873 B |
@ -114,7 +114,6 @@ private:
|
|||||||
object_ptr<Ui::RpWidget> createInvitesEdit();
|
object_ptr<Ui::RpWidget> createInvitesEdit();
|
||||||
object_ptr<Ui::RpWidget> createDeleteButton();
|
object_ptr<Ui::RpWidget> createDeleteButton();
|
||||||
|
|
||||||
void refreshInitialPhotoImage();
|
|
||||||
void submitTitle();
|
void submitTitle();
|
||||||
void submitDescription();
|
void submitDescription();
|
||||||
void deleteWithConfirmation();
|
void deleteWithConfirmation();
|
||||||
@ -264,31 +263,9 @@ object_ptr<Ui::RpWidget> Controller::createPhotoEdit() {
|
|||||||
st::editPeerPhotoMargins);
|
st::editPeerPhotoMargins);
|
||||||
_controls.photo = photoWrap->entity();
|
_controls.photo = photoWrap->entity();
|
||||||
|
|
||||||
_controls.initialPhotoImageWaiting = base::ObservableViewer(
|
|
||||||
Auth().downloaderTaskFinished())
|
|
||||||
| rpl::start_with_next([=] {
|
|
||||||
refreshInitialPhotoImage();
|
|
||||||
});
|
|
||||||
refreshInitialPhotoImage();
|
|
||||||
|
|
||||||
return photoWrap;
|
return photoWrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::refreshInitialPhotoImage() {
|
|
||||||
//if (auto image = _channel->currentUserpic()) {
|
|
||||||
// image->load();
|
|
||||||
// if (image->loaded()) {
|
|
||||||
// _controls.photo->setImage(image->pixNoCache(
|
|
||||||
// st::editPeerPhotoSize * cIntRetinaFactor(),
|
|
||||||
// st::editPeerPhotoSize * cIntRetinaFactor(),
|
|
||||||
// Images::Option::Smooth).toImage());
|
|
||||||
// _controls.initialPhotoImageWaiting.destroy();
|
|
||||||
// }
|
|
||||||
//} else {
|
|
||||||
// _controls.initialPhotoImageWaiting.destroy();
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
object_ptr<Ui::RpWidget> Controller::createTitleEdit() {
|
object_ptr<Ui::RpWidget> Controller::createTitleEdit() {
|
||||||
Expects(_wrap != nullptr);
|
Expects(_wrap != nullptr);
|
||||||
|
|
||||||
|
@ -243,7 +243,6 @@ Cover::Cover(
|
|||||||
_name->setContextCopyText(lang(lng_profile_copy_fullname));
|
_name->setContextCopyText(lang(lng_profile_copy_fullname));
|
||||||
_status->setAttribute(Qt::WA_TransparentForMouseEvents);
|
_status->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
|
||||||
initUserpicButton();
|
|
||||||
initViewers();
|
initViewers();
|
||||||
setupChildGeometry();
|
setupChildGeometry();
|
||||||
}
|
}
|
||||||
@ -275,10 +274,6 @@ Cover *Cover::setOnlineCount(rpl::producer<int> &&count) {
|
|||||||
|
|
||||||
void Cover::initViewers() {
|
void Cover::initViewers() {
|
||||||
using Flag = Notify::PeerUpdate::Flag;
|
using Flag = Notify::PeerUpdate::Flag;
|
||||||
Notify::PeerUpdateValue(_peer, Flag::PhotoChanged)
|
|
||||||
| rpl::start_with_next(
|
|
||||||
[this] { refreshUserpicLink(); },
|
|
||||||
lifetime());
|
|
||||||
Notify::PeerUpdateValue(_peer, Flag::NameChanged)
|
Notify::PeerUpdateValue(_peer, Flag::NameChanged)
|
||||||
| rpl::start_with_next(
|
| rpl::start_with_next(
|
||||||
[this] { refreshNameText(); },
|
[this] { refreshNameText(); },
|
||||||
@ -288,12 +283,30 @@ void Cover::initViewers() {
|
|||||||
| rpl::start_with_next(
|
| rpl::start_with_next(
|
||||||
[this] { refreshStatusText(); },
|
[this] { refreshStatusText(); },
|
||||||
lifetime());
|
lifetime());
|
||||||
|
if (!_peer->isUser()) {
|
||||||
|
Notify::PeerUpdateValue(_peer,
|
||||||
|
Flag::ChannelRightsChanged | Flag::ChatCanEdit)
|
||||||
|
| rpl::start_with_next(
|
||||||
|
[this] { refreshUploadPhotoOverlay(); },
|
||||||
|
lifetime());
|
||||||
|
}
|
||||||
VerifiedValue(_peer)
|
VerifiedValue(_peer)
|
||||||
| rpl::start_with_next(
|
| rpl::start_with_next(
|
||||||
[this](bool verified) { setVerified(verified); },
|
[this](bool verified) { setVerified(verified); },
|
||||||
lifetime());
|
lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Cover::refreshUploadPhotoOverlay() {
|
||||||
|
_userpic->switchChangePhotoOverlay([&] {
|
||||||
|
if (auto chat = _peer->asChat()) {
|
||||||
|
return chat->canEdit();
|
||||||
|
} else if (auto channel = _peer->asChannel()) {
|
||||||
|
return channel->canEditInformation();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
|
||||||
void Cover::setVerified(bool verified) {
|
void Cover::setVerified(bool verified) {
|
||||||
if ((_verifiedCheck != nullptr) == verified) {
|
if ((_verifiedCheck != nullptr) == verified) {
|
||||||
return;
|
return;
|
||||||
@ -313,29 +326,6 @@ void Cover::setVerified(bool verified) {
|
|||||||
refreshNameGeometry(width());
|
refreshNameGeometry(width());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cover::initUserpicButton() {
|
|
||||||
_userpic->setClickedCallback([this] {
|
|
||||||
auto hasPhoto = (_peer->photoId != 0);
|
|
||||||
auto knownPhoto = (_peer->photoId != UnknownPeerPhotoId);
|
|
||||||
if (hasPhoto && knownPhoto) {
|
|
||||||
if (auto photo = App::photo(_peer->photoId)) {
|
|
||||||
if (photo->date) {
|
|
||||||
Messenger::Instance().showPhoto(photo, _peer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cover::refreshUserpicLink() {
|
|
||||||
auto hasPhoto = (_peer->photoId != 0);
|
|
||||||
auto knownPhoto = (_peer->photoId != UnknownPeerPhotoId);
|
|
||||||
_userpic->setPointerCursor(hasPhoto && knownPhoto);
|
|
||||||
if (!knownPhoto) {
|
|
||||||
Auth().api().requestFullPeer(_peer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cover::refreshNameText() {
|
void Cover::refreshNameText() {
|
||||||
_name->setText(App::peerName(_peer));
|
_name->setText(App::peerName(_peer));
|
||||||
refreshNameGeometry(width());
|
refreshNameGeometry(width());
|
||||||
|
@ -79,12 +79,11 @@ public:
|
|||||||
private:
|
private:
|
||||||
void setupChildGeometry();
|
void setupChildGeometry();
|
||||||
void initViewers();
|
void initViewers();
|
||||||
void initUserpicButton();
|
|
||||||
void refreshUserpicLink();
|
|
||||||
void refreshNameText();
|
void refreshNameText();
|
||||||
void refreshStatusText();
|
void refreshStatusText();
|
||||||
void refreshNameGeometry(int newWidth);
|
void refreshNameGeometry(int newWidth);
|
||||||
void refreshStatusGeometry(int newWidth);
|
void refreshStatusGeometry(int newWidth);
|
||||||
|
void refreshUploadPhotoOverlay();
|
||||||
void setVerified(bool verified);
|
void setVerified(bool verified);
|
||||||
|
|
||||||
not_null<PeerData*> _peer;
|
not_null<PeerData*> _peer;
|
||||||
|
@ -83,6 +83,7 @@ protected:
|
|||||||
Down = (1 << 1),
|
Down = (1 << 1),
|
||||||
Disabled = (1 << 2),
|
Disabled = (1 << 2),
|
||||||
};
|
};
|
||||||
|
friend constexpr bool is_flag_type(StateFlag) { return true; };
|
||||||
using State = base::flags<StateFlag>;
|
using State = base::flags<StateFlag>;
|
||||||
|
|
||||||
State state() const {
|
State state() const {
|
||||||
|
@ -52,6 +52,74 @@ QPixmap CreateSquarePixmap(int width, Callback &&paintCallback) {
|
|||||||
return App::pixmapFromImageInPlace(std::move(image));
|
return App::pixmapFromImageInPlace(std::move(image));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Callback>
|
||||||
|
void SuggestPhoto(
|
||||||
|
const QImage &image,
|
||||||
|
PeerId peerForCrop,
|
||||||
|
Callback &&callback) {
|
||||||
|
auto badAspect = [](int a, int b) {
|
||||||
|
return (a >= 10 * b);
|
||||||
|
};
|
||||||
|
if (image.isNull()
|
||||||
|
|| badAspect(image.width(), image.height())
|
||||||
|
|| badAspect(image.height(), image.width())) {
|
||||||
|
Ui::show(
|
||||||
|
Box<InformBox>(lang(lng_bad_photo)),
|
||||||
|
LayerOption::KeepOther);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto box = Ui::show(
|
||||||
|
Box<PhotoCropBox>(image, peerForCrop),
|
||||||
|
LayerOption::KeepOther);
|
||||||
|
box->ready()
|
||||||
|
| rpl::start_with_next(
|
||||||
|
std::forward<Callback>(callback),
|
||||||
|
box->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Callback>
|
||||||
|
void SuggestPhotoFile(
|
||||||
|
const FileDialog::OpenResult &result,
|
||||||
|
PeerId peerForCrop,
|
||||||
|
Callback &&callback) {
|
||||||
|
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto image = [&] {
|
||||||
|
if (!result.remoteContent.isEmpty()) {
|
||||||
|
return App::readImage(result.remoteContent);
|
||||||
|
} else if (!result.paths.isEmpty()) {
|
||||||
|
return App::readImage(result.paths.front());
|
||||||
|
}
|
||||||
|
return QImage();
|
||||||
|
}();
|
||||||
|
SuggestPhoto(
|
||||||
|
image,
|
||||||
|
peerForCrop,
|
||||||
|
std::forward<Callback>(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Callback>
|
||||||
|
void ShowChoosePhotoBox(PeerId peerForCrop, Callback &&callback) {
|
||||||
|
auto imgExtensions = cImgExtensions();
|
||||||
|
auto filter = qsl("Image files (*")
|
||||||
|
+ imgExtensions.join(qsl(" *"))
|
||||||
|
+ qsl(");;")
|
||||||
|
+ FileDialog::AllFilesFilter();
|
||||||
|
auto handleChosenPhoto = [
|
||||||
|
peerForCrop,
|
||||||
|
callback = std::forward<Callback>(callback)
|
||||||
|
](auto &&result) mutable {
|
||||||
|
SuggestPhotoFile(result, peerForCrop, std::move(callback));
|
||||||
|
};
|
||||||
|
FileDialog::GetOpenPath(
|
||||||
|
lang(lng_choose_image),
|
||||||
|
filter,
|
||||||
|
std::move(handleChosenPhoto));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
HistoryDownButton::HistoryDownButton(QWidget *parent, const style::TwoIconButton &st) : RippleButton(parent, st.ripple)
|
HistoryDownButton::HistoryDownButton(QWidget *parent, const style::TwoIconButton &st) : RippleButton(parent, st.ripple)
|
||||||
@ -387,63 +455,33 @@ void UserpicButton::setClickHandlerByRole() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UserpicButton::changePhotoLazy() {
|
void UserpicButton::changePhotoLazy() {
|
||||||
auto imgExtensions = cImgExtensions();
|
auto callback = base::lambda_guarded(
|
||||||
auto filter = qsl("Image files (*")
|
|
||||||
+ imgExtensions.join(qsl(" *"))
|
|
||||||
+ qsl(");;")
|
|
||||||
+ FileDialog::AllFilesFilter();
|
|
||||||
auto handleChosenPhoto = base::lambda_guarded(
|
|
||||||
this,
|
this,
|
||||||
[this](auto &&result) { suggestPhotoFile(result); });
|
[this](QImage &&image) { setImage(std::move(image)); });
|
||||||
FileDialog::GetOpenPath(
|
ShowChoosePhotoBox(_peerForCrop, std::move(callback));
|
||||||
lang(lng_choose_image),
|
|
||||||
filter,
|
|
||||||
std::move(handleChosenPhoto));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserpicButton::suggestPhotoFile(
|
void UserpicButton::uploadNewPeerPhoto() {
|
||||||
const FileDialog::OpenResult &result) {
|
auto callback = base::lambda_guarded(
|
||||||
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
|
this,
|
||||||
return;
|
[this](QImage &&image) {
|
||||||
}
|
Messenger::Instance().uploadProfilePhoto(
|
||||||
|
std::move(image),
|
||||||
auto image = [&] {
|
_peer->id
|
||||||
if (!result.remoteContent.isEmpty()) {
|
);
|
||||||
return App::readImage(result.remoteContent);
|
});
|
||||||
} else if (!result.paths.isEmpty()) {
|
ShowChoosePhotoBox(_peerForCrop, std::move(callback));
|
||||||
return App::readImage(result.paths.front());
|
|
||||||
}
|
|
||||||
return QImage();
|
|
||||||
}();
|
|
||||||
suggestPhoto(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UserpicButton::suggestPhoto(const QImage &image) {
|
|
||||||
auto badAspect = [](int a, int b) {
|
|
||||||
return (a >= 10 * b);
|
|
||||||
};
|
|
||||||
if (image.isNull()
|
|
||||||
|| badAspect(image.width(), image.height())
|
|
||||||
|| badAspect(image.height(), image.width())) {
|
|
||||||
Ui::show(
|
|
||||||
Box<InformBox>(lang(lng_bad_photo)),
|
|
||||||
LayerOption::KeepOther);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto box = Ui::show(
|
|
||||||
Box<PhotoCropBox>(image, _peerForCrop),
|
|
||||||
LayerOption::KeepOther);
|
|
||||||
box->ready()
|
|
||||||
| rpl::start_with_next([this](QImage &&image) {
|
|
||||||
setImage(std::move(image));
|
|
||||||
}, box->lifetime());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserpicButton::openPeerPhoto() {
|
void UserpicButton::openPeerPhoto() {
|
||||||
Expects(_peer != nullptr);
|
Expects(_peer != nullptr);
|
||||||
Expects(_controller != nullptr);
|
Expects(_controller != nullptr);
|
||||||
|
|
||||||
|
if (_changeOverlayEnabled && _cursorInChangeOverlay) {
|
||||||
|
uploadNewPeerPhoto();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto id = _peer->photoId;
|
auto id = _peer->photoId;
|
||||||
if (!id || id == UnknownPeerPhotoId) {
|
if (!id || id == UnknownPeerPhotoId) {
|
||||||
return;
|
return;
|
||||||
@ -524,6 +562,47 @@ void UserpicButton::paintEvent(QPaintEvent *e) {
|
|||||||
photoTop + iconTop,
|
photoTop + iconTop,
|
||||||
width());
|
width());
|
||||||
}
|
}
|
||||||
|
} else if (_changeOverlayEnabled) {
|
||||||
|
auto current = _changeOverlayShown.current(
|
||||||
|
ms,
|
||||||
|
(isOver() || isDown()) ? 1. : 0.);
|
||||||
|
auto barHeight = anim::interpolate(
|
||||||
|
0,
|
||||||
|
_st.uploadHeight,
|
||||||
|
current);
|
||||||
|
if (barHeight > 0) {
|
||||||
|
auto barLeft = photoLeft;
|
||||||
|
auto barTop = photoTop + _st.photoSize - barHeight;
|
||||||
|
auto rect = QRect(
|
||||||
|
barLeft,
|
||||||
|
barTop,
|
||||||
|
_st.photoSize,
|
||||||
|
barHeight);
|
||||||
|
p.setClipRect(rect);
|
||||||
|
{
|
||||||
|
PainterHighQualityEnabler hq(p);
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(_st.uploadBg);
|
||||||
|
p.drawEllipse(
|
||||||
|
photoLeft,
|
||||||
|
photoTop,
|
||||||
|
_st.photoSize,
|
||||||
|
_st.photoSize);
|
||||||
|
}
|
||||||
|
auto iconLeft = (_st.uploadIconPosition.x() < 0)
|
||||||
|
? (_st.photoSize - _st.uploadIcon.width()) / 2
|
||||||
|
: _st.uploadIconPosition.x();
|
||||||
|
auto iconTop = (_st.uploadIconPosition.y() < 0)
|
||||||
|
? (_st.uploadHeight - _st.uploadIcon.height()) / 2
|
||||||
|
: _st.uploadIconPosition.y();
|
||||||
|
if (iconTop < barHeight) {
|
||||||
|
_st.uploadIcon.paint(
|
||||||
|
p,
|
||||||
|
barLeft + iconLeft,
|
||||||
|
barTop + iconTop,
|
||||||
|
width());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,8 +631,8 @@ QPoint UserpicButton::prepareRippleStartPosition() const {
|
|||||||
void UserpicButton::processPeerPhoto() {
|
void UserpicButton::processPeerPhoto() {
|
||||||
Expects(_peer != nullptr);
|
Expects(_peer != nullptr);
|
||||||
|
|
||||||
bool hasPhoto = (_peer->photoId && _peer->photoId != UnknownPeerPhotoId);
|
auto hasPhoto = (_peer->photoId
|
||||||
setCursor(hasPhoto ? style::cur_pointer : style::cur_default);
|
&& _peer->photoId != UnknownPeerPhotoId);
|
||||||
_waiting = !_peer->userpicLoaded();
|
_waiting = !_peer->userpicLoaded();
|
||||||
if (_waiting) {
|
if (_waiting) {
|
||||||
_peer->loadUserpic(true);
|
_peer->loadUserpic(true);
|
||||||
@ -561,10 +640,52 @@ void UserpicButton::processPeerPhoto() {
|
|||||||
if (_role == Role::OpenPhoto) {
|
if (_role == Role::OpenPhoto) {
|
||||||
auto id = _peer->photoId;
|
auto id = _peer->photoId;
|
||||||
if (id == UnknownPeerPhotoId) {
|
if (id == UnknownPeerPhotoId) {
|
||||||
_peer->updateFull();
|
_peer->updateFullForced();
|
||||||
}
|
}
|
||||||
auto canOpen = (id != 0 && id != UnknownPeerPhotoId);
|
_canOpenPhoto = (id != 0 && id != UnknownPeerPhotoId);
|
||||||
setCursor(canOpen ? style::cur_pointer : style::cur_default);
|
updateCursor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserpicButton::updateCursor() {
|
||||||
|
Expects(_role == Role::OpenPhoto);
|
||||||
|
|
||||||
|
auto pointer = _canOpenPhoto
|
||||||
|
|| (_changeOverlayEnabled && _cursorInChangeOverlay);
|
||||||
|
setPointerCursor(pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserpicButton::mouseMoveEvent(QMouseEvent *e) {
|
||||||
|
RippleButton::mouseMoveEvent(e);
|
||||||
|
if (_role == Role::OpenPhoto) {
|
||||||
|
updateCursorInChangeOverlay(e->pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserpicButton::updateCursorInChangeOverlay(QPoint localPos) {
|
||||||
|
auto photoPosition = countPhotoPosition();
|
||||||
|
auto overlayRect = QRect(
|
||||||
|
photoPosition.x(),
|
||||||
|
photoPosition.y() + _st.photoSize - _st.uploadHeight,
|
||||||
|
_st.photoSize,
|
||||||
|
_st.uploadHeight);
|
||||||
|
auto inOverlay = overlayRect.contains(localPos);
|
||||||
|
setCursorInChangeOverlay(inOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserpicButton::leaveEventHook(QEvent *e) {
|
||||||
|
if (_role == Role::OpenPhoto) {
|
||||||
|
setCursorInChangeOverlay(false);
|
||||||
|
}
|
||||||
|
return RippleButton::leaveEventHook(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserpicButton::setCursorInChangeOverlay(bool inOverlay) {
|
||||||
|
Expects(_role == Role::OpenPhoto);
|
||||||
|
|
||||||
|
if (_cursorInChangeOverlay != inOverlay) {
|
||||||
|
_cursorInChangeOverlay = inOverlay;
|
||||||
|
updateCursor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -606,7 +727,45 @@ void UserpicButton::startAnimation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UserpicButton::switchChangePhotoOverlay(bool enabled) {
|
void UserpicButton::switchChangePhotoOverlay(bool enabled) {
|
||||||
|
Expects(_role == Role::OpenPhoto);
|
||||||
|
|
||||||
|
if (_changeOverlayEnabled != enabled) {
|
||||||
|
_changeOverlayEnabled = enabled;
|
||||||
|
if (enabled) {
|
||||||
|
if (isOver()) {
|
||||||
|
startChangeOverlayAnimation();
|
||||||
|
}
|
||||||
|
updateCursorInChangeOverlay(
|
||||||
|
mapFromGlobal(QCursor::pos()));
|
||||||
|
} else {
|
||||||
|
_changeOverlayShown.finish();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserpicButton::startChangeOverlayAnimation() {
|
||||||
|
auto over = isOver() || isDown();
|
||||||
|
_changeOverlayShown.start(
|
||||||
|
[this] { update(); },
|
||||||
|
over ? 0. : 1.,
|
||||||
|
over ? 1. : 0.,
|
||||||
|
st::slideWrapDuration);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserpicButton::onStateChanged(
|
||||||
|
State was,
|
||||||
|
StateChangeSource source) {
|
||||||
|
RippleButton::onStateChanged(was, source);
|
||||||
|
if (_changeOverlayEnabled) {
|
||||||
|
auto mask = (StateFlag::Over | StateFlag::Down);
|
||||||
|
auto wasOver = (was & mask) != 0;
|
||||||
|
auto nowOver = (state() & mask) != 0;
|
||||||
|
if (wasOver != nowOver) {
|
||||||
|
startChangeOverlayAnimation();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserpicButton::setImage(QImage &&image) {
|
void UserpicButton::setImage(QImage &&image) {
|
||||||
|
@ -30,10 +30,6 @@ namespace Window {
|
|||||||
class Controller;
|
class Controller;
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
||||||
namespace FileDialog {
|
|
||||||
struct OpenResult;
|
|
||||||
} // namespace FileDialog
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
class HistoryDownButton : public RippleButton {
|
class HistoryDownButton : public RippleButton {
|
||||||
@ -180,7 +176,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e);
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
|
void leaveEventHook(QEvent *e) override;
|
||||||
|
|
||||||
|
void onStateChanged(State was, StateChangeSource source) override;
|
||||||
|
|
||||||
QImage prepareRippleMask() const override;
|
QImage prepareRippleMask() const override;
|
||||||
QPoint prepareRippleStartPosition() const override;
|
QPoint prepareRippleStartPosition() const override;
|
||||||
@ -195,14 +195,16 @@ private:
|
|||||||
void startNewPhotoShowing();
|
void startNewPhotoShowing();
|
||||||
void prepareUserpicPixmap();
|
void prepareUserpicPixmap();
|
||||||
QPoint countPhotoPosition() const;
|
QPoint countPhotoPosition() const;
|
||||||
|
void startChangeOverlayAnimation();
|
||||||
|
void updateCursorInChangeOverlay(QPoint localPos);
|
||||||
|
void setCursorInChangeOverlay(bool inOverlay);
|
||||||
|
void updateCursor();
|
||||||
|
|
||||||
void grabOldUserpic();
|
void grabOldUserpic();
|
||||||
void setClickHandlerByRole();
|
void setClickHandlerByRole();
|
||||||
void openPeerPhoto();
|
void openPeerPhoto();
|
||||||
void changePhotoLazy();
|
void changePhotoLazy();
|
||||||
void suggestPhotoFile(
|
void uploadNewPeerPhoto();
|
||||||
const FileDialog::OpenResult &result);
|
|
||||||
void suggestPhoto(const QImage &image);
|
|
||||||
|
|
||||||
const style::UserpicButton &_st;
|
const style::UserpicButton &_st;
|
||||||
Window::Controller *_controller = nullptr;
|
Window::Controller *_controller = nullptr;
|
||||||
@ -218,6 +220,11 @@ private:
|
|||||||
Animation _a_appearance;
|
Animation _a_appearance;
|
||||||
QImage _result;
|
QImage _result;
|
||||||
|
|
||||||
|
bool _canOpenPhoto = false;
|
||||||
|
bool _cursorInChangeOverlay = false;
|
||||||
|
bool _changeOverlayEnabled = false;
|
||||||
|
Animation _changeOverlayShown;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
@ -500,6 +500,10 @@ UserpicButton {
|
|||||||
changeIcon: icon;
|
changeIcon: icon;
|
||||||
changeIconPosition: point;
|
changeIconPosition: point;
|
||||||
duration: int;
|
duration: int;
|
||||||
|
uploadHeight: pixels;
|
||||||
|
uploadBg: color;
|
||||||
|
uploadIcon: icon;
|
||||||
|
uploadIconPosition: point;
|
||||||
}
|
}
|
||||||
|
|
||||||
InfoProfileButton {
|
InfoProfileButton {
|
||||||
@ -981,6 +985,7 @@ defaultImportantTooltipLabel: FlatLabel(defaultFlatLabel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultChangeUserpicIcon: icon {{ "new_chat_photo", activeButtonFg }};
|
defaultChangeUserpicIcon: icon {{ "new_chat_photo", activeButtonFg }};
|
||||||
|
defaultUploadUserpicIcon: icon {{ "upload_chat_photo", msgDateImgFg }};
|
||||||
defaultUserpicButton: UserpicButton {
|
defaultUserpicButton: UserpicButton {
|
||||||
size: size(76px, 76px);
|
size: size(76px, 76px);
|
||||||
photoSize: 76px;
|
photoSize: 76px;
|
||||||
@ -989,6 +994,10 @@ defaultUserpicButton: UserpicButton {
|
|||||||
changeIcon: defaultChangeUserpicIcon;
|
changeIcon: defaultChangeUserpicIcon;
|
||||||
changeIconPosition: point(23px, 25px);
|
changeIconPosition: point(23px, 25px);
|
||||||
duration: 500;
|
duration: 500;
|
||||||
|
uploadHeight: 24px;
|
||||||
|
uploadBg: msgDateImgBgOver;
|
||||||
|
uploadIcon: defaultUploadUserpicIcon;
|
||||||
|
uploadIconPosition: point(-1px, 1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
historyToDownBelow: icon {
|
historyToDownBelow: icon {
|
||||||
|
@ -199,7 +199,7 @@ void Controller::resizeForThirdSection() {
|
|||||||
|
|
||||||
auto extendBy = qMax(
|
auto extendBy = qMax(
|
||||||
minimalThreeColumnWidth() - layout.bodyWidth,
|
minimalThreeColumnWidth() - layout.bodyWidth,
|
||||||
st::columnMinimalWidthThird);
|
countThirdColumnWidthFromRatio(layout.bodyWidth));
|
||||||
auto newBodyWidth = layout.bodyWidth + extendBy;
|
auto newBodyWidth = layout.bodyWidth + extendBy;
|
||||||
auto currentRatio = Auth().data().dialogsWidthRatio();
|
auto currentRatio = Auth().data().dialogsWidthRatio();
|
||||||
Auth().data().setDialogsWidthRatio(
|
Auth().data().setDialogsWidthRatio(
|
||||||
|
Loading…
Reference in New Issue
Block a user