From 39428841e43f89592c21d306aba25619c6484213 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 23 Nov 2017 18:58:00 +0400 Subject: [PATCH] Improve selected shared media items layout. Also fix night mode theme bug in report spam panel. --- Telegram/Resources/night.tdesktop-theme | Bin 8880 -> 8877 bytes Telegram/SourceFiles/boxes/boxes.style | 16 +- Telegram/SourceFiles/info/info.style | 21 +- .../info/media/info_media_list_widget.cpp | 3 +- Telegram/SourceFiles/overview/overview.style | 14 +- .../SourceFiles/overview/overview_layout.cpp | 540 +++++++++++------- .../SourceFiles/overview/overview_layout.h | 58 +- 7 files changed, 381 insertions(+), 271 deletions(-) diff --git a/Telegram/Resources/night.tdesktop-theme b/Telegram/Resources/night.tdesktop-theme index 035ed030dcb9dd3b355acb26eeac24e78eb90b39..3b25f9d55eb6df084a70c66a554d4c9a7a21f62c 100644 GIT binary patch delta 7862 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 + Checkbox(UpdateCallback callback, const style::RoundCheckbox &st) + : _updateCallback(callback) + , _check(st, _updateCallback) { + } + + void paint(Painter &p, TimeMs ms, QPoint position, int outerWidth, bool selected, bool selecting); + + void setActive(bool active); + void setPressed(bool pressed); + + void invalidateCache() { + _check.invalidateCache(); + } + +private: + void startAnimation(); + + base::lambda _updateCallback; + Ui::RoundCheckbox _check; + + Animation _pression; + bool _active = false; + bool _pressed = false; + +}; + +void Checkbox::paint(Painter &p, TimeMs ms, QPoint position, int outerWidth, bool selected, bool selecting) { + _check.setDisplayInactive(selecting); + _check.setChecked(selected); + const auto pression = _pression.current(ms, (_active && _pressed) ? 1. : 0.); + const auto masterScale = 1. - (1. - st::overviewCheckPressedSize) * pression; + _check.paint(p, ms, position.x(), position.y(), outerWidth, masterScale); +} + +void Checkbox::setActive(bool active) { + _active = active; + if (_pressed) { + startAnimation(); + } +} + +void Checkbox::setPressed(bool pressed) { + _pressed = pressed; + if (_active) { + startAnimation(); + } +} + +void Checkbox::startAnimation() { + auto showPressed = (_pressed && _active); + _pression.start(_updateCallback, showPressed ? 0. : 1., showPressed ? 1. : 0., st::overviewCheck.duration); +} + +ItemBase::ItemBase(not_null parent) : _parent(parent) { +} + void ItemBase::clickHandlerActiveChanged( const ClickHandlerPtr &action, bool active) { App::hoveredLinkItem(active ? _parent.get() : nullptr); Auth().data().requestItemRepaint(_parent); + if (_check) { + _check->setActive(active); + } } void ItemBase::clickHandlerPressedChanged( @@ -80,8 +142,44 @@ void ItemBase::clickHandlerPressedChanged( bool pressed) { App::pressedLinkItem(pressed ? _parent.get() : nullptr); Auth().data().requestItemRepaint(_parent); + if (_check) { + _check->setPressed(pressed); + } } +void ItemBase::invalidateCache() { + if (_check) { + _check->invalidateCache(); + } +} + +void ItemBase::paintCheckbox( + Painter &p, + QPoint position, + bool selected, + const PaintContext *context) { + if (selected || context->selecting) { + ensureCheckboxCreated(); + } + if (_check) { + _check->paint(p, context->ms, position, _width, selected, context->selecting); + } +} + +const style::RoundCheckbox &ItemBase::checkboxStyle() const { + return st::overviewCheck; +} + +void ItemBase::ensureCheckboxCreated() { + if (!_check) { + _check = std::make_unique( + [this] { Auth().data().requestItemRepaint(_parent); }, + checkboxStyle()); + } +} + +ItemBase::~ItemBase() = default; + void RadialProgressItem::setDocumentLinks( not_null document) { auto createSaveHandler = []( @@ -103,7 +201,7 @@ void RadialProgressItem::clickHandlerActiveChanged(const ClickHandlerPtr &action if (action == _openl || action == _savel || action == _cancell) { if (iconAnimated()) { _a_iconOver.start( - [this] { Auth().data().requestItemRepaint(_parent); }, + [this] { Auth().data().requestItemRepaint(parent()); }, active ? 0. : 1., active ? 1. : 0., st::msgFileOverDuration); @@ -119,7 +217,7 @@ void RadialProgressItem::setLinks(ClickHandlerPtr &&openl, ClickHandlerPtr &&sav void RadialProgressItem::step_radial(TimeMs ms, bool timer) { if (timer) { - Auth().data().requestItemRepaint(_parent); + Auth().data().requestItemRepaint(parent()); } else { _radial->update(dataProgress(), dataFinished(), ms); if (!_radial->animating()) { @@ -180,63 +278,6 @@ void Date::paint(Painter &p, const QRect &clip, TextSelection selection, const P } } -class PhotoVideoCheckbox { -public: - template - PhotoVideoCheckbox(UpdateCallback callback) : _updateCallback(callback), _check(st::overviewCheck, _updateCallback) { - } - - void paint(Painter &p, TimeMs ms, int width, int height, bool selected, bool selecting); - - void setActive(bool active); - void setPressed(bool pressed); - - void invalidateCache() { - _check.invalidateCache(); - } - -private: - void startAnimation(); - - base::lambda _updateCallback; - Ui::RoundCheckbox _check; - - Animation _pression; - bool _active = false; - bool _pressed = false; - -}; - -void PhotoVideoCheckbox::paint(Painter &p, TimeMs ms, int width, int height, bool selected, bool selecting) { - if (selected) { - p.fillRect(0, 0, width, height, st::overviewPhotoSelectOverlay); - } - _check.setDisplayInactive(selecting); - _check.setChecked(selected); - auto pression = _pression.current(ms, (_active && _pressed) ? 1. : 0.); - auto masterScale = 1. - (1. - st::overviewCheckPressedSize) * pression; - _check.paint(p, ms, width - st::overviewCheckSkip - st::overviewCheck.size, height - st::overviewCheckSkip - st::overviewCheck.size, width, masterScale); -} - -void PhotoVideoCheckbox::setActive(bool active) { - _active = active; - if (_pressed) { - startAnimation(); - } -} - -void PhotoVideoCheckbox::setPressed(bool pressed) { - _pressed = pressed; - if (_active) { - startAnimation(); - } -} - -void PhotoVideoCheckbox::startAnimation() { - auto showPressed = (_pressed && _active); - _pression.start(_updateCallback, showPressed ? 0. : 1., showPressed ? 1. : 0., st::overviewCheck.duration); -} - Photo::Photo( not_null parent, not_null photo) @@ -262,7 +303,7 @@ int32 Photo::resizeGetHeight(int32 width) { void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) { bool good = _data->loaded(), selected = (selection == FullSelection); if (!good) { - _data->medium->automaticLoad(_parent); + _data->medium->automaticLoad(parent()); good = _data->medium->loaded(); } if ((good && !_goodLoaded) || _pix.width() != _width * cIntRetinaFactor()) { @@ -298,18 +339,13 @@ void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const p.drawPixmap(0, 0, _pix); } - if (selected || context->selecting) { - ensureCheckboxCreated(); + if (selected) { + p.fillRect(0, 0, _width, _height, st::overviewPhotoSelectOverlay); } - if (_check) { - _check->paint(p, context->ms, _width, _height, selected, context->selecting); - } -} - -void Photo::ensureCheckboxCreated() { - if (!_check) _check = std::make_unique([this] { - Auth().data().requestItemRepaint(_parent); - }); + const auto checkDelta = st::overviewCheckSkip + st::overviewCheck.size; + const auto checkLeft = _width - checkDelta; + const auto checkTop = _height - checkDelta; + paintCheckbox(p, { checkLeft, checkTop }, selected, context); } HistoryTextState Photo::getState( @@ -321,28 +357,6 @@ HistoryTextState Photo::getState( return {}; } -void Photo::clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) { - ItemBase::clickHandlerActiveChanged(action, active); - if (_check) { - _check->setActive(active); - } -} - -void Photo::clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) { - ItemBase::clickHandlerPressedChanged(action, pressed); - if (_check) { - _check->setPressed(pressed); - } -} - -void Photo::invalidateCache() { - if (_check) { - _check->invalidateCache(); - } -} - -Photo::~Photo() = default; - Video::Video( not_null parent, not_null video) @@ -367,7 +381,7 @@ int32 Video::resizeGetHeight(int32 width) { void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) { bool selected = (selection == FullSelection), thumbLoaded = _data->thumb->loaded(); - _data->automaticLoad(_parent); + _data->automaticLoad(parent()); bool loaded = _data->loaded(), displayLoading = _data->displayLoading(); if (displayLoading) { ensureRadial(); @@ -466,39 +480,12 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const } } - if (selected || context->selecting) { - ensureCheckboxCreated(); - } - if (_check) { - _check->paint(p, context->ms, _width, _height, selected, context->selecting); - } + const auto checkDelta = st::overviewCheckSkip + st::overviewCheck.size; + const auto checkLeft = _width - checkDelta; + const auto checkTop = _height - checkDelta; + paintCheckbox(p, { checkLeft, checkTop }, selected, context); } -void Video::ensureCheckboxCreated() { - if (!_check) _check = std::make_unique([this] { - Auth().data().requestItemRepaint(_parent); - }); -} - -void Video::clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) { - RadialProgressItem::clickHandlerActiveChanged(action, active); - if (_check) { - _check->setActive(active); - } -} - -void Video::clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) { - RadialProgressItem::clickHandlerPressedChanged(action, pressed); - if (_check) { - _check->setPressed(pressed); - } -} - -void Video::invalidateCache() { - if (_check) { - _check->invalidateCache(); - } -} float64 Video::dataProgress() const { return _data->progress(); } @@ -551,8 +538,6 @@ void Video::updateStatusText() { } } -Video::~Video() = default; - Voice::Voice( not_null parent, not_null voice, @@ -582,7 +567,7 @@ void Voice::initDimensions() { void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) { bool selected = (selection == FullSelection); - _data->automaticLoad(_parent); + _data->automaticLoad(parent()); bool loaded = _data->loaded(), displayLoading = _data->displayLoading(); if (displayLoading) { @@ -592,24 +577,26 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const } } bool showPause = updateStatusText(); - int32 nameVersion = _parent->fromOriginal()->nameVersion; + int32 nameVersion = parent()->fromOriginal()->nameVersion; if (nameVersion > _nameVersion) { updateName(); } bool radial = isRadialAnimation(context->ms); - int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = -1; + const auto nameleft = _st.songPadding.left() + + _st.songThumbSize + + _st.songPadding.right(); + const auto nameright = _st.songPadding.left(); + const auto nametop = _st.songNameTop; + const auto statustop = _st.songStatusTop; + const auto namewidth = _width - nameleft - nameright; - nameleft = _st.songPadding.left() + _st.songThumbSize + _st.songPadding.right(); - nameright = _st.songPadding.left(); - nametop = _st.songNameTop; - statustop = _st.songStatusTop; - - if (selected) { - p.fillRect(clip.intersected(QRect(0, 0, _width, _height)), st::msgInBgSelected); - } - - QRect inner(rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width)); + const auto inner = rtlrect( + _st.songPadding.left(), + _st.songPadding.top(), + _st.songThumbSize, + _st.songThumbSize, + _width); if (clip.intersects(inner)) { p.setPen(Qt::NoPen); if (selected) { @@ -643,8 +630,6 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const icon->paintInCenter(p, inner); } - int32 namewidth = _width - nameleft - nameright; - if (clip.intersects(rtlrect(nameleft, nametop, namewidth, st::semiboldFont->height, _width))) { p.setPen(st::historyFileNameInFg); _name.drawLeftElided(p, nameleft, nametop, namewidth, _width); @@ -664,7 +649,7 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const p.drawTextLeft(nameleft, statustop, _width, _status.text(), statusw); unreadx += statusw; } - if (_parent->isMediaUnread() && unreadx + st::mediaUnreadSkip + st::mediaUnreadSize <= _width) { + if (parent()->isMediaUnread() && unreadx + st::mediaUnreadSkip + st::mediaUnreadSize <= _width) { p.setPen(Qt::NoPen); p.setBrush(selected ? st::msgFileInBgSelected : st::msgFileInBg); @@ -674,33 +659,65 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const } } } + + const auto checkDelta = _st.songThumbSize + + st::overviewCheckSkip + - st::overviewSmallCheck.size; + const auto checkLeft = _st.songPadding.left() + checkDelta; + const auto checkTop = _st.songPadding.top() + checkDelta; + paintCheckbox(p, { checkLeft, checkTop }, selected, context); } HistoryTextState Voice::getState( QPoint point, HistoryStateRequest request) const { - bool loaded = _data->loaded(); + const auto loaded = _data->loaded(); - int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = 0; + const auto nameleft = _st.songPadding.left() + + _st.songThumbSize + + _st.songPadding.right(); + const auto nameright = _st.songPadding.left(); + const auto nametop = _st.songNameTop; + const auto statustop = _st.songStatusTop; - nameleft = _st.songPadding.left() + _st.songThumbSize + _st.songPadding.right(); - nameright = _st.songPadding.left(); - nametop = _st.songNameTop; - statustop = _st.songStatusTop; - - auto inner = rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width); + const auto inner = rtlrect( + _st.songPadding.left(), + _st.songPadding.top(), + _st.songThumbSize, + _st.songThumbSize, + _width); if (inner.contains(point)) { - return loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _openl); + return loaded + ? _openl + : ((_data->loading() || _data->status == FileUploading) + ? _cancell + : _openl); } auto result = HistoryTextState(); - if (rtlrect(nameleft, statustop, _width - nameleft - nameright, st::normalFont->height, _width).contains(point)) { + const auto statusmaxwidth = _width - nameleft - nameright; + const auto statusrect = rtlrect( + nameleft, + statustop, + statusmaxwidth, + st::normalFont->height, + _width); + if (statusrect.contains(point)) { if (_status.size() == FileStatusSizeLoaded || _status.size() == FileStatusSizeReady) { auto textState = _details.getStateLeft(point - QPoint(nameleft, statustop), _width, _width); result.link = textState.link; result.cursor = textState.uponSymbol ? HistoryInTextCursorState : HistoryDefaultCursorState; } } - if (hasPoint(point) && !result.link && !_data->loading()) { + const auto namewidth = std::min( + _width - nameleft - nameright, + _name.maxWidth()); + const auto namerect = rtlrect( + nameleft, + nametop, + namewidth, + st::normalFont->height, + _width); + if (namerect.contains(point) && !result.link && !_data->loading()) { return _namel; } return result; @@ -722,18 +739,22 @@ bool Voice::iconAnimated() const { return true; } +const style::RoundCheckbox &Voice::checkboxStyle() const { + return st::overviewSmallCheck; +} + void Voice::updateName() { auto version = 0; - if (auto forwarded = _parent->Get()) { - if (_parent->fromOriginal()->isChannel()) { - _name.setText(st::semiboldTextStyle, lng_forwarded_channel(lt_channel, App::peerName(_parent->fromOriginal())), _textNameOptions); + if (auto forwarded = parent()->Get()) { + if (parent()->fromOriginal()->isChannel()) { + _name.setText(st::semiboldTextStyle, lng_forwarded_channel(lt_channel, App::peerName(parent()->fromOriginal())), _textNameOptions); } else { - _name.setText(st::semiboldTextStyle, lng_forwarded(lt_user, App::peerName(_parent->fromOriginal())), _textNameOptions); + _name.setText(st::semiboldTextStyle, lng_forwarded(lt_user, App::peerName(parent()->fromOriginal())), _textNameOptions); } } else { - _name.setText(st::semiboldTextStyle, App::peerName(_parent->from()), _textNameOptions); + _name.setText(st::semiboldTextStyle, App::peerName(parent()->from()), _textNameOptions); } - version = _parent->fromOriginal()->nameVersion; + version = parent()->fromOriginal()->nameVersion; _nameVersion = version; } @@ -746,7 +767,7 @@ bool Voice::updateStatusText() { statusSize = FileStatusSizeLoaded; using State = Media::Player::State; auto state = Media::Player::mixer()->currentState(AudioMsgId::Type::Voice); - if (state.id == AudioMsgId(_data, _parent->fullId()) && !Media::Player::IsStoppedOrStopping(state.state)) { + if (state.id == AudioMsgId(_data, parent()->fullId()) && !Media::Player::IsStoppedOrStopping(state.state)) { statusSize = -1 - (state.position / state.frequency); realDuration = (state.length / state.frequency); showPause = (state.state == State::Playing || state.state == State::Resuming || state.state == State::Starting); @@ -811,7 +832,7 @@ void Document::initDimensions() { void Document::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) { bool selected = (selection == FullSelection); - _data->automaticLoad(_parent); + _data->automaticLoad(parent()); bool loaded = _data->loaded() || Local::willStickerImageLoad(_data->mediaKey()), displayLoading = _data->displayLoading(); if (displayLoading) { @@ -833,10 +854,6 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con nametop = _st.songNameTop; statustop = _st.songStatusTop; - if (selected) { - p.fillRect(QRect(0, 0, _width, _height), st::msgInBgSelected); - } - auto inner = rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width); if (clip.intersects(inner)) { p.setPen(Qt::NoPen); @@ -941,16 +958,11 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con } } } - if (selected || context->selecting) { - QRect check(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - st::defaultCheck.diameter), rthumb.height() - st::defaultCheck.diameter), QSize(st::defaultCheck.diameter, st::defaultCheck.diameter)); - p.fillRect(check, selected ? st::overviewFileChecked : st::overviewFileCheck); - st::defaultCheck.icon.paint(p, QPoint(rthumb.width() - st::defaultCheck.diameter, rthumb.y() + rthumb.height() - st::defaultCheck.diameter), _width); - } } } - int availwidth = _width - nameleft - nameright; - int namewidth = qMin(availwidth, _name.maxWidth()); + const auto availwidth = _width - nameleft - nameright; + const auto namewidth = std::min(availwidth, _name.maxWidth()); if (clip.intersects(rtlrect(nameleft, nametop, namewidth, st::semiboldFont->height, _width))) { p.setPen(st::historyFileNameInFg); _name.drawLeftElided(p, nameleft, nametop, namewidth, _width); @@ -966,51 +978,110 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con p.setPen(st::mediaInFg); p.drawTextLeft(nameleft, datetop, _width, _date, _datew); } + + const auto checkDelta = (isSong ? _st.songThumbSize : _st.fileThumbSize) + + (isSong ? st::overviewCheckSkip : -st::overviewCheckSkip) + - st::overviewSmallCheck.size; + const auto checkLeft = (isSong + ? _st.songPadding.left() + : 0) + checkDelta; + const auto checkTop = (isSong + ? _st.songPadding.top() + : (st::linksBorder + _st.filePadding.top())) + checkDelta; + paintCheckbox(p, { checkLeft, checkTop }, selected, context); } HistoryTextState Document::getState( QPoint point, HistoryStateRequest request) const { - bool loaded = _data->loaded() || Local::willStickerImageLoad(_data->mediaKey()); - - int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = 0; - bool wthumb = withThumb(); + const auto loaded = _data->loaded() + || Local::willStickerImageLoad(_data->mediaKey()); + const auto wthumb = withThumb(); if (_data->song()) { - nameleft = _st.songPadding.left() + _st.songThumbSize + _st.songPadding.right(); - nameright = _st.songPadding.left(); - nametop = _st.songNameTop; - statustop = _st.songStatusTop; + const auto nameleft = _st.songPadding.left() + _st.songThumbSize + _st.songPadding.right(); + const auto nameright = _st.songPadding.left(); + const auto namewidth = std::min( + _width - nameleft - nameright, + _name.maxWidth()); + const auto nametop = _st.songNameTop; + const auto statustop = _st.songStatusTop; - auto inner = rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width); + const auto inner = rtlrect( + _st.songPadding.left(), + _st.songPadding.top(), + _st.songThumbSize, + _st.songThumbSize, + _width); if (inner.contains(point)) { - return loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _openl); + return loaded + ? _openl + : ((_data->loading() || _data->status == FileUploading) + ? _cancell + : _openl); } - if (hasPoint(point) && !_data->loading()) { + const auto namerect = rtlrect( + nameleft, + nametop, + namewidth, + st::semiboldFont->height, + _width); + if (namerect.contains(point) && !_data->loading()) { return _namel; } } else { - nameleft = _st.fileThumbSize + _st.filePadding.right(); - nametop = st::linksBorder + _st.fileNameTop; - statustop = st::linksBorder + _st.fileStatusTop; - datetop = st::linksBorder + _st.fileDateTop; + const auto nameleft = _st.fileThumbSize + _st.filePadding.right(); + const auto nameright = 0; + const auto nametop = st::linksBorder + _st.fileNameTop; + const auto namewidth = std::min( + _width - nameleft - nameright, + _name.maxWidth()); + const auto statustop = st::linksBorder + _st.fileStatusTop; + const auto datetop = st::linksBorder + _st.fileDateTop; - auto rthumb = rtlrect(0, st::linksBorder + _st.filePadding.top(), _st.fileThumbSize, _st.fileThumbSize, _width); + const auto rthumb = rtlrect( + 0, + st::linksBorder + _st.filePadding.top(), + _st.fileThumbSize, + _st.fileThumbSize, + _width); if (rthumb.contains(point)) { - return loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _savel); + return loaded + ? _openl + : ((_data->loading() || _data->status == FileUploading) + ? _cancell + : _savel); } if (_data->status != FileUploadFailed) { - if (rtlrect(nameleft, datetop, _datew, st::normalFont->height, _width).contains(point)) { + auto daterect = rtlrect( + nameleft, + datetop, + _datew, + st::normalFont->height, + _width); + if (daterect.contains(point)) { return _msgl; } } if (!_data->loading() && _data->isValid()) { - if (loaded && rtlrect(0, st::linksBorder, nameleft, _height - st::linksBorder, _width).contains(point)) { + auto leftofnamerect = rtlrect( + 0, + st::linksBorder, + nameleft, + _height - st::linksBorder, + _width); + if (loaded && leftofnamerect.contains(point)) { return _namel; } - if (rtlrect(nameleft, nametop, qMin(_width - nameleft - nameright, _name.maxWidth()), st::semiboldFont->height, _width).contains(point)) { + const auto namerect = rtlrect( + nameleft, + nametop, + namewidth, + st::semiboldFont->height, + _width); + if (namerect.contains(point)) { return _namel; } } @@ -1018,6 +1089,10 @@ HistoryTextState Document::getState( return {}; } +const style::RoundCheckbox &Document::checkboxStyle() const { + return st::overviewSmallCheck; +} + float64 Document::dataProgress() const { return _data->progress(); } @@ -1056,12 +1131,12 @@ bool Document::updateStatusText() { statusSize = FileStatusSizeLoaded; using State = Media::Player::State; auto state = Media::Player::mixer()->currentState(AudioMsgId::Type::Song); - if (state.id == AudioMsgId(_data, _parent->fullId()) && !Media::Player::IsStoppedOrStopping(state.state)) { + if (state.id == AudioMsgId(_data, parent()->fullId()) && !Media::Player::IsStoppedOrStopping(state.state)) { statusSize = -1 - (state.position / state.frequency); realDuration = (state.length / state.frequency); showPause = (state.state == State::Playing || state.state == State::Resuming || state.state == State::Starting); } - if (!showPause && (state.id == AudioMsgId(_data, _parent->fullId())) && Media::Player::instance()->isSeeking(AudioMsgId::Type::Song)) { + if (!showPause && (state.id == AudioMsgId(_data, parent()->fullId())) && Media::Player::instance()->isSeeking(AudioMsgId::Type::Song)) { showPause = true; } } else { @@ -1082,19 +1157,20 @@ Link::Link( : ItemBase(parent) { AddComponents(Info::Bit()); - auto textWithEntities = _parent->originalText(); + auto textWithEntities = parent->originalText(); QString mainUrl; auto text = textWithEntities.text; - auto &entities = textWithEntities.entities; + const auto &entities = textWithEntities.entities; int32 from = 0, till = text.size(), lnk = entities.size(); - for_const (auto &entity, entities) { + for (const auto &entity : entities) { auto type = entity.type(); if (type != EntityInTextUrl && type != EntityInTextCustomUrl && type != EntityInTextEmail) { continue; } - auto customUrl = entity.data(), entityText = text.mid(entity.offset(), entity.length()); - auto url = customUrl.isEmpty() ? entityText : customUrl; + const auto customUrl = entity.data(); + const auto entityText = text.mid(entity.offset(), entity.length()); + const auto url = customUrl.isEmpty() ? entityText : customUrl; if (_links.isEmpty()) { mainUrl = url; } @@ -1235,8 +1311,11 @@ int32 Link::resizeGetHeight(int32 width) { } void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) { - int32 left = st::linksPhotoSize + st::linksPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left; - if (clip.intersects(rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width))) { + auto selected = (selection == FullSelection); + + const auto pixLeft = 0; + const auto pixTop = st::linksMargin.top() + st::linksBorder; + if (clip.intersects(rtlrect(0, pixTop, st::linksPhotoSize, st::linksPhotoSize, _width))) { if (_page && _page->photo) { QPixmap pix; if (_page->photo->medium->loaded()) { @@ -1246,39 +1325,46 @@ void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const P } else { pix = _page->photo->thumb->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small); } - p.drawPixmapLeft(0, top, _width, pix); + p.drawPixmapLeft(pixLeft, pixTop, _width, pix); } else if (_page && _page->document && !_page->document->thumb->isNull()) { auto roundRadius = _page->document->isRoundVideo() ? ImageRoundRadius::Ellipse : ImageRoundRadius::Small; - p.drawPixmapLeft(0, top, _width, _page->document->thumb->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, roundRadius)); + p.drawPixmapLeft(pixLeft, pixTop, _width, _page->document->thumb->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, roundRadius)); } else { - int32 index = _letter.isEmpty() ? 0 : (_letter.at(0).unicode() % 4); + const auto index = _letter.isEmpty() + ? 0 + : (_letter[0].unicode() % 4); + const auto fill = [&](style::color color, RoundCorners corners) { + auto pixRect = rtlrect( + pixLeft, + pixTop, + st::linksPhotoSize, + st::linksPhotoSize, + _width); + App::roundRect(p, pixRect, color, corners); + }; switch (index) { - case 0: App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::msgFile1Bg, Doc1Corners); break; - case 1: App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::msgFile2Bg, Doc2Corners); break; - case 2: App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::msgFile3Bg, Doc3Corners); break; - case 3: App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::msgFile4Bg, Doc4Corners); break; + case 0: fill(st::msgFile1Bg, Doc1Corners); break; + case 1: fill(st::msgFile2Bg, Doc2Corners); break; + case 2: fill(st::msgFile3Bg, Doc3Corners); break; + case 3: fill(st::msgFile4Bg, Doc4Corners); break; } if (!_letter.isEmpty()) { p.setFont(st::linksLetterFont); p.setPen(st::linksLetterFg); - p.drawText(rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), _letter, style::al_center); + p.drawText(rtlrect(pixLeft, pixTop, st::linksPhotoSize, st::linksPhotoSize, _width), _letter, style::al_center); } } + } - if (selection == FullSelection) { - App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::overviewPhotoSelectOverlay, PhotoSelectOverlayCorners); - st::overviewLinksChecked.paint(p, QPoint(st::linksPhotoSize - st::overviewLinksChecked.width(), top + st::linksPhotoSize - st::overviewLinksChecked.height()), _width); - } else if (context->selecting) { - st::overviewLinksCheck.paint(p, QPoint(st::linksPhotoSize - st::overviewLinksCheck.width(), top + st::linksPhotoSize - st::overviewLinksCheck.height()), _width); + const auto left = st::linksPhotoSize + st::linksPhotoPadding; + const auto w = _width - left; + auto top = [&] { + if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) { + return pixTop + (st::linksPhotoSize - st::semiboldFont->height - st::normalFont->height) / 2; } - } - - if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) { - top += (st::linksPhotoSize - st::semiboldFont->height - st::normalFont->height) / 2; - } else { - top = st::linksTextTop; - } + return st::linksTextTop; + }(); p.setPen(st::linksTextFg); p.setFont(st::semiboldFont); @@ -1310,6 +1396,12 @@ void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const P if (!context->isAfterDate && clip.intersects(border)) { p.fillRect(clip.intersected(border), st::linksBorderFg); } + + const auto checkDelta = st::linksPhotoSize + st::overviewCheckSkip + - st::overviewSmallCheck.size; + const auto checkLeft = pixLeft + checkDelta; + const auto checkTop = pixTop + checkDelta; + paintCheckbox(p, { checkLeft, checkTop }, selected, context); } HistoryTextState Link::getState( @@ -1341,6 +1433,10 @@ HistoryTextState Link::getState( return {}; } +const style::RoundCheckbox &Link::checkboxStyle() const { + return st::overviewSmallCheck; +} + Link::LinkEntry::LinkEntry(const QString &url, const QString &text) : text(text) , width(st::normalFont->width(text)) diff --git a/Telegram/SourceFiles/overview/overview_layout.h b/Telegram/SourceFiles/overview/overview_layout.h index 57d9a64ae3..f8d0e5d8d1 100644 --- a/Telegram/SourceFiles/overview/overview_layout.h +++ b/Telegram/SourceFiles/overview/overview_layout.h @@ -25,9 +25,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "ui/effects/radial_animation.h" #include "styles/style_overview.h" +namespace style { +struct RoundCheckbox; +} // namespace style + namespace Overview { namespace Layout { +class Checkbox; + class PaintContext : public PaintContextBase { public: PaintContext(TimeMs ms, bool selecting) : PaintContextBase(ms, selecting), isAfterDate(false) { @@ -66,8 +72,7 @@ public: class ItemBase : public AbstractItem { public: - ItemBase(not_null parent) : _parent(parent) { - } + ItemBase(not_null parent); void setPosition(int position) { _position = position; @@ -89,9 +94,27 @@ public: void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override; void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override; + void invalidateCache() override; + + ~ItemBase(); + protected: - not_null _parent; + not_null parent() const { + return _parent; + } + void paintCheckbox( + Painter &p, + QPoint position, + bool selected, + const PaintContext *context); + virtual const style::RoundCheckbox &checkboxStyle() const; + +private: + void ensureCheckboxCreated(); + int _position = 0; + not_null _parent; + std::unique_ptr _check; }; @@ -178,8 +201,6 @@ private: }; -class PhotoVideoCheckbox; - class Photo : public ItemBase { public: Photo( @@ -193,18 +214,7 @@ public: QPoint point, HistoryStateRequest request) const override; - void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override; - void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override; - - void invalidateCache() override; - - ~Photo(); - private: - void ensureCheckboxCreated(); - - std::unique_ptr _check; - not_null _data; ClickHandlerPtr _link; @@ -226,13 +236,6 @@ public: QPoint point, HistoryStateRequest request) const override; - void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override; - void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override; - - void invalidateCache() override; - - ~Video(); - protected: float64 dataProgress() const override; bool dataFinished() const override; @@ -240,10 +243,6 @@ protected: bool iconAnimated() const override; private: - void ensureCheckboxCreated(); - - std::unique_ptr _check; - not_null _data; StatusText _status; @@ -273,6 +272,7 @@ protected: bool dataFinished() const override; bool dataLoaded() const override; bool iconAnimated() const override; + const style::RoundCheckbox &checkboxStyle() const override; private: not_null _data; @@ -311,6 +311,7 @@ protected: bool dataFinished() const override; bool dataLoaded() const override; bool iconAnimated() const override; + const style::RoundCheckbox &checkboxStyle() const override; private: not_null _data; @@ -345,6 +346,9 @@ public: QPoint point, HistoryStateRequest request) const override; +protected: + const style::RoundCheckbox &checkboxStyle() const override; + private: ClickHandlerPtr _photol;