mirror of https://github.com/procxx/kepka.git
				
				
				
			Video play progress displayed in MediaView (in case of audio stream).
This commit is contained in:
		
							parent
							
								
									d806d079a2
								
							
						
					
					
						commit
						01d448c1bd
					
				| 
						 | 
					@ -718,6 +718,14 @@ void AudioPlayer::stopAndClear() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AudioPlaybackState AudioPlayer::currentVideoState(uint64 videoPlayId) {
 | 
				
			||||||
 | 
						QMutexLocker lock(&playerMutex);
 | 
				
			||||||
 | 
						auto current = dataForType(AudioMsgId::Type::Video);
 | 
				
			||||||
 | 
						if (!current || current->videoPlayId != videoPlayId) return AudioPlaybackState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return current->playbackState;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AudioPlaybackState AudioPlayer::currentState(AudioMsgId *audio, AudioMsgId::Type type) {
 | 
					AudioPlaybackState AudioPlayer::currentState(AudioMsgId *audio, AudioMsgId::Type type) {
 | 
				
			||||||
	QMutexLocker lock(&playerMutex);
 | 
						QMutexLocker lock(&playerMutex);
 | 
				
			||||||
	auto current = dataForType(type);
 | 
						auto current = dataForType(type);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,6 +71,7 @@ public:
 | 
				
			||||||
	void feedFromVideo(VideoSoundPart &&part);
 | 
						void feedFromVideo(VideoSoundPart &&part);
 | 
				
			||||||
	int64 getVideoCorrectedTime(uint64 playId, uint64 systemMs);
 | 
						int64 getVideoCorrectedTime(uint64 playId, uint64 systemMs);
 | 
				
			||||||
	void videoSoundProgress(const AudioMsgId &audio);
 | 
						void videoSoundProgress(const AudioMsgId &audio);
 | 
				
			||||||
 | 
						AudioPlaybackState currentVideoState(uint64 videoPlayId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void stopAndClear();
 | 
						void stopAndClear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -215,12 +216,10 @@ class AudioPlayerFader : public QObject {
 | 
				
			||||||
	Q_OBJECT
 | 
						Q_OBJECT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					 | 
				
			||||||
	AudioPlayerFader(QThread *thread);
 | 
						AudioPlayerFader(QThread *thread);
 | 
				
			||||||
	void resumeDevice();
 | 
						void resumeDevice();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signals:
 | 
					signals:
 | 
				
			||||||
 | 
					 | 
				
			||||||
	void error(const AudioMsgId &audio);
 | 
						void error(const AudioMsgId &audio);
 | 
				
			||||||
	void playPositionUpdated(const AudioMsgId &audio);
 | 
						void playPositionUpdated(const AudioMsgId &audio);
 | 
				
			||||||
	void audioStopped(const AudioMsgId &audio);
 | 
						void audioStopped(const AudioMsgId &audio);
 | 
				
			||||||
| 
						 | 
					@ -228,8 +227,7 @@ signals:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void stopPauseDevice();
 | 
						void stopPauseDevice();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public slots:
 | 
					public slots:
 | 
				
			||||||
 | 
					 | 
				
			||||||
	void onInit();
 | 
						void onInit();
 | 
				
			||||||
	void onTimer();
 | 
						void onTimer();
 | 
				
			||||||
	void onPauseTimer();
 | 
						void onPauseTimer();
 | 
				
			||||||
| 
						 | 
					@ -241,7 +239,6 @@ signals:
 | 
				
			||||||
	void onSongVolumeChanged();
 | 
						void onSongVolumeChanged();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					 | 
				
			||||||
	enum {
 | 
						enum {
 | 
				
			||||||
		EmitError = 0x01,
 | 
							EmitError = 0x01,
 | 
				
			||||||
		EmitStopped = 0x02,
 | 
							EmitStopped = 0x02,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,8 @@ namespace Media {
 | 
				
			||||||
namespace Clip {
 | 
					namespace Clip {
 | 
				
			||||||
namespace internal {
 | 
					namespace internal {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FFMpegReaderImplementation::FFMpegReaderImplementation(FileLocation *location, QByteArray *data) : ReaderImplementation(location, data) {
 | 
					FFMpegReaderImplementation::FFMpegReaderImplementation(FileLocation *location, QByteArray *data, uint64 playId) : ReaderImplementation(location, data)
 | 
				
			||||||
 | 
					, _playId(playId) {
 | 
				
			||||||
	_frame = av_frame_alloc();
 | 
						_frame = av_frame_alloc();
 | 
				
			||||||
	av_init_packet(&_packetNull);
 | 
						av_init_packet(&_packetNull);
 | 
				
			||||||
	_packetNull.data = nullptr;
 | 
						_packetNull.data = nullptr;
 | 
				
			||||||
| 
						 | 
					@ -311,7 +312,6 @@ bool FFMpegReaderImplementation::start(Mode mode) {
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			soundData->length = (_fmtContext->streams[_audioStreamId]->duration * soundData->frequency * _fmtContext->streams[_audioStreamId]->time_base.num) / _fmtContext->streams[_audioStreamId]->time_base.den;
 | 
								soundData->length = (_fmtContext->streams[_audioStreamId]->duration * soundData->frequency * _fmtContext->streams[_audioStreamId]->time_base.num) / _fmtContext->streams[_audioStreamId]->time_base.den;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		_playId = rand_value<uint64>();
 | 
					 | 
				
			||||||
		audioPlayer()->playFromVideo(AudioMsgId(AudioMsgId::Type::Video), _playId, std_::move(soundData), 0);
 | 
							audioPlayer()->playFromVideo(AudioMsgId(AudioMsgId::Type::Video), _playId, std_::move(soundData), 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,7 @@ namespace internal {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FFMpegReaderImplementation : public ReaderImplementation {
 | 
					class FFMpegReaderImplementation : public ReaderImplementation {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	FFMpegReaderImplementation(FileLocation *location, QByteArray *data);
 | 
						FFMpegReaderImplementation(FileLocation *location, QByteArray *data, uint64 playId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool readFramesTill(int64 ms) override;
 | 
						bool readFramesTill(int64 ms) override;
 | 
				
			||||||
	uint64 framePresentationTime() const override;
 | 
						uint64 framePresentationTime() const override;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,8 @@ QPixmap _prepareFrame(const FrameRequest &request, const QImage &original, bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Reader::Reader(const FileLocation &location, const QByteArray &data, Callback &&callback, Mode mode)
 | 
					Reader::Reader(const FileLocation &location, const QByteArray &data, Callback &&callback, Mode mode)
 | 
				
			||||||
: _callback(std_::move(callback))
 | 
					: _callback(std_::move(callback))
 | 
				
			||||||
, _mode(mode) {
 | 
					, _mode(mode)
 | 
				
			||||||
 | 
					, _playId(rand_value<uint64>()) {
 | 
				
			||||||
	if (threads.size() < ClipThreadsCount) {
 | 
						if (threads.size() < ClipThreadsCount) {
 | 
				
			||||||
		_threadIndex = threads.size();
 | 
							_threadIndex = threads.size();
 | 
				
			||||||
		threads.push_back(new QThread());
 | 
							threads.push_back(new QThread());
 | 
				
			||||||
| 
						 | 
					@ -289,6 +290,7 @@ class ReaderPrivate {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	ReaderPrivate(Reader *reader, const FileLocation &location, const QByteArray &data) : _interface(reader)
 | 
						ReaderPrivate(Reader *reader, const FileLocation &location, const QByteArray &data) : _interface(reader)
 | 
				
			||||||
	, _mode(reader->mode())
 | 
						, _mode(reader->mode())
 | 
				
			||||||
 | 
						, _playId(reader->playId())
 | 
				
			||||||
	, _data(data)
 | 
						, _data(data)
 | 
				
			||||||
	, _location(_data.isEmpty() ? new FileLocation(location) : 0) {
 | 
						, _location(_data.isEmpty() ? new FileLocation(location) : 0) {
 | 
				
			||||||
		if (_data.isEmpty() && !_location->accessEnable()) {
 | 
							if (_data.isEmpty() && !_location->accessEnable()) {
 | 
				
			||||||
| 
						 | 
					@ -364,7 +366,7 @@ public:
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		_implementation = std_::make_unique<internal::FFMpegReaderImplementation>(_location, &_data);
 | 
							_implementation = std_::make_unique<internal::FFMpegReaderImplementation>(_location, &_data, _playId);
 | 
				
			||||||
//		_implementation = new QtGifReaderImplementation(_location, &_data);
 | 
					//		_implementation = new QtGifReaderImplementation(_location, &_data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto implementationMode = [this]() {
 | 
							auto implementationMode = [this]() {
 | 
				
			||||||
| 
						 | 
					@ -410,6 +412,7 @@ private:
 | 
				
			||||||
	Reader *_interface;
 | 
						Reader *_interface;
 | 
				
			||||||
	State _state = State::Reading;
 | 
						State _state = State::Reading;
 | 
				
			||||||
	Reader::Mode _mode;
 | 
						Reader::Mode _mode;
 | 
				
			||||||
 | 
						uint64 _playId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QByteArray _data;
 | 
						QByteArray _data;
 | 
				
			||||||
	FileLocation *_location;
 | 
						FileLocation *_location;
 | 
				
			||||||
| 
						 | 
					@ -687,7 +690,8 @@ MTPDocumentAttribute readAttributes(const QString &fname, const QByteArray &data
 | 
				
			||||||
	FileLocation localloc(StorageFilePartial, fname);
 | 
						FileLocation localloc(StorageFilePartial, fname);
 | 
				
			||||||
	QByteArray localdata(data);
 | 
						QByteArray localdata(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto reader = std_::make_unique<internal::FFMpegReaderImplementation>(&localloc, &localdata);
 | 
						auto playId = 0ULL;
 | 
				
			||||||
 | 
						auto reader = std_::make_unique<internal::FFMpegReaderImplementation>(&localloc, &localdata, playId);
 | 
				
			||||||
	if (reader->start(internal::ReaderImplementation::Mode::OnlyGifv)) {
 | 
						if (reader->start(internal::ReaderImplementation::Mode::OnlyGifv)) {
 | 
				
			||||||
		bool hasAlpha = false;
 | 
							bool hasAlpha = false;
 | 
				
			||||||
		if (reader->readFramesTill(-1) && reader->renderFrame(cover, hasAlpha, QSize())) {
 | 
							if (reader->readFramesTill(-1) && reader->renderFrame(cover, hasAlpha, QSize())) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,7 +51,6 @@ enum ReaderSteps {
 | 
				
			||||||
class ReaderPrivate;
 | 
					class ReaderPrivate;
 | 
				
			||||||
class Reader {
 | 
					class Reader {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					 | 
				
			||||||
	using Callback = Function<void, Notification>;
 | 
						using Callback = Function<void, Notification>;
 | 
				
			||||||
	enum class Mode {
 | 
						enum class Mode {
 | 
				
			||||||
		Gif,
 | 
							Gif,
 | 
				
			||||||
| 
						 | 
					@ -68,6 +67,10 @@ public:
 | 
				
			||||||
		return _autoplay;
 | 
							return _autoplay;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64 playId() const {
 | 
				
			||||||
 | 
							return _playId;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void start(int framew, int frameh, int outerw, int outerh, bool rounded);
 | 
						void start(int framew, int frameh, int outerw, int outerh, bool rounded);
 | 
				
			||||||
	QPixmap current(int framew, int frameh, int outerw, int outerh, uint64 ms);
 | 
						QPixmap current(int framew, int frameh, int outerw, int outerh, uint64 ms);
 | 
				
			||||||
	QPixmap frameOriginal() const {
 | 
						QPixmap frameOriginal() const {
 | 
				
			||||||
| 
						 | 
					@ -114,6 +117,8 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	State _state = State::Reading;
 | 
						State _state = State::Reading;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64 _playId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mutable int _width = 0;
 | 
						mutable int _width = 0;
 | 
				
			||||||
	mutable int _height = 0;
 | 
						mutable int _height = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,6 +41,8 @@ Controller::Controller(QWidget *parent) : TWidget(parent)
 | 
				
			||||||
, _toPlayLeft(this, st::mediaviewPlayProgressLabel)
 | 
					, _toPlayLeft(this, st::mediaviewPlayProgressLabel)
 | 
				
			||||||
, _fadeAnimation(std_::make_unique<Ui::FadeAnimation>(this)) {
 | 
					, _fadeAnimation(std_::make_unique<Ui::FadeAnimation>(this)) {
 | 
				
			||||||
	_fadeAnimation->show();
 | 
						_fadeAnimation->show();
 | 
				
			||||||
 | 
						_fadeAnimation->setFinishedCallback(func(this, &Controller::fadeFinished));
 | 
				
			||||||
 | 
						_fadeAnimation->setUpdatedCallback(func(this, &Controller::fadeUpdated));
 | 
				
			||||||
	connect(_playPauseResume, SIGNAL(clicked()), this, SIGNAL(playPressed()));
 | 
						connect(_playPauseResume, SIGNAL(clicked()), this, SIGNAL(playPressed()));
 | 
				
			||||||
	connect(_fullScreenToggle, SIGNAL(clicked()), this, SIGNAL(toFullScreenPressed()));
 | 
						connect(_fullScreenToggle, SIGNAL(clicked()), this, SIGNAL(toFullScreenPressed()));
 | 
				
			||||||
	connect(_playback, SIGNAL(seekProgress(int64)), this, SLOT(onSeekProgress(int64)));
 | 
						connect(_playback, SIGNAL(seekProgress(int64)), this, SLOT(onSeekProgress(int64)));
 | 
				
			||||||
| 
						 | 
					@ -59,14 +61,38 @@ void Controller::onSeekFinished(int64 position) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Controller::showAnimated() {
 | 
					void Controller::showAnimated() {
 | 
				
			||||||
	_fadeAnimation->fadeIn(st::mvShowDuration);
 | 
						startFading([this]() {
 | 
				
			||||||
 | 
							_fadeAnimation->fadeIn(st::mvShowDuration);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Controller::hideAnimated() {
 | 
					void Controller::hideAnimated() {
 | 
				
			||||||
	_fadeAnimation->fadeOut(st::mvHideDuration);
 | 
						startFading([this]() {
 | 
				
			||||||
 | 
							_fadeAnimation->fadeOut(st::mvShowDuration);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename Callback>
 | 
				
			||||||
 | 
					void Controller::startFading(Callback start) {
 | 
				
			||||||
 | 
						start();
 | 
				
			||||||
 | 
						_playback->show();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Controller::fadeFinished() {
 | 
				
			||||||
 | 
						fadeUpdated(1.);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Controller::fadeUpdated(float64 opacity) {
 | 
				
			||||||
 | 
						_playback->setFadeOpacity(opacity);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Controller::updatePlayback(const AudioPlaybackState &playbackState) {
 | 
					void Controller::updatePlayback(const AudioPlaybackState &playbackState) {
 | 
				
			||||||
 | 
						updatePlayPauseResumeState(playbackState);
 | 
				
			||||||
 | 
						_playback->updateState(playbackState);
 | 
				
			||||||
 | 
						updateTimeTexts(playbackState);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Controller::updatePlayPauseResumeState(const AudioPlaybackState &playbackState) {
 | 
				
			||||||
	bool showPause = (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming);
 | 
						bool showPause = (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming);
 | 
				
			||||||
	if (showPause != _showPause) {
 | 
						if (showPause != _showPause) {
 | 
				
			||||||
		disconnect(_playPauseResume, SIGNAL(clicked()), this, _showPause ? SIGNAL(pausePressed()) : SIGNAL(playPressed()));
 | 
							disconnect(_playPauseResume, SIGNAL(clicked()), this, _showPause ? SIGNAL(pausePressed()) : SIGNAL(playPressed()));
 | 
				
			||||||
| 
						 | 
					@ -75,8 +101,32 @@ void Controller::updatePlayback(const AudioPlaybackState &playbackState) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		_playPauseResume->setIcon(_showPause ? &st::mediaviewPauseIcon : nullptr);
 | 
							_playPauseResume->setIcon(_showPause ? &st::mediaviewPauseIcon : nullptr);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_playback->updateState(playbackState);
 | 
					void Controller::updateTimeTexts(const AudioPlaybackState &playbackState) {
 | 
				
			||||||
 | 
						qint64 position = 0, duration = playbackState.duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
 | 
				
			||||||
 | 
							position = playbackState.position;
 | 
				
			||||||
 | 
						} else if (playbackState.state == AudioPlayerStoppedAtEnd) {
 | 
				
			||||||
 | 
							position = playbackState.duration;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							position = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						auto playFrequency = (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency);
 | 
				
			||||||
 | 
						auto playAlready = position / playFrequency;
 | 
				
			||||||
 | 
						auto playLeft = (playbackState.duration / playFrequency) - playAlready;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto timeAlready = formatDurationText(playAlready);
 | 
				
			||||||
 | 
						auto minus = QChar(8722);
 | 
				
			||||||
 | 
						auto timeLeft = minus + formatDurationText(playLeft);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto alreadyChanged = false, leftChanged = false;
 | 
				
			||||||
 | 
						_playedAlready->setText(timeAlready, &alreadyChanged);
 | 
				
			||||||
 | 
						_toPlayLeft->setText(timeLeft, &leftChanged);
 | 
				
			||||||
 | 
						if (alreadyChanged || leftChanged) {
 | 
				
			||||||
 | 
							_fadeAnimation->refreshCache();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Controller::setInFullScreen(bool inFullScreen) {
 | 
					void Controller::setInFullScreen(bool inFullScreen) {
 | 
				
			||||||
| 
						 | 
					@ -88,18 +138,29 @@ void Controller::setInFullScreen(bool inFullScreen) {
 | 
				
			||||||
	connect(_fullScreenToggle, SIGNAL(clicked()), this, handler);
 | 
						connect(_fullScreenToggle, SIGNAL(clicked()), this, handler);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Controller::grabStart() {
 | 
				
			||||||
 | 
						showChildren();
 | 
				
			||||||
 | 
						_playback->hide();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Controller::grabFinish() {
 | 
				
			||||||
 | 
						hideChildren();
 | 
				
			||||||
 | 
						_playback->show();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Controller::resizeEvent(QResizeEvent *e) {
 | 
					void Controller::resizeEvent(QResizeEvent *e) {
 | 
				
			||||||
	int playTop = (height() - _playPauseResume->height()) / 2;
 | 
						int playTop = (height() - _playPauseResume->height()) / 2;
 | 
				
			||||||
	_playPauseResume->moveToLeft(playTop, playTop);
 | 
						_playPauseResume->moveToLeft(playTop, playTop);
 | 
				
			||||||
	_playedAlready->moveToLeft(playTop + _playPauseResume->width() + playTop, 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int fullScreenTop = (height() - _fullScreenToggle->height()) / 2;
 | 
						int fullScreenTop = (height() - _fullScreenToggle->height()) / 2;
 | 
				
			||||||
	_fullScreenToggle->moveToRight(fullScreenTop, fullScreenTop);
 | 
						_fullScreenToggle->moveToRight(fullScreenTop, fullScreenTop);
 | 
				
			||||||
	_toPlayLeft->moveToRight(fullScreenTop + _fullScreenToggle->width() + fullScreenTop, 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_volumeController->moveToRight(fullScreenTop + _fullScreenToggle->width() + fullScreenTop, (height() - _volumeController->height()) / 2);
 | 
						_volumeController->moveToRight(fullScreenTop + _fullScreenToggle->width() + fullScreenTop, (height() - _volumeController->height()) / 2);
 | 
				
			||||||
	_playback->resize(width() - playTop - _playPauseResume->width() - playTop - fullScreenTop - _volumeController->width() - fullScreenTop - _fullScreenToggle->width() - fullScreenTop, _volumeController->height());
 | 
						_playback->resize(width() - playTop - _playPauseResume->width() - playTop - fullScreenTop - _volumeController->width() - fullScreenTop - _fullScreenToggle->width() - fullScreenTop, _volumeController->height());
 | 
				
			||||||
	_playback->moveToLeft(playTop + _playPauseResume->width() + playTop, (height() - _playback->height()) / 2);
 | 
						_playback->moveToLeft(playTop + _playPauseResume->width() + playTop, st::mediaviewPlaybackTop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_playedAlready->moveToLeft(playTop + _playPauseResume->width() + playTop, st::mediaviewPlayProgressTop);
 | 
				
			||||||
 | 
						_toPlayLeft->moveToRight(width() - (playTop + _playPauseResume->width() + playTop) - _playback->width(), st::mediaviewPlayProgressTop);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Controller::paintEvent(QPaintEvent *e) {
 | 
					void Controller::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,6 +46,9 @@ public:
 | 
				
			||||||
	void updatePlayback(const AudioPlaybackState &playbackState);
 | 
						void updatePlayback(const AudioPlaybackState &playbackState);
 | 
				
			||||||
	void setInFullScreen(bool inFullScreen);
 | 
						void setInFullScreen(bool inFullScreen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void grabStart() override;
 | 
				
			||||||
 | 
						void grabFinish() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signals:
 | 
					signals:
 | 
				
			||||||
	void playPressed();
 | 
						void playPressed();
 | 
				
			||||||
	void pausePressed();
 | 
						void pausePressed();
 | 
				
			||||||
| 
						 | 
					@ -64,6 +67,14 @@ protected:
 | 
				
			||||||
	void paintEvent(QPaintEvent *e) override;
 | 
						void paintEvent(QPaintEvent *e) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
						template <typename Callback>
 | 
				
			||||||
 | 
						void startFading(Callback start);
 | 
				
			||||||
 | 
						void fadeFinished();
 | 
				
			||||||
 | 
						void fadeUpdated(float64 opacity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void updatePlayPauseResumeState(const AudioPlaybackState &playbackState);
 | 
				
			||||||
 | 
						void updateTimeTexts(const AudioPlaybackState &playbackState);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool _showPause = false;
 | 
						bool _showPause = false;
 | 
				
			||||||
	int64 _seekPosition = -1;
 | 
						int64 _seekPosition = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,6 +60,11 @@ void Playback::updateState(const AudioPlaybackState &playbackState) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Playback::setFadeOpacity(float64 opacity) {
 | 
				
			||||||
 | 
						_fadeOpacity = opacity;
 | 
				
			||||||
 | 
						update();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Playback::step_progress(float64 ms, bool timer) {
 | 
					void Playback::step_progress(float64 ms, bool timer) {
 | 
				
			||||||
	float64 dt = ms / (2 * AudioVoiceMsgUpdateView);
 | 
						float64 dt = ms / (2 * AudioVoiceMsgUpdateView);
 | 
				
			||||||
	if (_duration && dt >= 1) {
 | 
						if (_duration && dt >= 1) {
 | 
				
			||||||
| 
						 | 
					@ -75,6 +80,7 @@ void Playback::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
	Painter p(this);
 | 
						Painter p(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int radius = st::mediaviewPlaybackWidth / 2;
 | 
						int radius = st::mediaviewPlaybackWidth / 2;
 | 
				
			||||||
 | 
						p.setOpacity(_fadeOpacity);
 | 
				
			||||||
	p.setPen(Qt::NoPen);
 | 
						p.setPen(Qt::NoPen);
 | 
				
			||||||
	p.setRenderHint(QPainter::HighQualityAntialiasing);
 | 
						p.setRenderHint(QPainter::HighQualityAntialiasing);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,19 +91,19 @@ void Playback::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
	int32 from = skip, mid = qRound(from + prg * length), end = from + length;
 | 
						int32 from = skip, mid = qRound(from + prg * length), end = from + length;
 | 
				
			||||||
	if (mid > from) {
 | 
						if (mid > from) {
 | 
				
			||||||
		p.setClipRect(0, 0, mid, height());
 | 
							p.setClipRect(0, 0, mid, height());
 | 
				
			||||||
		p.setOpacity(over * st::mediaviewActiveOpacity + (1. - over) * st::mediaviewInactiveOpacity);
 | 
							p.setOpacity(_fadeOpacity * (over * st::mediaviewActiveOpacity + (1. - over) * st::mediaviewInactiveOpacity));
 | 
				
			||||||
		p.setBrush(st::mediaviewPlaybackActive);
 | 
							p.setBrush(st::mediaviewPlaybackActive);
 | 
				
			||||||
		p.drawRoundedRect(0, (height() - st::mediaviewPlaybackWidth) / 2, mid + radius, st::mediaviewPlaybackWidth, radius, radius);
 | 
							p.drawRoundedRect(0, (height() - st::mediaviewPlaybackWidth) / 2, mid + radius, st::mediaviewPlaybackWidth, radius, radius);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (end > mid) {
 | 
						if (end > mid) {
 | 
				
			||||||
		p.setClipRect(mid, 0, width() - mid, height());
 | 
							p.setClipRect(mid, 0, width() - mid, height());
 | 
				
			||||||
		p.setOpacity(1.);
 | 
							p.setOpacity(_fadeOpacity);
 | 
				
			||||||
		p.setBrush(st::mediaviewPlaybackInactive);
 | 
							p.setBrush(st::mediaviewPlaybackInactive);
 | 
				
			||||||
		p.drawRoundedRect(mid - radius, (height() - st::mediaviewPlaybackWidth) / 2, width() - (mid - radius), st::mediaviewPlaybackWidth, radius, radius);
 | 
							p.drawRoundedRect(mid - radius, (height() - st::mediaviewPlaybackWidth) / 2, width() - (mid - radius), st::mediaviewPlaybackWidth, radius, radius);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	int x = mid - skip;
 | 
						int x = mid - skip;
 | 
				
			||||||
	p.setClipRect(rect());
 | 
						p.setClipRect(rect());
 | 
				
			||||||
	p.setOpacity(over * st::mediaviewActiveOpacity + (1. - over) * st::mediaviewInactiveOpacity);
 | 
						p.setOpacity(_fadeOpacity * (over * st::mediaviewActiveOpacity + (1. - over) * st::mediaviewInactiveOpacity));
 | 
				
			||||||
	p.setBrush(st::mediaviewPlaybackActive);
 | 
						p.setBrush(st::mediaviewPlaybackActive);
 | 
				
			||||||
	p.drawRoundedRect(x, (height() - st::mediaviewSeekSize.height()) / 2, st::mediaviewSeekSize.width(), st::mediaviewSeekSize.height(), st::mediaviewSeekSize.width() / 2, st::mediaviewSeekSize.width() / 2);
 | 
						p.drawRoundedRect(x, (height() - st::mediaviewSeekSize.height()) / 2, st::mediaviewSeekSize.width(), st::mediaviewSeekSize.height(), st::mediaviewSeekSize.width() / 2, st::mediaviewSeekSize.width() / 2);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,7 @@ public:
 | 
				
			||||||
	Playback(QWidget *parent);
 | 
						Playback(QWidget *parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void updateState(const AudioPlaybackState &playbackState);
 | 
						void updateState(const AudioPlaybackState &playbackState);
 | 
				
			||||||
 | 
						void setFadeOpacity(float64 opacity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signals:
 | 
					signals:
 | 
				
			||||||
	void seekProgress(int64 position);
 | 
						void seekProgress(int64 position);
 | 
				
			||||||
| 
						 | 
					@ -63,6 +64,8 @@ private:
 | 
				
			||||||
	bool _mouseDown = false;
 | 
						bool _mouseDown = false;
 | 
				
			||||||
	float64 _downProgress = 0.;
 | 
						float64 _downProgress = 0.;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						float64 _fadeOpacity = 1.;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Clip
 | 
					} // namespace Clip
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,8 +28,10 @@ mediaviewOverDuration: 150;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mediaviewControllerSize: size(600px, 50px);
 | 
					mediaviewControllerSize: size(600px, 50px);
 | 
				
			||||||
mediaviewPlayProgressLabel: LabelSimple(defaultLabelSimple) {
 | 
					mediaviewPlayProgressLabel: LabelSimple(defaultLabelSimple) {
 | 
				
			||||||
 | 
						font: semiboldFont;
 | 
				
			||||||
	textFg: #ffffffc7;
 | 
						textFg: #ffffffc7;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					mediaviewPlayProgressTop: 8px;
 | 
				
			||||||
mediaviewPlayButton: IconButton {
 | 
					mediaviewPlayButton: IconButton {
 | 
				
			||||||
	width: 25px;
 | 
						width: 25px;
 | 
				
			||||||
	height: 24px;
 | 
						height: 24px;
 | 
				
			||||||
| 
						 | 
					@ -63,6 +65,7 @@ mediaviewFullScreenOutIcon: icon {
 | 
				
			||||||
mediaviewPlaybackActive: #ffffff;
 | 
					mediaviewPlaybackActive: #ffffff;
 | 
				
			||||||
mediaviewPlaybackInactive: #474747;
 | 
					mediaviewPlaybackInactive: #474747;
 | 
				
			||||||
mediaviewPlaybackWidth: 3px;
 | 
					mediaviewPlaybackWidth: 3px;
 | 
				
			||||||
 | 
					mediaviewPlaybackTop: 23px;
 | 
				
			||||||
mediaviewSeekSize: size(2px, 13px);
 | 
					mediaviewSeekSize: size(2px, 13px);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mediaviewVolumeSize: size(44px, 12px);
 | 
					mediaviewVolumeSize: size(44px, 12px);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 | 
				
			||||||
#include "media/media_clip_reader.h"
 | 
					#include "media/media_clip_reader.h"
 | 
				
			||||||
#include "media/view/media_clip_controller.h"
 | 
					#include "media/view/media_clip_controller.h"
 | 
				
			||||||
#include "styles/style_mediaview.h"
 | 
					#include "styles/style_mediaview.h"
 | 
				
			||||||
 | 
					#include "media/media_audio.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -233,6 +234,9 @@ void MediaView::stopGif() {
 | 
				
			||||||
	_gif = nullptr;
 | 
						_gif = nullptr;
 | 
				
			||||||
	_clipController.destroy();
 | 
						_clipController.destroy();
 | 
				
			||||||
	Sandbox::removeEventFilter(this);
 | 
						Sandbox::removeEventFilter(this);
 | 
				
			||||||
 | 
						if (audioPlayer()) {
 | 
				
			||||||
 | 
							disconnect(audioPlayer(), SIGNAL(updated(const AudioMsgId&)), this, SLOT(onVideoPlayProgress(const AudioMsgId&)));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MediaView::documentUpdated(DocumentData *doc) {
 | 
					void MediaView::documentUpdated(DocumentData *doc) {
 | 
				
			||||||
| 
						 | 
					@ -1247,6 +1251,10 @@ void MediaView::createClipController() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Sandbox::removeEventFilter(this);
 | 
						Sandbox::removeEventFilter(this);
 | 
				
			||||||
	Sandbox::installEventFilter(this);
 | 
						Sandbox::installEventFilter(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (audioPlayer()) {
 | 
				
			||||||
 | 
							connect(audioPlayer(), SIGNAL(updated(const AudioMsgId&)), this, SLOT(onVideoPlayProgress(const AudioMsgId&)));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MediaView::setClipControllerGeometry() {
 | 
					void MediaView::setClipControllerGeometry() {
 | 
				
			||||||
| 
						 | 
					@ -1289,6 +1297,19 @@ void MediaView::onVideoFromFullScreen() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MediaView::onVideoPlayProgress(const AudioMsgId &audioId) {
 | 
				
			||||||
 | 
						if (audioId.type() != AudioMsgId::Type::Video) {
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t_assert(_gif != nullptr);
 | 
				
			||||||
 | 
						t_assert(audioPlayer() != nullptr);
 | 
				
			||||||
 | 
						auto state = audioPlayer()->currentVideoState(_gif->playId());
 | 
				
			||||||
 | 
						if (state.frequency) {
 | 
				
			||||||
 | 
							_clipController->updatePlayback(state);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MediaView::paintEvent(QPaintEvent *e) {
 | 
					void MediaView::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
	QRect r(e->rect());
 | 
						QRect r(e->rect());
 | 
				
			||||||
	QRegion region(e->region());
 | 
						QRegion region(e->region());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,6 +122,7 @@ private slots:
 | 
				
			||||||
	void onVideoVolumeChanged(float64 volume);
 | 
						void onVideoVolumeChanged(float64 volume);
 | 
				
			||||||
	void onVideoToFullScreen();
 | 
						void onVideoToFullScreen();
 | 
				
			||||||
	void onVideoFromFullScreen();
 | 
						void onVideoFromFullScreen();
 | 
				
			||||||
 | 
						void onVideoPlayProgress(const AudioMsgId &audioId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void displayPhoto(PhotoData *photo, HistoryItem *item);
 | 
						void displayPhoto(PhotoData *photo, HistoryItem *item);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,20 +29,26 @@ FadeAnimation::FadeAnimation(TWidget *widget) : _widget(widget) {
 | 
				
			||||||
bool FadeAnimation::paint(Painter &p) {
 | 
					bool FadeAnimation::paint(Painter &p) {
 | 
				
			||||||
	if (_cache.isNull()) return false;
 | 
						if (_cache.isNull()) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool animating = _animation.animating(getms());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	p.setOpacity(_animation.current(_visible ? 1. : 0.));
 | 
						p.setOpacity(_animation.current(_visible ? 1. : 0.));
 | 
				
			||||||
	p.drawPixmap(0, 0, _cache);
 | 
						p.drawPixmap(0, 0, _cache);
 | 
				
			||||||
	if (!animating) {
 | 
					 | 
				
			||||||
		stopAnimation();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FadeAnimation::refreshCache() {
 | 
				
			||||||
 | 
						if (!_cache.isNull()) {
 | 
				
			||||||
 | 
							_cache = QPixmap();
 | 
				
			||||||
 | 
							_cache = myGrab(_widget);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FadeAnimation::setFinishedCallback(FinishedCallback &&callback) {
 | 
					void FadeAnimation::setFinishedCallback(FinishedCallback &&callback) {
 | 
				
			||||||
	_finishedCallback = std_::move(callback);
 | 
						_finishedCallback = std_::move(callback);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void FadeAnimation::setUpdatedCallback(UpdatedCallback &&callback) {
 | 
				
			||||||
 | 
						_updatedCallback = std_::move(callback);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FadeAnimation::show() {
 | 
					void FadeAnimation::show() {
 | 
				
			||||||
	_visible = true;
 | 
						_visible = true;
 | 
				
			||||||
	stopAnimation();
 | 
						stopAnimation();
 | 
				
			||||||
| 
						 | 
					@ -93,7 +99,12 @@ void FadeAnimation::startAnimation(int duration) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FadeAnimation::updateCallback() {
 | 
					void FadeAnimation::updateCallback() {
 | 
				
			||||||
	_widget->update();
 | 
						if (_animation.animating(getms())) {
 | 
				
			||||||
 | 
							_widget->update();
 | 
				
			||||||
 | 
							_updatedCallback.call(_animation.current());
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							stopAnimation();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Ui
 | 
					} // namespace Ui
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,10 +29,14 @@ public:
 | 
				
			||||||
	FadeAnimation(TWidget *widget);
 | 
						FadeAnimation(TWidget *widget);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool paint(Painter &p);
 | 
						bool paint(Painter &p);
 | 
				
			||||||
 | 
						void refreshCache();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	using FinishedCallback = Function<void>;
 | 
						using FinishedCallback = Function<void>;
 | 
				
			||||||
	void setFinishedCallback(FinishedCallback &&callback);
 | 
						void setFinishedCallback(FinishedCallback &&callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						using UpdatedCallback = Function<void, float64>;
 | 
				
			||||||
 | 
						void setUpdatedCallback(UpdatedCallback &&callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void show();
 | 
						void show();
 | 
				
			||||||
	void hide();
 | 
						void hide();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,6 +55,7 @@ private:
 | 
				
			||||||
	bool _visible = false;
 | 
						bool _visible = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FinishedCallback _finishedCallback;
 | 
						FinishedCallback _finishedCallback;
 | 
				
			||||||
 | 
						UpdatedCallback _updatedCallback;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,17 +28,29 @@ LabelSimple::LabelSimple(QWidget *parent, const style::LabelSimple &st, const QS
 | 
				
			||||||
	setText(value);
 | 
						setText(value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LabelSimple::setText(const QString &value) {
 | 
					void LabelSimple::setText(const QString &value, bool *outTextChanged) {
 | 
				
			||||||
 | 
						if (_fullText == value) {
 | 
				
			||||||
 | 
							if (outTextChanged) *outTextChanged = false;
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_fullText = value;
 | 
						_fullText = value;
 | 
				
			||||||
	_fullTextWidth = _st.font->width(_fullText);
 | 
						_fullTextWidth = _st.font->width(_fullText);
 | 
				
			||||||
	if (!_st.maxWidth || _fullTextWidth <= _st.maxWidth) {
 | 
						if (!_st.maxWidth || _fullTextWidth <= _st.maxWidth) {
 | 
				
			||||||
		_text = _fullText;
 | 
							_text = _fullText;
 | 
				
			||||||
		_textWidth = _fullTextWidth;
 | 
							_textWidth = _fullTextWidth;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		_text = _st.font->elided(_fullText, _st.maxWidth);
 | 
							auto newText = _st.font->elided(_fullText, _st.maxWidth);
 | 
				
			||||||
 | 
							if (newText == _text) {
 | 
				
			||||||
 | 
								if (outTextChanged) *outTextChanged = false;
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							_text = newText;
 | 
				
			||||||
		_textWidth = _st.font->width(_text);
 | 
							_textWidth = _st.font->width(_text);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	resize(_textWidth, _st.font->height);
 | 
						resize(_textWidth, _st.font->height);
 | 
				
			||||||
 | 
						update();
 | 
				
			||||||
 | 
						if (outTextChanged) *outTextChanged = true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LabelSimple::paintEvent(QPaintEvent *e) {
 | 
					void LabelSimple::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,7 +29,7 @@ public:
 | 
				
			||||||
	LabelSimple(QWidget *parent, const style::LabelSimple &st = st::defaultLabelSimple, const QString &value = QString());
 | 
						LabelSimple(QWidget *parent, const style::LabelSimple &st = st::defaultLabelSimple, const QString &value = QString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// This method also resizes the label.
 | 
						// This method also resizes the label.
 | 
				
			||||||
	void setText(const QString &newText);
 | 
						void setText(const QString &newText, bool *outTextChanged = nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
	void paintEvent(QPaintEvent *e) override;
 | 
						void paintEvent(QPaintEvent *e) override;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue