void ServiceMessagePainter::paint(Painter &p, const HistoryService *message, const PaintContext &context, int height) {
	int left = 0, width = 0;
	message->countPositionAndSize(left, width);
	if (width < 1) return;

	uint64 fullAnimMs = App::main() ? App::main()->animActiveTimeStart(message) : 0;
	if (fullAnimMs > 0 && fullAnimMs <= context.ms) {
		int animms = context.ms - fullAnimMs;
		if (animms > st::activeFadeInDuration + st::activeFadeOutDuration) {
			App::main()->stopAnimActive();
		} else {
			int skiph = st::msgServiceMargin.top() - st::msgServiceMargin.bottom();

			textstyleSet(&st::inTextStyle);
			float64 dt = (animms > st::activeFadeInDuration) ? (1 - (animms - st::activeFadeInDuration) / float64(st::activeFadeOutDuration)) : (animms / float64(st::activeFadeInDuration));
			float64 o = p.opacity();
			p.setOpacity(o * dt);
			p.fillRect(0, skiph, message->history()->width, message->height() - skiph, textstyleCurrent()->selectOverlay->b);
			p.setOpacity(o);
		}
	}

	textstyleSet(&st::serviceTextStyle);

	if (auto media = message->getMedia()) {
		height -= st::msgServiceMargin.top() + media->height();
		int32 left = st::msgServiceMargin.left() + (width - media->maxWidth()) / 2, top = st::msgServiceMargin.top() + height + st::msgServiceMargin.top();
		p.translate(left, top);
		media->draw(p, context.clip.translated(-left, -top), message->toMediaSelection(context.selection), context.ms);
		p.translate(-left, -top);
	}

	QRect trect(QRect(left, st::msgServiceMargin.top(), width, height).marginsAdded(-st::msgServicePadding));

	paintBubble(p, left, width, message->_text, trect);

	if (width > message->maxWidth()) {
		left += (width - message->maxWidth()) / 2;
		width = message->maxWidth();
	}

	p.setBrush(Qt::NoBrush);
	p.setPen(st::msgServiceColor);
	p.setFont(st::msgServiceFont);
	message->_text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignCenter, 0, -1, context.selection, false);

	textstyleRestore();
}
Exemple #2
0
ConvertToSupergroupBox::ConvertToSupergroupBox(ChatData *chat) : AbstractBox(st::boxWideWidth)
    , _chat(chat)
    , _text(100)
    , _note(100)
    , _convert(this, lang(lng_profile_convert_confirm), st::defaultBoxButton)
    , _cancel(this, lang(lng_cancel), st::cancelBoxButton) {
    QStringList text;
    text.push_back(lang(lng_profile_convert_feature1));
    text.push_back(lang(lng_profile_convert_feature2));
    text.push_back(lang(lng_profile_convert_feature3));
    text.push_back(lang(lng_profile_convert_feature4));

    textstyleSet(&st::boxTextStyle);
    _text.setText(st::boxTextFont, text.join('\n'), _confirmBoxTextOptions);
    _note.setText(st::boxTextFont, lng_profile_convert_warning(lt_bold_start, textcmdStartSemibold(), lt_bold_end, textcmdStopSemibold()), _confirmBoxTextOptions);
    _textWidth = st::boxWideWidth - st::boxPadding.left() - st::boxButtonPadding.right();
    _textHeight = _text.countHeight(_textWidth);
    setMaxHeight(st::boxTitleHeight + _textHeight + st::boxPadding.bottom() + _note.countHeight(_textWidth) + st::boxButtonPadding.top() + _convert.height() + st::boxButtonPadding.bottom());
    textstyleRestore();

    connect(&_convert, SIGNAL(clicked()), this, SLOT(onConvert()));
    connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));

    prepare();
}
Exemple #3
0
UsernameBox::UsernameBox() : AbstractBox(st::boxWidth),
_save(this, lang(lng_settings_save), st::defaultBoxButton),
_cancel(this, lang(lng_cancel), st::cancelBoxButton),
_username(this, st::defaultInputField, qsl("@username"), App::self()->username, false),
_link(this, QString(), st::defaultBoxLinkButton),
_saveRequestId(0), _checkRequestId(0),
_about(st::boxWidth - st::usernamePadding.left()) {
	setBlueTitle(true);

	_goodText = App::self()->username.isEmpty() ? QString() : lang(lng_username_available);

	textstyleSet(&st::usernameTextStyle);
	_about.setRichText(st::boxTextFont, lang(lng_username_about));
	resizeMaxHeight(st::boxWidth, st::boxTitleHeight + st::usernamePadding.top() + _username.height() + st::usernameSkip + _about.countHeight(st::boxWidth - st::usernamePadding.left()) + 3 * st::usernameTextStyle.lineHeight + st::usernamePadding.bottom() + st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom());
	textstyleRestore();

	connect(&_save, SIGNAL(clicked()), this, SLOT(onSave()));
	connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
	connect(&_username, SIGNAL(changed()), this, SLOT(onChanged()));
	connect(&_username, SIGNAL(submitted(bool)), this, SLOT(onSave()));

	connect(&_link, SIGNAL(clicked()), this, SLOT(onLinkClick()));

	_checkTimer.setSingleShot(true);
	connect(&_checkTimer, SIGNAL(timeout()), this, SLOT(onCheck()));

	prepare();
}
Exemple #4
0
Text::StateResult FlatLabel::getTextState(const QPoint &m) const {
	Text::StateRequestElided request;
	request.align = _st.align;
	if (_selectable) {
		request.flags |= Text::StateRequest::Flag::LookupSymbol;
	}
	int textWidth = width() - _st.margin.left() - _st.margin.right();

	textstyleSet(&_tst);
	Text::StateResult state;
	bool heightExceeded = _st.maxHeight && (_st.maxHeight < _fullTextHeight || textWidth < _text.maxWidth());
	bool renderElided = _breakEverywhere || heightExceeded;
	if (renderElided) {
		auto lineHeight = qMax(_tst.lineHeight, _st.font->height);
		auto lines = _st.maxHeight ? qMax(_st.maxHeight / lineHeight, 1) : ((height() / lineHeight) + 2);
		request.lines = lines;
		if (_breakEverywhere) {
			request.flags |= Text::StateRequest::Flag::BreakEverywhere;
		}
		state = _text.getStateElided(m.x() - _st.margin.left(), m.y() - _st.margin.top(), textWidth, request);
	} else {
		state = _text.getState(m.x() - _st.margin.left(), m.y() - _st.margin.top(), textWidth, request);
	}
	textstyleRestore();

	return state;
}
PasscodeBox::PasscodeBox(const QByteArray &newSalt, const QByteArray &curSalt, bool hasRecovery, const QString &hint, bool turningOff) : AbstractBox(st::boxWidth)
, _replacedBy(0)
, _turningOff(turningOff)
, _cloudPwd(true)
, _setRequest(0)
, _newSalt(newSalt)
, _curSalt(curSalt)
, _hasRecovery(hasRecovery)
, _skipEmailWarning(false)
, _aboutHeight(0)
, _about(st::boxWidth - st::boxPadding.left() * 1.5)
, _saveButton(this, lang(_turningOff ? lng_passcode_remove_button : lng_settings_save), st::defaultBoxButton)
, _cancelButton(this, lang(lng_cancel), st::cancelBoxButton)
, _oldPasscode(this, st::defaultInputField, lang(lng_cloud_password_enter_old))
, _newPasscode(this, st::defaultInputField, lang(curSalt.isEmpty() ? lng_cloud_password_enter_first : lng_cloud_password_enter_new))
, _reenterPasscode(this, st::defaultInputField, lang(lng_cloud_password_confirm_new))
, _passwordHint(this, st::defaultInputField, lang(curSalt.isEmpty() ? lng_cloud_password_hint : lng_cloud_password_change_hint))
, _recoverEmail(this, st::defaultInputField, lang(lng_cloud_password_email))
, _recover(this, lang(lng_signin_recover)) {
	textstyleSet(&st::usernameTextStyle);
	if (!hint.isEmpty()) _hintText.setText(st::normalFont, lng_signin_hint(lt_password_hint, hint));
	textstyleRestore();
	init();
	prepare();
}
void PasscodeBox::paintEvent(QPaintEvent *e) {
	Painter p(this);
	if (paint(p)) return;

	paintTitle(p, _boxTitle);

	textstyleSet(&st::usernameTextStyle);

	int32 w = st::boxWidth - st::boxPadding.left() * 1.5;
	int32 abouty = (_passwordHint.isHidden() ? (_reenterPasscode.isHidden() ? (_oldPasscode.y() + (_hasRecovery && !_hintText.isEmpty() ? st::passcodeSkip : 0)) : _reenterPasscode.y()) + st::passcodeSkip : _passwordHint.y() + st::contactSkip) + _oldPasscode.height();
	p.setPen(st::black);
	_about.drawLeft(p, st::boxPadding.left(), abouty, w, width());

	if (!_hintText.isEmpty() && _oldError.isEmpty()) {
		p.setPen(st::black->p);
		_hintText.drawLeftElided(p, st::boxPadding.left(), _oldPasscode.y() + _oldPasscode.height() + ((st::passcodeSkip - st::normalFont->height) / 2), w, width(), 1, style::al_topleft);
	}

	if (!_oldError.isEmpty()) {
		p.setPen(st::setErrColor->p);
		p.drawText(QRect(st::boxPadding.left(), _oldPasscode.y() + _oldPasscode.height(), w, st::passcodeSkip), _oldError, style::al_left);
	}

	if (!_newError.isEmpty()) {
		p.setPen(st::setErrColor->p);
		p.drawText(QRect(st::boxPadding.left(), _reenterPasscode.y() + _reenterPasscode.height(), w, st::passcodeSkip), _newError, style::al_left);
	}

	if (!_emailError.isEmpty()) {
		p.setPen(st::setErrColor->p);
		p.drawText(QRect(st::boxPadding.left(), _recoverEmail.y() + _recoverEmail.height(), w, st::passcodeSkip), _emailError, style::al_left);
	}

	textstyleRestore();
}
Exemple #7
0
void FlatLabel::setRichText(const QString &text) {
	textstyleSet(&_tst);
	_text.setRichText(_st.font, text, _labelOptions);
	refreshSize();
	textstyleRestore();
	setMouseTracking(_selectable || _text.hasLinks());
}
Exemple #8
0
void FlatLabel::setMarkedText(const TextWithEntities &textWithEntities) {
	textstyleSet(&_tst);
	_text.setMarkedText(_st.font, textWithEntities, _labelMarkedOptions);
	refreshSize();
	textstyleRestore();
	setMouseTracking(_selectable || _text.hasLinks());
}
Exemple #9
0
int FlatLabel::resizeGetHeight(int newWidth) {
	_allowedWidth = newWidth;
	textstyleSet(&_tst);
	int textWidth = countTextWidth();
	int textHeight = countTextHeight(textWidth);
	textstyleRestore();
	return _st.margin.top() + textHeight + _st.margin.bottom();
}
Exemple #10
0
void ConfirmBox::updateHover() {
    QPoint m(mapFromGlobal(_lastMousePos));

    textstyleSet(&st::boxTextStyle);
    auto state = _text.getStateLeft(m.x() - st::boxPadding.left(), m.y() - st::boxPadding.top(), _textWidth, width());
    textstyleRestore();

    ClickHandler::setActive(state.link, this);
}
Exemple #11
0
void ConfirmBox::onTextUpdated() {
    textstyleSet(&st::boxTextStyle);
    _textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right();
    _textHeight = qMin(_text.countHeight(_textWidth), 16 * int(st::boxTextStyle.lineHeight));
    setMaxHeight(st::boxPadding.top() + _textHeight + st::boxPadding.bottom() + st::boxButtonPadding.top() + _confirm.height() + st::boxButtonPadding.bottom());
    textstyleRestore();

    setMouseTracking(_text.hasLinks());
}
Exemple #12
0
void ConfirmBox::paintEvent(QPaintEvent *e) {
    QPainter p(this);
    if (paint(p)) return;

    // draw box title / text
    p.setPen(st::black->p);
    textstyleSet(&st::boxTextStyle);
    _text.drawLeftElided(p, st::boxPadding.left(), st::boxPadding.top(), _textWidth, width(), 16, style::al_left);
    textstyleRestore();
}
Exemple #13
0
void Widget::paintEvent(QPaintEvent *e) {
    Painter p(this);

    p.setOpacity(_shownLevel);
    App::roundRect(p, rect(), st::toastBg);

    p.setPen(st::toastFg);
    textstyleSet(&st::defaultTextStyle);
    _text.drawElided(p, st::toastPadding.left(), st::toastPadding.top(), width() - st::toastPadding.left() - st::toastPadding.right());
    textstyleRestore();
}
Exemple #14
0
void ConvertToSupergroupBox::paintEvent(QPaintEvent *e) {
    Painter p(this);
    if (paint(p)) return;

    paintTitle(p, lang(lng_profile_convert_title));

    // draw box title / text
    p.setPen(st::black);
    textstyleSet(&st::boxTextStyle);
    _text.drawLeft(p, st::boxPadding.left(), st::boxTitleHeight, _textWidth, width());
    _note.drawLeft(p, st::boxPadding.left(), st::boxTitleHeight + _textHeight + st::boxPadding.bottom(), _textWidth, width());
    textstyleRestore();
}
void ConfirmBox::updateHover() {
	QPoint m(mapFromGlobal(_lastMousePos));
	bool wasMy = (_myLink == textlnkOver());
	textstyleSet(&st::boxTextStyle);
	_myLink = _text.linkLeft(m.x() - st::boxPadding.left(), m.y() - st::boxPadding.top(), _textWidth, width(), (_text.maxWidth() < width()) ? style::al_center : style::al_left);
	textstyleRestore();
	if (_myLink != textlnkOver()) {
		if (wasMy || _myLink || rect().contains(m)) {
			textlnkOver(_myLink);
		}
		setCursor(_myLink ? style::cur_pointer : style::cur_default);
		update();
	}
}
Exemple #16
0
void UsernameBox::resizeEvent(QResizeEvent *e) {
	_username.resize(width() - st::usernamePadding.left() - st::usernamePadding.right(), _username.height());
	_username.moveToLeft(st::usernamePadding.left(), st::boxTitleHeight + st::usernamePadding.top());

	textstyleSet(&st::usernameTextStyle);
	int32 availw = st::boxWidth - st::usernamePadding.left(), h = _about.countHeight(availw);
	textstyleRestore();
	int32 linky = _username.y() + _username.height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2);
	_link.moveToLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2));

	_save.moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save.height());
	_cancel.moveToRight(st::boxButtonPadding.right() + _save.width() + st::boxButtonPadding.left(), _save.y());

	AbstractBox::resizeEvent(e);
}
Exemple #17
0
void FlatLabel::paintEvent(QPaintEvent *e) {
	Painter p(this);
	p.setOpacity(_opacity);
	p.setPen(_st.textFg);
	textstyleSet(&_tst);
	int textWidth = width() - _st.margin.left() - _st.margin.right();
	auto selection = _selection.empty() ? (_contextMenu ? _savedSelection : _selection) : _selection;
	bool heightExceeded = _st.maxHeight && (_st.maxHeight < _fullTextHeight || textWidth < _text.maxWidth());
	bool renderElided = _breakEverywhere || heightExceeded;
	if (renderElided) {
		auto lineHeight = qMax(_tst.lineHeight, _st.font->height);
		auto lines = _st.maxHeight ? qMax(_st.maxHeight / lineHeight, 1) : ((height() / lineHeight) + 2);
		_text.drawElided(p, _st.margin.left(), _st.margin.top(), textWidth, lines, _st.align, e->rect().y(), e->rect().bottom(), 0, _breakEverywhere, selection);
	} else {
		_text.draw(p, _st.margin.left(), _st.margin.top(), textWidth, _st.align, e->rect().y(), e->rect().bottom(), selection);
	}
	textstyleRestore();
}
void ConfirmBox::init(const QString &text) {
	_text.setText(st::boxTextFont, text, _informative ? _confirmBoxTextOptions : _textPlainOptions);

	textstyleSet(&st::boxTextStyle);
	_textWidth = st::boxWidth - st::boxPadding.left() - st::boxButtonPadding.right();
	_textHeight = qMin(_text.countHeight(_textWidth), 16 * int(st::boxTextStyle.lineHeight));
	setMaxHeight(st::boxPadding.top() + _textHeight + st::boxPadding.bottom() + st::boxButtonPadding.top() + _confirm.height() + st::boxButtonPadding.bottom());
	textstyleRestore();

	connect(&_confirm, SIGNAL(clicked()), this, SIGNAL(confirmed()));
	connect(&_cancel, SIGNAL(clicked()), this, SLOT(onCancel()));
	if (_informative) {
		_cancel.hide();
		connect(this, SIGNAL(confirmed()), this, SLOT(onCancel()));
	}
	setMouseTracking(_text.hasLinks());

	prepare();
}
Exemple #19
0
void PasscodeBox::init() {
	setBlueTitle(true);

	textstyleSet(&st::usernameTextStyle);
	_about.setRichText(st::normalFont, lang(_cloudPwd ? lng_cloud_password_about : lng_passcode_about));
	_aboutHeight = _about.countHeight(st::boxWidth - st::boxPadding.left() * 1.5);
	textstyleRestore();
	if (_turningOff) {
		_oldPasscode.show();
		_boxTitle = lang(_cloudPwd ? lng_cloud_password_remove : lng_passcode_remove);
		setMaxHeight(st::boxTitleHeight + st::passcodePadding.top() + _oldPasscode.height() + st::passcodeSkip + ((_hasRecovery && !_hintText.isEmpty()) ? st::passcodeSkip : 0) + _aboutHeight + st::passcodePadding.bottom() + st::boxButtonPadding.top() + _saveButton.height() + st::boxButtonPadding.bottom());
	} else {
		bool has = _cloudPwd ? (!_curSalt.isEmpty()) : cHasPasscode();
		if (has) {
			_oldPasscode.show();
			_boxTitle = lang(_cloudPwd ? lng_cloud_password_change : lng_passcode_change);
			setMaxHeight(st::boxTitleHeight + st::passcodePadding.top() + _oldPasscode.height() + st::passcodeSkip + ((_hasRecovery && !_hintText.isEmpty()) ? st::passcodeSkip : 0) + _newPasscode.height() + st::contactSkip + _reenterPasscode.height() + st::passcodeSkip + (_cloudPwd ? _passwordHint.height() + st::contactSkip : 0) + _aboutHeight + st::passcodePadding.bottom() + st::boxButtonPadding.top() + _saveButton.height() + st::boxButtonPadding.bottom());
		} else {
			_oldPasscode.hide();
			_boxTitle = lang(_cloudPwd ? lng_cloud_password_create : lng_passcode_create);
			setMaxHeight(st::boxTitleHeight + st::passcodePadding.top() + _newPasscode.height() + st::contactSkip + _reenterPasscode.height() + st::passcodeSkip + (_cloudPwd ? _passwordHint.height() + st::contactSkip : 0) + _aboutHeight + (_cloudPwd ? st::contactSkip + _recoverEmail.height() + st::passcodeSkip : st::passcodePadding.bottom()) + st::boxButtonPadding.top() + _saveButton.height() + st::boxButtonPadding.bottom());
		}
	}

	connect(&_saveButton, SIGNAL(clicked()), this, SLOT(onSave()));
	connect(&_cancelButton, SIGNAL(clicked()), this, SLOT(onClose()));

	connect(&_oldPasscode, SIGNAL(changed()), this, SLOT(onOldChanged()));
	connect(&_newPasscode, SIGNAL(changed()), this, SLOT(onNewChanged()));
	connect(&_reenterPasscode, SIGNAL(changed()), this, SLOT(onNewChanged()));
	connect(&_passwordHint, SIGNAL(changed()), this, SLOT(onNewChanged()));
	connect(&_recoverEmail, SIGNAL(changed()), this, SLOT(onEmailChanged()));

	connect(&_oldPasscode, SIGNAL(submitted(bool)), this, SLOT(onSubmit()));
	connect(&_newPasscode, SIGNAL(submitted(bool)), this, SLOT(onSubmit()));
	connect(&_reenterPasscode, SIGNAL(submitted(bool)), this, SLOT(onSubmit()));
	connect(&_passwordHint, SIGNAL(submitted(bool)), this, SLOT(onSubmit()));
	connect(&_recoverEmail, SIGNAL(submitted(bool)), this, SLOT(onSubmit()));

	connect(&_recover, SIGNAL(clicked()), this, SLOT(onRecoverByEmail()));
}
Exemple #20
0
void UsernameBox::paintEvent(QPaintEvent *e) {
	Painter p(this);
	if (paint(p)) return;

	paintTitle(p, lang(lng_username_title));

	if (!_copiedTextLink.isEmpty()) {
		p.setPen(st::usernameDefaultFg);
		p.setFont(st::boxTextFont);
		p.drawTextLeft(st::usernamePadding.left(), _username.y() + _username.height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), _copiedTextLink);
	} else if (!_errorText.isEmpty()) {
		p.setPen(st::setErrColor);
		p.setFont(st::boxTextFont);
		p.drawTextLeft(st::usernamePadding.left(), _username.y() + _username.height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), _errorText);
	} else if (!_goodText.isEmpty()) {
		p.setPen(st::setGoodColor);
		p.setFont(st::boxTextFont);
		p.drawTextLeft(st::usernamePadding.left(), _username.y() + _username.height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), _goodText);
	} else {
		p.setPen(st::usernameDefaultFg);
		p.setFont(st::boxTextFont);
		p.drawTextLeft(st::usernamePadding.left(), _username.y() + _username.height() + ((st::usernameSkip - st::boxTextFont->height) / 2), width(), lang(lng_username_choose));
	}
	p.setPen(st::black);
	textstyleSet(&st::usernameTextStyle);
	int32 availw = st::boxWidth - st::usernamePadding.left(), h = _about.countHeight(availw);
	_about.drawLeft(p, st::usernamePadding.left(), _username.y() + _username.height() + st::usernameSkip, availw, width());
	textstyleRestore();

	int32 linky = _username.y() + _username.height() + st::usernameSkip + h + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2);
	if (_link.isHidden()) {
		p.drawTextLeft(st::usernamePadding.left(), linky, width(), lang(lng_username_link_willbe));
		p.setPen(st::usernameDefaultFg);
		p.drawTextLeft(st::usernamePadding.left(), linky + st::usernameTextStyle.lineHeight + ((st::usernameTextStyle.lineHeight - st::boxTextFont->height) / 2), width(), qsl("https://telegram.me/username"));
	} else {
		p.drawTextLeft(st::usernamePadding.left(), linky, width(), lang(lng_username_link));
	}
}
void PlayerWidget::paintEvent(QPaintEvent *e) {
	Painter p(this);

	QRect r(e->rect()), checkr(myrtlrect(r));
	p.fillRect(r, st::playerBg->b);

	if (!_playbackRect.contains(checkr)) {
		if (_fullAvailable && checkr.intersects(_prevRect)) {
			if (_prevAvailable) {
				float64 o = _stateHovers[OverPrev];
				p.setOpacity(o * 1. + (1. - o) * st::playerInactiveOpacity);
			} else {
				p.setOpacity(st::playerUnavailableOpacity);
			}
			p.drawSpriteCenterLeft(_prevRect, width(), st::playerPrev);
		}
		if (checkr.intersects(_playRect)) {
			float64 o = _stateHovers[OverPlay];
			p.setOpacity(o * 1. + (1. - o) * st::playerInactiveOpacity);
			p.drawSpriteCenterLeft(_playRect, width(), (_showPause || _down == OverPlayback) ? st::playerPause : st::playerPlay);
		}
		if (_fullAvailable && checkr.intersects(_nextRect)) {
			if (_nextAvailable) {
				float64 o = _stateHovers[OverNext];
				p.setOpacity(o * 1. + (1. - o) * st::playerInactiveOpacity);
			} else {
				p.setOpacity(st::playerUnavailableOpacity);
			}
			p.drawSpriteCenterLeft(_nextRect, width(), st::playerNext);
		}
		if (checkr.intersects(_closeRect)) {
			float64 o = _stateHovers[OverClose];
			p.setOpacity(o * 1. + (1. - o) * st::playerInactiveOpacity);
			p.drawSpriteCenterLeft(_closeRect, width(), st::playerClose);
		}
		if (checkr.intersects(_volumeRect)) {
			float64 o = _stateHovers[OverVolume];
			p.setOpacity(o * 1. + (1. - o) * st::playerInactiveOpacity);
			int32 top = _volumeRect.y() + (_volumeRect.height() - st::playerVolume.pxHeight()) / 2;
			int32 left = _volumeRect.x() + (_volumeRect.width() - st::playerVolume.pxWidth()) / 2;
			int32 mid = left + qRound(st::playerVolume.pxWidth() * cSongVolume());
			int32 right = left + st::playerVolume.pxWidth();
			if (rtl()) {
				left = width() - left;
				mid = width() - mid;
				right = width() - right;
				if (mid < left) {
					p.drawPixmap(QRect(mid, top, left - mid, st::playerVolume.pxHeight()), App::sprite(), QRect(st::playerVolume.x() + (mid - right) * cIntRetinaFactor(), st::playerVolume.y(), (left - mid) * cIntRetinaFactor(), st::playerVolume.pxHeight() * cIntRetinaFactor()));
				}
				if (right < mid) {
					p.setOpacity(st::playerUnavailableOpacity);
					p.drawPixmap(QRect(right, top, mid - right, st::playerVolume.pxHeight()), App::sprite(), QRect(st::playerVolume.x(), st::playerVolume.y(), (mid - right) * cIntRetinaFactor(), st::playerVolume.pxHeight() * cIntRetinaFactor()));
				}
			} else {
				if (mid > left) {
					p.drawPixmap(QRect(left, top, mid - left, st::playerVolume.pxHeight()), App::sprite(), QRect(st::playerVolume.x(), st::playerVolume.y(), (mid - left) * cIntRetinaFactor(), st::playerVolume.pxHeight() * cIntRetinaFactor()));
				}
				if (right > mid) {
					p.setOpacity(st::playerUnavailableOpacity);
					p.drawPixmap(QRect(mid, top, right - mid, st::playerVolume.pxHeight()), App::sprite(), QRect(st::playerVolume.x() + (mid - left) * cIntRetinaFactor(), st::playerVolume.y(), (right - mid) * cIntRetinaFactor(), st::playerVolume.pxHeight() * cIntRetinaFactor()));
				}
			}
		}
		if (_fullAvailable && checkr.intersects(_fullRect)) {
			float64 o = _stateHovers[OverFull];
			p.setOpacity(o * 1. + (1. - o) * st::playerInactiveOpacity);
			p.drawSpriteCenterLeft(_fullRect, width(), st::playerFull);
		}
		if (checkr.intersects(_repeatRect)) {
			float64 o = _stateHovers[OverRepeat];
			p.setOpacity(_repeat ? 1. : (o * st::playerInactiveOpacity + (1. - o) * st::playerUnavailableOpacity));
			p.drawSpriteCenterLeft(_repeatRect, width(), st::playerRepeat);
		}
		p.setOpacity(1.);

		p.setPen(st::playerTimeFg->p);
		p.setFont(st::linkFont->f);
		p.drawTextLeft(_infoRect.x() + _infoRect.width() - _timeWidth, _infoRect.y() + (_infoRect.height() - st::linkFont->height) / 2, width(), _time, _timeWidth);

		textstyleSet(&st::playerNameStyle);
		p.setPen(st::playerFg->p);
		_name.drawElided(p, _infoRect.x() + (rtl() ? (_timeWidth + st::playerSkip) : 0), _infoRect.y() + (_infoRect.height() - st::linkFont->height) / 2, _infoRect.width() - _timeWidth - st::playerSkip);
		textstyleRestore();
	}

	if (_duration) {
		float64 prg = (_down == OverPlayback) ? _downProgress : a_progress.current();
		int32 from = _playbackRect.x(), mid = qRound(_playbackRect.x() + prg * _playbackRect.width()), end = _playbackRect.x() + _playbackRect.width();
		if (mid > from) {
			p.fillRect(rtl() ? (width() - mid) : from, height() - st::playerLineHeight, mid - from, _playbackRect.height(), st::playerLineActive->b);
		}
		if (end > mid) {
			p.fillRect(rtl() ? (width() - end) : mid, height() - st::playerLineHeight, end - mid, st::playerLineHeight, st::playerLineInactive->b);
		}
		if (_stateHovers[OverPlayback] > 0) {
			p.setOpacity(_stateHovers[OverPlayback]);

			int32 x = mid - (st::playerMoverSize.width() / 2);
			p.fillRect(rtl() ? (width() - x - st::playerMoverSize.width()) : x, height() - st::playerMoverSize.height(), st::playerMoverSize.width(), st::playerMoverSize.height(), st::playerLineActive->b);
		}
	} else if (a_loadProgress.current() > 0) {
		int32 from = _playbackRect.x(), mid = qRound(_playbackRect.x() + a_loadProgress.current() * _playbackRect.width());
		if (mid > from) {
			p.fillRect(rtl() ? (width() - mid) : from, height() - st::playerLineHeight, mid - from, _playbackRect.height(), st::playerLineInactive->b);
		}
	}
}