mirror of https://github.com/procxx/kepka.git
				
				
				
			Handle click on group thumb item in MediaView.
This commit is contained in:
		
							parent
							
								
									59e5ffe743
								
							
						
					
					
						commit
						0171a4e874
					
				| 
						 | 
				
			
			@ -105,7 +105,7 @@ public:
 | 
			
		|||
		Dying,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Thumb(Key key, ImagePtr image);
 | 
			
		||||
	Thumb(Key key, ImagePtr image, base::lambda<void()> handler);
 | 
			
		||||
 | 
			
		||||
	int leftToUpdate() const;
 | 
			
		||||
	int rightToUpdate() const;
 | 
			
		||||
| 
						 | 
				
			
			@ -118,6 +118,7 @@ public:
 | 
			
		|||
	bool removed() const;
 | 
			
		||||
 | 
			
		||||
	void paint(Painter &p, int x, int y, int outerWidth, float64 progress);
 | 
			
		||||
	ClickHandlerPtr getState(QPoint point) const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	QSize wantedPixSize() const;
 | 
			
		||||
| 
						 | 
				
			
			@ -126,30 +127,33 @@ private:
 | 
			
		|||
	int currentWidth() const;
 | 
			
		||||
	int finalLeft() const;
 | 
			
		||||
	int finalWidth() const;
 | 
			
		||||
	void toggle(bool visible);
 | 
			
		||||
	void animateTo(int left, int width);
 | 
			
		||||
 | 
			
		||||
	ClickHandlerPtr _link;
 | 
			
		||||
	const Key _key;
 | 
			
		||||
	ImagePtr _image;
 | 
			
		||||
	State _state = State::Alive;
 | 
			
		||||
	QPixmap _full;
 | 
			
		||||
	int _fullWidth = 0;
 | 
			
		||||
	bool _hiding = true;
 | 
			
		||||
	bool _hiding = false;
 | 
			
		||||
 | 
			
		||||
	anim::value _left = { 0. };
 | 
			
		||||
	anim::value _width = { 0. };
 | 
			
		||||
	anim::value _opacity = { 0. };
 | 
			
		||||
	anim::value _opacity = { 0., 1. };
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GroupThumbs::Thumb::Thumb(Key key, ImagePtr image)
 | 
			
		||||
GroupThumbs::Thumb::Thumb(
 | 
			
		||||
	Key key,
 | 
			
		||||
	ImagePtr image,
 | 
			
		||||
	base::lambda<void()> handler)
 | 
			
		||||
: _key(key)
 | 
			
		||||
, _image(image) {
 | 
			
		||||
	_link = std::make_shared<LambdaClickHandler>(std::move(handler));
 | 
			
		||||
	_fullWidth = std::min(
 | 
			
		||||
		wantedPixSize().width(),
 | 
			
		||||
		st::mediaviewGroupWidthMax);
 | 
			
		||||
	validateImage();
 | 
			
		||||
	toggle(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QSize GroupThumbs::Thumb::wantedPixSize() const {
 | 
			
		||||
| 
						 | 
				
			
			@ -229,23 +233,21 @@ void GroupThumbs::Thumb::setState(State state) {
 | 
			
		|||
			_left = anim::value(-_fullWidth / 2);
 | 
			
		||||
			_width = anim::value(_fullWidth);
 | 
			
		||||
		} else {
 | 
			
		||||
			toggle(true);
 | 
			
		||||
			_opacity.start(1.);
 | 
			
		||||
		}
 | 
			
		||||
		_hiding = false;
 | 
			
		||||
		animateTo(-_fullWidth / 2, _fullWidth);
 | 
			
		||||
	} else if (_state == State::Alive) {
 | 
			
		||||
		toggle(true);
 | 
			
		||||
		_opacity.start(0.7);
 | 
			
		||||
		_hiding = false;
 | 
			
		||||
	} else if (_state == State::Dying) {
 | 
			
		||||
		toggle(false);
 | 
			
		||||
		_opacity.start(0.);
 | 
			
		||||
		_hiding = true;
 | 
			
		||||
		_left.restart();
 | 
			
		||||
		_width.restart();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GroupThumbs::Thumb::toggle(bool visible) {
 | 
			
		||||
	_hiding = !visible;
 | 
			
		||||
	_opacity.start(_hiding ? 0. : 1.);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GroupThumbs::Thumb::animateTo(int left, int width) {
 | 
			
		||||
	_left.start(left);
 | 
			
		||||
	_width.start(width);
 | 
			
		||||
| 
						 | 
				
			
			@ -324,6 +326,17 @@ void GroupThumbs::Thumb::paint(
 | 
			
		|||
	p.setOpacity(opacity);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClickHandlerPtr GroupThumbs::Thumb::getState(QPoint point) const {
 | 
			
		||||
	if (_state != State::Alive) {
 | 
			
		||||
		return nullptr;
 | 
			
		||||
	}
 | 
			
		||||
	const auto left = finalLeft();
 | 
			
		||||
	const auto width = finalWidth();
 | 
			
		||||
	return QRect(left, 0, width, st::mediaviewGroupHeight).contains(point)
 | 
			
		||||
		? _link
 | 
			
		||||
		: nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GroupThumbs::GroupThumbs(Context context)
 | 
			
		||||
: _context(context) {
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -486,7 +499,12 @@ auto GroupThumbs::createThumb(Key key) -> std::unique_ptr<Thumb> {
 | 
			
		|||
 | 
			
		||||
auto GroupThumbs::createThumb(Key key, ImagePtr image)
 | 
			
		||||
-> std::unique_ptr<Thumb> {
 | 
			
		||||
	return std::make_unique<Thumb>(key, image);
 | 
			
		||||
	const auto weak = base::make_weak(this);
 | 
			
		||||
	return std::make_unique<Thumb>(key, image, [=] {
 | 
			
		||||
		if (const auto strong = weak.get()) {
 | 
			
		||||
			strong->_activateStream.fire_copy(key);
 | 
			
		||||
		}
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
auto GroupThumbs::validateCacheEntry(Key key) -> not_null<Thumb*> {
 | 
			
		||||
| 
						 | 
				
			
			@ -597,6 +615,16 @@ void GroupThumbs::paint(
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClickHandlerPtr GroupThumbs::getState(QPoint point) const {
 | 
			
		||||
	point -= QPoint((_width / 2), st::mediaviewGroupPadding.top());
 | 
			
		||||
	for (const auto &[key, thumb] : _cache) {
 | 
			
		||||
		if (auto link = thumb->getState(point)) {
 | 
			
		||||
			return link;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GroupThumbs::countUpdatedRect() {
 | 
			
		||||
	if (_cache.empty()) {
 | 
			
		||||
		return;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "history/history_item_components.h"
 | 
			
		||||
#include "base/weak_ptr.h"
 | 
			
		||||
 | 
			
		||||
class SharedMediaWithLastSlice;
 | 
			
		||||
class UserPhotosSlice;
 | 
			
		||||
| 
						 | 
				
			
			@ -28,8 +29,10 @@ class UserPhotosSlice;
 | 
			
		|||
namespace Media {
 | 
			
		||||
namespace View {
 | 
			
		||||
 | 
			
		||||
class GroupThumbs {
 | 
			
		||||
class GroupThumbs : public base::has_weak_ptr {
 | 
			
		||||
public:
 | 
			
		||||
	using Key = base::variant<PhotoId, FullMsgId>;
 | 
			
		||||
 | 
			
		||||
	static void Refresh(
 | 
			
		||||
		std::unique_ptr<GroupThumbs> &instance,
 | 
			
		||||
		const SharedMediaWithLastSlice &slice,
 | 
			
		||||
| 
						 | 
				
			
			@ -49,17 +52,21 @@ public:
 | 
			
		|||
	void checkForAnimationStart();
 | 
			
		||||
 | 
			
		||||
	void paint(Painter &p, int x, int y, int outerWidth, TimeMs ms);
 | 
			
		||||
	ClickHandlerPtr getState(QPoint point) const;
 | 
			
		||||
 | 
			
		||||
	rpl::producer<QRect> updateRequests() const {
 | 
			
		||||
		return _updateRequests.events();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rpl::producer<Key> activateRequests() const {
 | 
			
		||||
		return _activateStream.events();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rpl::lifetime &lifetime() {
 | 
			
		||||
		return _lifetime;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	using Context = base::optional_variant<PeerId, MessageGroupId>;
 | 
			
		||||
	using Key = base::variant<PhotoId, FullMsgId>;
 | 
			
		||||
 | 
			
		||||
	GroupThumbs(Context context);
 | 
			
		||||
	~GroupThumbs();
 | 
			
		||||
| 
						 | 
				
			
			@ -98,11 +105,12 @@ private:
 | 
			
		|||
	base::flat_map<Key, std::unique_ptr<Thumb>> _cache;
 | 
			
		||||
	int _width = 0;
 | 
			
		||||
	int _limit = 0;
 | 
			
		||||
	rpl::event_stream<QRect> _updateRequests;
 | 
			
		||||
	rpl::lifetime _lifetime;
 | 
			
		||||
 | 
			
		||||
	QRect _updatedRect;
 | 
			
		||||
 | 
			
		||||
	rpl::event_stream<QRect> _updateRequests;
 | 
			
		||||
	rpl::event_stream<Key> _activateStream;
 | 
			
		||||
	rpl::lifetime _lifetime;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace View
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1288,24 +1288,41 @@ void MediaView::refreshGroupThumbs() {
 | 
			
		|||
		_groupThumbs->resizeToWidth(_groupThumbsAvailableWidth);
 | 
			
		||||
	}
 | 
			
		||||
	if (_groupThumbs && !existed) {
 | 
			
		||||
		_groupThumbs->updateRequests(
 | 
			
		||||
		) | rpl::start_with_next([this](QRect rect) {
 | 
			
		||||
			const auto shift = (width() / 2);
 | 
			
		||||
			_groupThumbsRect = QRect(
 | 
			
		||||
				shift + rect.x(),
 | 
			
		||||
				_groupThumbsTop,
 | 
			
		||||
				rect.width(),
 | 
			
		||||
				_groupThumbs->height());
 | 
			
		||||
			update(_groupThumbsRect);
 | 
			
		||||
		}, _groupThumbs->lifetime());
 | 
			
		||||
		_groupThumbsRect = QRect(
 | 
			
		||||
			_groupThumbsLeft,
 | 
			
		||||
			_groupThumbsTop,
 | 
			
		||||
			width() - 2 * _groupThumbsLeft,
 | 
			
		||||
			height() - _groupThumbsTop);
 | 
			
		||||
		initGroupThumbs();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MediaView::initGroupThumbs() {
 | 
			
		||||
	Expects(_groupThumbs != nullptr);
 | 
			
		||||
 | 
			
		||||
	_groupThumbs->updateRequests(
 | 
			
		||||
	) | rpl::start_with_next([this](QRect rect) {
 | 
			
		||||
		const auto shift = (width() / 2);
 | 
			
		||||
		_groupThumbsRect = QRect(
 | 
			
		||||
			shift + rect.x(),
 | 
			
		||||
			_groupThumbsTop,
 | 
			
		||||
			rect.width(),
 | 
			
		||||
			_groupThumbs->height());
 | 
			
		||||
		update(_groupThumbsRect);
 | 
			
		||||
	}, _groupThumbs->lifetime());
 | 
			
		||||
 | 
			
		||||
	_groupThumbs->activateRequests(
 | 
			
		||||
	) | rpl::start_with_next([this](Media::View::GroupThumbs::Key key) {
 | 
			
		||||
		if (const auto photoId = base::get_if<PhotoId>(&key)) {
 | 
			
		||||
			const auto photo = App::photo(*photoId);
 | 
			
		||||
			moveToEntity({ photo, nullptr });
 | 
			
		||||
		} else if (const auto itemId = base::get_if<FullMsgId>(&key)) {
 | 
			
		||||
			moveToEntity(entityForItemId(*itemId));
 | 
			
		||||
		}
 | 
			
		||||
	}, _groupThumbs->lifetime());
 | 
			
		||||
 | 
			
		||||
	_groupThumbsRect = QRect(
 | 
			
		||||
		_groupThumbsLeft,
 | 
			
		||||
		_groupThumbsTop,
 | 
			
		||||
		width() - 2 * _groupThumbsLeft,
 | 
			
		||||
		height() - _groupThumbsTop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MediaView::showPhoto(not_null<PhotoData*> photo, HistoryItem *context) {
 | 
			
		||||
	if (context) {
 | 
			
		||||
		setContext(context);
 | 
			
		||||
| 
						 | 
				
			
			@ -2421,16 +2438,21 @@ MediaView::Entity MediaView::entityForSharedMedia(int index) const {
 | 
			
		|||
		// Last peer photo.
 | 
			
		||||
		return { *photo, nullptr };
 | 
			
		||||
	} else if (const auto itemId = base::get_if<FullMsgId>(&value)) {
 | 
			
		||||
		if (const auto item = App::histItemById(*itemId)) {
 | 
			
		||||
			if (const auto media = item->getMedia()) {
 | 
			
		||||
				if (const auto photo = media->getPhoto()) {
 | 
			
		||||
					return { photo, item };
 | 
			
		||||
				} else if (const auto document = media->getDocument()) {
 | 
			
		||||
					return { document, item };
 | 
			
		||||
				}
 | 
			
		||||
		return entityForItemId(*itemId);
 | 
			
		||||
	}
 | 
			
		||||
	return { base::none, nullptr };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MediaView::Entity MediaView::entityForItemId(const FullMsgId &itemId) const {
 | 
			
		||||
	if (const auto item = App::histItemById(itemId)) {
 | 
			
		||||
		if (const auto media = item->getMedia()) {
 | 
			
		||||
			if (const auto photo = media->getPhoto()) {
 | 
			
		||||
				return { photo, item };
 | 
			
		||||
			} else if (const auto document = media->getDocument()) {
 | 
			
		||||
				return { document, item };
 | 
			
		||||
			}
 | 
			
		||||
			return { base::none, item };
 | 
			
		||||
		}
 | 
			
		||||
		return { base::none, item };
 | 
			
		||||
	}
 | 
			
		||||
	return { base::none, nullptr };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2481,12 +2503,14 @@ bool MediaView::moveToNext(int delta) {
 | 
			
		|||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	auto newIndex = *_index + delta;
 | 
			
		||||
	auto entity = entityByIndex(newIndex);
 | 
			
		||||
	return moveToEntity(entityByIndex(newIndex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool MediaView::moveToEntity(const Entity &entity, int preloadDelta) {
 | 
			
		||||
	if (!entity.data && !entity.item) {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	_index = newIndex;
 | 
			
		||||
	if (auto item = entity.item) {
 | 
			
		||||
	if (const auto item = entity.item) {
 | 
			
		||||
		setContext(item);
 | 
			
		||||
	} else if (_peer) {
 | 
			
		||||
		setContext(_peer);
 | 
			
		||||
| 
						 | 
				
			
			@ -2501,7 +2525,7 @@ bool MediaView::moveToNext(int delta) {
 | 
			
		|||
	} else {
 | 
			
		||||
		displayDocument(nullptr, entity.item);
 | 
			
		||||
	}
 | 
			
		||||
	preloadData(delta);
 | 
			
		||||
	preloadData(preloadDelta);
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2695,8 +2719,13 @@ void MediaView::updateOver(QPoint pos) {
 | 
			
		|||
		auto textState = _caption.getState(pos - _captionRect.topLeft(), _captionRect.width());
 | 
			
		||||
		lnk = textState.link;
 | 
			
		||||
		lnkhost = this;
 | 
			
		||||
	} else if (_groupThumbs && _groupThumbsRect.contains(pos)) {
 | 
			
		||||
		const auto point = pos - QPoint(_groupThumbsLeft, _groupThumbsTop);
 | 
			
		||||
		lnk = _groupThumbs->getState(point);
 | 
			
		||||
		lnkhost = this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// retina
 | 
			
		||||
	if (pos.x() == width()) {
 | 
			
		||||
		pos.setX(pos.x() - 1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -161,6 +161,8 @@ private:
 | 
			
		|||
	Entity entityForUserPhotos(int index) const;
 | 
			
		||||
	Entity entityForSharedMedia(int index) const;
 | 
			
		||||
	Entity entityByIndex(int index) const;
 | 
			
		||||
	Entity entityForItemId(const FullMsgId &itemId) const;
 | 
			
		||||
	bool moveToEntity(const Entity &entity, int preloadDelta = 0);
 | 
			
		||||
	void setContext(base::optional_variant<
 | 
			
		||||
		not_null<HistoryItem*>,
 | 
			
		||||
		not_null<PeerData*>> context);
 | 
			
		||||
| 
						 | 
				
			
			@ -250,8 +252,8 @@ private:
 | 
			
		|||
	bool updateOverState(OverState newState);
 | 
			
		||||
	float64 overLevel(OverState control) const;
 | 
			
		||||
 | 
			
		||||
	QRect groupThumbsFullRect() const;
 | 
			
		||||
	void checkGroupThumbsAnimation();
 | 
			
		||||
	void initGroupThumbs();
 | 
			
		||||
 | 
			
		||||
	QBrush _transparentBrush;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue