mirror of https://github.com/procxx/kepka.git
Improve selected shared media items layout.
Also fix night mode theme bug in report spam panel.
This commit is contained in:
parent
981063596a
commit
39428841e4
Binary file not shown.
|
@ -311,17 +311,23 @@ contactsMultiSelect: MultiSelect {
|
||||||
fieldCancel: contactsSearchCancel;
|
fieldCancel: contactsSearchCancel;
|
||||||
fieldCancelSkip: 40px;
|
fieldCancelSkip: 40px;
|
||||||
}
|
}
|
||||||
|
contactsPhotoCheckIcon: icon {{
|
||||||
|
"default_checkbox_check",
|
||||||
|
windowFgActive,
|
||||||
|
point(3px, 6px)
|
||||||
|
}};
|
||||||
|
contactsPhotoCheck: RoundCheckbox(defaultRoundCheckbox) {
|
||||||
|
size: 20px;
|
||||||
|
sizeSmall: 0.3;
|
||||||
|
check: contactsPhotoCheckIcon;
|
||||||
|
}
|
||||||
contactsPhotoCheckbox: RoundImageCheckbox {
|
contactsPhotoCheckbox: RoundImageCheckbox {
|
||||||
imageRadius: 21px;
|
imageRadius: 21px;
|
||||||
imageSmallRadius: 18px;
|
imageSmallRadius: 18px;
|
||||||
selectWidth: 2px;
|
selectWidth: 2px;
|
||||||
selectFg: windowBgActive;
|
selectFg: windowBgActive;
|
||||||
selectDuration: 150;
|
selectDuration: 150;
|
||||||
check: RoundCheckbox(defaultRoundCheckbox) {
|
check: contactsPhotoCheck;
|
||||||
size: 20px;
|
|
||||||
sizeSmall: 0.3;
|
|
||||||
check: icon {{ "default_checkbox_check", windowFgActive, point(3px, 6px) }};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
contactsPhotoDisabledCheckFg: menuIconFg;
|
contactsPhotoDisabledCheckFg: menuIconFg;
|
||||||
contactsNameCheckedFg: windowActiveTextFg;
|
contactsNameCheckedFg: windowActiveTextFg;
|
||||||
|
|
|
@ -131,11 +131,16 @@ infoTopBarTitle: FlatLabel(defaultFlatLabel) {
|
||||||
linkFontOver: font(14px semibold);
|
linkFontOver: font(14px semibold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
infoTopBarClose: IconButton(infoTopBarBack) {
|
infoTopBarMediaCancel: IconButton(infoTopBarBack) {
|
||||||
width: infoTopBarHeight;
|
width: infoTopBarHeight;
|
||||||
icon: icon {{ "info_close", boxTitleCloseFg }};
|
icon: icon {{ "info_close", boxTitleCloseFg }};
|
||||||
iconOver: icon {{ "info_close", boxTitleCloseFgOver }};
|
iconOver: icon {{ "info_close", boxTitleCloseFgOver }};
|
||||||
}
|
}
|
||||||
|
infoTopBarClose: IconButton(infoTopBarMediaCancel) {
|
||||||
|
width: 48px;
|
||||||
|
iconPosition: point(5px, -1px);
|
||||||
|
rippleAreaPosition: point(0px, 6px);
|
||||||
|
}
|
||||||
infoTopBarSearch: IconButton(infoTopBarBack) {
|
infoTopBarSearch: IconButton(infoTopBarBack) {
|
||||||
width: 56px;
|
width: 56px;
|
||||||
icon: icon {{ "top_bar_search", boxTitleCloseFg }};
|
icon: icon {{ "top_bar_search", boxTitleCloseFg }};
|
||||||
|
@ -176,7 +181,7 @@ infoTopBar: InfoTopBar {
|
||||||
title: infoTopBarTitle;
|
title: infoTopBarTitle;
|
||||||
titlePosition: point(23px, 18px);
|
titlePosition: point(23px, 18px);
|
||||||
bg: windowBg;
|
bg: windowBg;
|
||||||
mediaCancel: infoTopBarClose;
|
mediaCancel: infoTopBarMediaCancel;
|
||||||
mediaActionsSkip: 4px;
|
mediaActionsSkip: 4px;
|
||||||
mediaForward: infoTopBarForward;
|
mediaForward: infoTopBarForward;
|
||||||
mediaDelete: infoTopBarDelete;
|
mediaDelete: infoTopBarDelete;
|
||||||
|
@ -200,12 +205,12 @@ infoLayerTopBarBack: IconButton(infoTopBarBack) {
|
||||||
iconOver: infoLayerTopBarBackIconOver;
|
iconOver: infoLayerTopBarBackIconOver;
|
||||||
rippleAreaSize: 44px;
|
rippleAreaSize: 44px;
|
||||||
}
|
}
|
||||||
infoLayerTopBarCloseIcon: icon {{ "info_close", boxTitleCloseFg }};
|
infoLayerTopBarMediaCancel: IconButton(infoLayerTopBarBack) {
|
||||||
infoLayerTopBarCloseIconOver: icon {{ "info_close", boxTitleCloseFgOver }};
|
icon: icon {{ "info_close", boxTitleCloseFg }};
|
||||||
infoLayerTopBarClose: IconButton(infoLayerTopBarBack) {
|
iconOver: icon {{ "info_close", boxTitleCloseFgOver }};
|
||||||
|
}
|
||||||
|
infoLayerTopBarClose: IconButton(infoLayerTopBarMediaCancel) {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
icon: infoLayerTopBarCloseIcon;
|
|
||||||
iconOver: infoLayerTopBarCloseIconOver;
|
|
||||||
iconPosition: point(6px, -1px);
|
iconPosition: point(6px, -1px);
|
||||||
rippleAreaPosition: point(0px, 6px);
|
rippleAreaPosition: point(0px, 6px);
|
||||||
}
|
}
|
||||||
|
@ -237,7 +242,7 @@ infoLayerTopBar: InfoTopBar(infoTopBar) {
|
||||||
title: boxTitle;
|
title: boxTitle;
|
||||||
titlePosition: boxLayerTitlePosition;
|
titlePosition: boxLayerTitlePosition;
|
||||||
bg: boxBg;
|
bg: boxBg;
|
||||||
mediaCancel: infoLayerTopBarClose;
|
mediaCancel: infoLayerTopBarMediaCancel;
|
||||||
mediaActionsSkip: 6px;
|
mediaActionsSkip: 6px;
|
||||||
mediaForward: infoLayerTopBarForward;
|
mediaForward: infoLayerTopBarForward;
|
||||||
mediaDelete: infoLayerTopBarDelete;
|
mediaDelete: infoLayerTopBarDelete;
|
||||||
|
|
|
@ -1784,7 +1784,8 @@ void ListWidget::mouseActionStart(const QPoint &screenPos, Qt::MouseButton butto
|
||||||
if (ClickHandler::getPressed() && !hasSelected()) {
|
if (ClickHandler::getPressed() && !hasSelected()) {
|
||||||
_mouseAction = MouseAction::PrepareDrag;
|
_mouseAction = MouseAction::PrepareDrag;
|
||||||
} else if (hasSelectedItems()) {
|
} else if (hasSelectedItems()) {
|
||||||
if (isItemUnderPressSelected()) {
|
if (isItemUnderPressSelected() && ClickHandler::getPressed()) {
|
||||||
|
// In shared media overview drag only by click handlers.
|
||||||
_mouseAction = MouseAction::PrepareDrag; // start items drag
|
_mouseAction = MouseAction::PrepareDrag; // start items drag
|
||||||
} else if (!_pressWasInactive) {
|
} else if (!_pressWasInactive) {
|
||||||
_mouseAction = MouseAction::PrepareSelect; // start items select
|
_mouseAction = MouseAction::PrepareSelect; // start items select
|
||||||
|
|
|
@ -22,6 +22,7 @@ using "basic.style";
|
||||||
using "history/history.style";
|
using "history/history.style";
|
||||||
using "ui/widgets/widgets.style";
|
using "ui/widgets/widgets.style";
|
||||||
using "media/view/mediaview.style";
|
using "media/view/mediaview.style";
|
||||||
|
using "boxes/boxes.style";
|
||||||
|
|
||||||
OverviewFileLayout {
|
OverviewFileLayout {
|
||||||
maxWidth: pixels;
|
maxWidth: pixels;
|
||||||
|
@ -59,6 +60,11 @@ overviewCheck: RoundCheckbox(defaultRoundCheckbox) {
|
||||||
sizeSmall: 0.3;
|
sizeSmall: 0.3;
|
||||||
check: icon {{ "overview_photo_check", overviewCheckFgActive, point(4px, 8px) }};
|
check: icon {{ "overview_photo_check", overviewCheckFgActive, point(4px, 8px) }};
|
||||||
}
|
}
|
||||||
|
overviewSmallCheck: RoundCheckbox(contactsPhotoCheck) {
|
||||||
|
bgInactive: overviewCheckBg;
|
||||||
|
bgActive: overviewCheckBgActive;
|
||||||
|
border: overviewCheckBorder;
|
||||||
|
}
|
||||||
overviewCheckSkip: 5px;
|
overviewCheckSkip: 5px;
|
||||||
|
|
||||||
overviewPhotoBg: windowBgOver;
|
overviewPhotoBg: windowBgOver;
|
||||||
|
@ -125,14 +131,6 @@ linksDateColor: windowSubTextFg;
|
||||||
linksDateMargin: margins(0px, 15px, 0px, 2px);
|
linksDateMargin: margins(0px, 15px, 0px, 2px);
|
||||||
linksPhotoSize: 46px;
|
linksPhotoSize: 46px;
|
||||||
linksPhotoPadding: 12px;
|
linksPhotoPadding: 12px;
|
||||||
overviewLinksCheck: icon {
|
|
||||||
{ "overview_links_check_bg", overviewCheckBg },
|
|
||||||
{ "overview_links_check", overviewCheckFg, point(4px, 5px) },
|
|
||||||
};
|
|
||||||
overviewLinksChecked: icon {
|
|
||||||
{ "overview_links_check_bg", overviewCheckBgActive },
|
|
||||||
{ "overview_links_check", overviewCheckFgActive, point(4px, 5px) },
|
|
||||||
};
|
|
||||||
|
|
||||||
overviewFilter: FlatInput(defaultFlatInput) {
|
overviewFilter: FlatInput(defaultFlatInput) {
|
||||||
font: font(fsize);
|
font: font(fsize);
|
||||||
|
|
|
@ -68,11 +68,73 @@ TextWithEntities ComposeNameWithEntities(DocumentData *document) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
class Checkbox {
|
||||||
|
public:
|
||||||
|
template <typename UpdateCallback>
|
||||||
|
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<void()> _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<HistoryItem*> parent) : _parent(parent) {
|
||||||
|
}
|
||||||
|
|
||||||
void ItemBase::clickHandlerActiveChanged(
|
void ItemBase::clickHandlerActiveChanged(
|
||||||
const ClickHandlerPtr &action,
|
const ClickHandlerPtr &action,
|
||||||
bool active) {
|
bool active) {
|
||||||
App::hoveredLinkItem(active ? _parent.get() : nullptr);
|
App::hoveredLinkItem(active ? _parent.get() : nullptr);
|
||||||
Auth().data().requestItemRepaint(_parent);
|
Auth().data().requestItemRepaint(_parent);
|
||||||
|
if (_check) {
|
||||||
|
_check->setActive(active);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemBase::clickHandlerPressedChanged(
|
void ItemBase::clickHandlerPressedChanged(
|
||||||
|
@ -80,8 +142,44 @@ void ItemBase::clickHandlerPressedChanged(
|
||||||
bool pressed) {
|
bool pressed) {
|
||||||
App::pressedLinkItem(pressed ? _parent.get() : nullptr);
|
App::pressedLinkItem(pressed ? _parent.get() : nullptr);
|
||||||
Auth().data().requestItemRepaint(_parent);
|
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<Checkbox>(
|
||||||
|
[this] { Auth().data().requestItemRepaint(_parent); },
|
||||||
|
checkboxStyle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemBase::~ItemBase() = default;
|
||||||
|
|
||||||
void RadialProgressItem::setDocumentLinks(
|
void RadialProgressItem::setDocumentLinks(
|
||||||
not_null<DocumentData*> document) {
|
not_null<DocumentData*> document) {
|
||||||
auto createSaveHandler = [](
|
auto createSaveHandler = [](
|
||||||
|
@ -103,7 +201,7 @@ void RadialProgressItem::clickHandlerActiveChanged(const ClickHandlerPtr &action
|
||||||
if (action == _openl || action == _savel || action == _cancell) {
|
if (action == _openl || action == _savel || action == _cancell) {
|
||||||
if (iconAnimated()) {
|
if (iconAnimated()) {
|
||||||
_a_iconOver.start(
|
_a_iconOver.start(
|
||||||
[this] { Auth().data().requestItemRepaint(_parent); },
|
[this] { Auth().data().requestItemRepaint(parent()); },
|
||||||
active ? 0. : 1.,
|
active ? 0. : 1.,
|
||||||
active ? 1. : 0.,
|
active ? 1. : 0.,
|
||||||
st::msgFileOverDuration);
|
st::msgFileOverDuration);
|
||||||
|
@ -119,7 +217,7 @@ void RadialProgressItem::setLinks(ClickHandlerPtr &&openl, ClickHandlerPtr &&sav
|
||||||
|
|
||||||
void RadialProgressItem::step_radial(TimeMs ms, bool timer) {
|
void RadialProgressItem::step_radial(TimeMs ms, bool timer) {
|
||||||
if (timer) {
|
if (timer) {
|
||||||
Auth().data().requestItemRepaint(_parent);
|
Auth().data().requestItemRepaint(parent());
|
||||||
} else {
|
} else {
|
||||||
_radial->update(dataProgress(), dataFinished(), ms);
|
_radial->update(dataProgress(), dataFinished(), ms);
|
||||||
if (!_radial->animating()) {
|
if (!_radial->animating()) {
|
||||||
|
@ -180,63 +278,6 @@ void Date::paint(Painter &p, const QRect &clip, TextSelection selection, const P
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PhotoVideoCheckbox {
|
|
||||||
public:
|
|
||||||
template <typename UpdateCallback>
|
|
||||||
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<void()> _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(
|
Photo::Photo(
|
||||||
not_null<HistoryItem*> parent,
|
not_null<HistoryItem*> parent,
|
||||||
not_null<PhotoData*> photo)
|
not_null<PhotoData*> photo)
|
||||||
|
@ -262,7 +303,7 @@ int32 Photo::resizeGetHeight(int32 width) {
|
||||||
void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
|
void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
|
||||||
bool good = _data->loaded(), selected = (selection == FullSelection);
|
bool good = _data->loaded(), selected = (selection == FullSelection);
|
||||||
if (!good) {
|
if (!good) {
|
||||||
_data->medium->automaticLoad(_parent);
|
_data->medium->automaticLoad(parent());
|
||||||
good = _data->medium->loaded();
|
good = _data->medium->loaded();
|
||||||
}
|
}
|
||||||
if ((good && !_goodLoaded) || _pix.width() != _width * cIntRetinaFactor()) {
|
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);
|
p.drawPixmap(0, 0, _pix);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected || context->selecting) {
|
if (selected) {
|
||||||
ensureCheckboxCreated();
|
p.fillRect(0, 0, _width, _height, st::overviewPhotoSelectOverlay);
|
||||||
}
|
}
|
||||||
if (_check) {
|
const auto checkDelta = st::overviewCheckSkip + st::overviewCheck.size;
|
||||||
_check->paint(p, context->ms, _width, _height, selected, context->selecting);
|
const auto checkLeft = _width - checkDelta;
|
||||||
}
|
const auto checkTop = _height - checkDelta;
|
||||||
}
|
paintCheckbox(p, { checkLeft, checkTop }, selected, context);
|
||||||
|
|
||||||
void Photo::ensureCheckboxCreated() {
|
|
||||||
if (!_check) _check = std::make_unique<PhotoVideoCheckbox>([this] {
|
|
||||||
Auth().data().requestItemRepaint(_parent);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryTextState Photo::getState(
|
HistoryTextState Photo::getState(
|
||||||
|
@ -321,28 +357,6 @@ HistoryTextState Photo::getState(
|
||||||
return {};
|
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(
|
Video::Video(
|
||||||
not_null<HistoryItem*> parent,
|
not_null<HistoryItem*> parent,
|
||||||
not_null<DocumentData*> video)
|
not_null<DocumentData*> video)
|
||||||
|
@ -367,7 +381,7 @@ int32 Video::resizeGetHeight(int32 width) {
|
||||||
void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
|
void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
|
||||||
bool selected = (selection == FullSelection), thumbLoaded = _data->thumb->loaded();
|
bool selected = (selection == FullSelection), thumbLoaded = _data->thumb->loaded();
|
||||||
|
|
||||||
_data->automaticLoad(_parent);
|
_data->automaticLoad(parent());
|
||||||
bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
|
bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
|
||||||
if (displayLoading) {
|
if (displayLoading) {
|
||||||
ensureRadial();
|
ensureRadial();
|
||||||
|
@ -466,39 +480,12 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected || context->selecting) {
|
const auto checkDelta = st::overviewCheckSkip + st::overviewCheck.size;
|
||||||
ensureCheckboxCreated();
|
const auto checkLeft = _width - checkDelta;
|
||||||
}
|
const auto checkTop = _height - checkDelta;
|
||||||
if (_check) {
|
paintCheckbox(p, { checkLeft, checkTop }, selected, context);
|
||||||
_check->paint(p, context->ms, _width, _height, selected, context->selecting);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video::ensureCheckboxCreated() {
|
|
||||||
if (!_check) _check = std::make_unique<PhotoVideoCheckbox>([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 {
|
float64 Video::dataProgress() const {
|
||||||
return _data->progress();
|
return _data->progress();
|
||||||
}
|
}
|
||||||
|
@ -551,8 +538,6 @@ void Video::updateStatusText() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Video::~Video() = default;
|
|
||||||
|
|
||||||
Voice::Voice(
|
Voice::Voice(
|
||||||
not_null<HistoryItem*> parent,
|
not_null<HistoryItem*> parent,
|
||||||
not_null<DocumentData*> voice,
|
not_null<DocumentData*> voice,
|
||||||
|
@ -582,7 +567,7 @@ void Voice::initDimensions() {
|
||||||
void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
|
void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
|
||||||
bool selected = (selection == FullSelection);
|
bool selected = (selection == FullSelection);
|
||||||
|
|
||||||
_data->automaticLoad(_parent);
|
_data->automaticLoad(parent());
|
||||||
bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
|
bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
|
||||||
|
|
||||||
if (displayLoading) {
|
if (displayLoading) {
|
||||||
|
@ -592,24 +577,26 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool showPause = updateStatusText();
|
bool showPause = updateStatusText();
|
||||||
int32 nameVersion = _parent->fromOriginal()->nameVersion;
|
int32 nameVersion = parent()->fromOriginal()->nameVersion;
|
||||||
if (nameVersion > _nameVersion) {
|
if (nameVersion > _nameVersion) {
|
||||||
updateName();
|
updateName();
|
||||||
}
|
}
|
||||||
bool radial = isRadialAnimation(context->ms);
|
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();
|
const auto inner = rtlrect(
|
||||||
nameright = _st.songPadding.left();
|
_st.songPadding.left(),
|
||||||
nametop = _st.songNameTop;
|
_st.songPadding.top(),
|
||||||
statustop = _st.songStatusTop;
|
_st.songThumbSize,
|
||||||
|
_st.songThumbSize,
|
||||||
if (selected) {
|
_width);
|
||||||
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));
|
|
||||||
if (clip.intersects(inner)) {
|
if (clip.intersects(inner)) {
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
if (selected) {
|
if (selected) {
|
||||||
|
@ -643,8 +630,6 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||||
icon->paintInCenter(p, inner);
|
icon->paintInCenter(p, inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 namewidth = _width - nameleft - nameright;
|
|
||||||
|
|
||||||
if (clip.intersects(rtlrect(nameleft, nametop, namewidth, st::semiboldFont->height, _width))) {
|
if (clip.intersects(rtlrect(nameleft, nametop, namewidth, st::semiboldFont->height, _width))) {
|
||||||
p.setPen(st::historyFileNameInFg);
|
p.setPen(st::historyFileNameInFg);
|
||||||
_name.drawLeftElided(p, nameleft, nametop, namewidth, _width);
|
_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);
|
p.drawTextLeft(nameleft, statustop, _width, _status.text(), statusw);
|
||||||
unreadx += 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.setPen(Qt::NoPen);
|
||||||
p.setBrush(selected ? st::msgFileInBgSelected : st::msgFileInBg);
|
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(
|
HistoryTextState Voice::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
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();
|
const auto inner = rtlrect(
|
||||||
nameright = _st.songPadding.left();
|
_st.songPadding.left(),
|
||||||
nametop = _st.songNameTop;
|
_st.songPadding.top(),
|
||||||
statustop = _st.songStatusTop;
|
_st.songThumbSize,
|
||||||
|
_st.songThumbSize,
|
||||||
auto inner = rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width);
|
_width);
|
||||||
if (inner.contains(point)) {
|
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();
|
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) {
|
if (_status.size() == FileStatusSizeLoaded || _status.size() == FileStatusSizeReady) {
|
||||||
auto textState = _details.getStateLeft(point - QPoint(nameleft, statustop), _width, _width);
|
auto textState = _details.getStateLeft(point - QPoint(nameleft, statustop), _width, _width);
|
||||||
result.link = textState.link;
|
result.link = textState.link;
|
||||||
result.cursor = textState.uponSymbol ? HistoryInTextCursorState : HistoryDefaultCursorState;
|
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 _namel;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -722,18 +739,22 @@ bool Voice::iconAnimated() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const style::RoundCheckbox &Voice::checkboxStyle() const {
|
||||||
|
return st::overviewSmallCheck;
|
||||||
|
}
|
||||||
|
|
||||||
void Voice::updateName() {
|
void Voice::updateName() {
|
||||||
auto version = 0;
|
auto version = 0;
|
||||||
if (auto forwarded = _parent->Get<HistoryMessageForwarded>()) {
|
if (auto forwarded = parent()->Get<HistoryMessageForwarded>()) {
|
||||||
if (_parent->fromOriginal()->isChannel()) {
|
if (parent()->fromOriginal()->isChannel()) {
|
||||||
_name.setText(st::semiboldTextStyle, lng_forwarded_channel(lt_channel, App::peerName(_parent->fromOriginal())), _textNameOptions);
|
_name.setText(st::semiboldTextStyle, lng_forwarded_channel(lt_channel, App::peerName(parent()->fromOriginal())), _textNameOptions);
|
||||||
} else {
|
} 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 {
|
} 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;
|
_nameVersion = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -746,7 +767,7 @@ bool Voice::updateStatusText() {
|
||||||
statusSize = FileStatusSizeLoaded;
|
statusSize = FileStatusSizeLoaded;
|
||||||
using State = Media::Player::State;
|
using State = Media::Player::State;
|
||||||
auto state = Media::Player::mixer()->currentState(AudioMsgId::Type::Voice);
|
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);
|
statusSize = -1 - (state.position / state.frequency);
|
||||||
realDuration = (state.length / state.frequency);
|
realDuration = (state.length / state.frequency);
|
||||||
showPause = (state.state == State::Playing || state.state == State::Resuming || state.state == State::Starting);
|
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) {
|
void Document::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
|
||||||
bool selected = (selection == FullSelection);
|
bool selected = (selection == FullSelection);
|
||||||
|
|
||||||
_data->automaticLoad(_parent);
|
_data->automaticLoad(parent());
|
||||||
bool loaded = _data->loaded() || Local::willStickerImageLoad(_data->mediaKey()), displayLoading = _data->displayLoading();
|
bool loaded = _data->loaded() || Local::willStickerImageLoad(_data->mediaKey()), displayLoading = _data->displayLoading();
|
||||||
|
|
||||||
if (displayLoading) {
|
if (displayLoading) {
|
||||||
|
@ -833,10 +854,6 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
||||||
nametop = _st.songNameTop;
|
nametop = _st.songNameTop;
|
||||||
statustop = _st.songStatusTop;
|
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);
|
auto inner = rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width);
|
||||||
if (clip.intersects(inner)) {
|
if (clip.intersects(inner)) {
|
||||||
p.setPen(Qt::NoPen);
|
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;
|
const auto availwidth = _width - nameleft - nameright;
|
||||||
int namewidth = qMin(availwidth, _name.maxWidth());
|
const auto namewidth = std::min(availwidth, _name.maxWidth());
|
||||||
if (clip.intersects(rtlrect(nameleft, nametop, namewidth, st::semiboldFont->height, _width))) {
|
if (clip.intersects(rtlrect(nameleft, nametop, namewidth, st::semiboldFont->height, _width))) {
|
||||||
p.setPen(st::historyFileNameInFg);
|
p.setPen(st::historyFileNameInFg);
|
||||||
_name.drawLeftElided(p, nameleft, nametop, namewidth, _width);
|
_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.setPen(st::mediaInFg);
|
||||||
p.drawTextLeft(nameleft, datetop, _width, _date, _datew);
|
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(
|
HistoryTextState Document::getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const {
|
HistoryStateRequest request) const {
|
||||||
bool loaded = _data->loaded() || Local::willStickerImageLoad(_data->mediaKey());
|
const auto loaded = _data->loaded()
|
||||||
|
|| Local::willStickerImageLoad(_data->mediaKey());
|
||||||
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, datetop = 0;
|
const auto wthumb = withThumb();
|
||||||
bool wthumb = withThumb();
|
|
||||||
|
|
||||||
if (_data->song()) {
|
if (_data->song()) {
|
||||||
nameleft = _st.songPadding.left() + _st.songThumbSize + _st.songPadding.right();
|
const auto nameleft = _st.songPadding.left() + _st.songThumbSize + _st.songPadding.right();
|
||||||
nameright = _st.songPadding.left();
|
const auto nameright = _st.songPadding.left();
|
||||||
nametop = _st.songNameTop;
|
const auto namewidth = std::min(
|
||||||
statustop = _st.songStatusTop;
|
_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)) {
|
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;
|
return _namel;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nameleft = _st.fileThumbSize + _st.filePadding.right();
|
const auto nameleft = _st.fileThumbSize + _st.filePadding.right();
|
||||||
nametop = st::linksBorder + _st.fileNameTop;
|
const auto nameright = 0;
|
||||||
statustop = st::linksBorder + _st.fileStatusTop;
|
const auto nametop = st::linksBorder + _st.fileNameTop;
|
||||||
datetop = st::linksBorder + _st.fileDateTop;
|
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)) {
|
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 (_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;
|
return _msgl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!_data->loading() && _data->isValid()) {
|
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;
|
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;
|
return _namel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1018,6 +1089,10 @@ HistoryTextState Document::getState(
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const style::RoundCheckbox &Document::checkboxStyle() const {
|
||||||
|
return st::overviewSmallCheck;
|
||||||
|
}
|
||||||
|
|
||||||
float64 Document::dataProgress() const {
|
float64 Document::dataProgress() const {
|
||||||
return _data->progress();
|
return _data->progress();
|
||||||
}
|
}
|
||||||
|
@ -1056,12 +1131,12 @@ bool Document::updateStatusText() {
|
||||||
statusSize = FileStatusSizeLoaded;
|
statusSize = FileStatusSizeLoaded;
|
||||||
using State = Media::Player::State;
|
using State = Media::Player::State;
|
||||||
auto state = Media::Player::mixer()->currentState(AudioMsgId::Type::Song);
|
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);
|
statusSize = -1 - (state.position / state.frequency);
|
||||||
realDuration = (state.length / state.frequency);
|
realDuration = (state.length / state.frequency);
|
||||||
showPause = (state.state == State::Playing || state.state == State::Resuming || state.state == State::Starting);
|
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;
|
showPause = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1082,19 +1157,20 @@ Link::Link(
|
||||||
: ItemBase(parent) {
|
: ItemBase(parent) {
|
||||||
AddComponents(Info::Bit());
|
AddComponents(Info::Bit());
|
||||||
|
|
||||||
auto textWithEntities = _parent->originalText();
|
auto textWithEntities = parent->originalText();
|
||||||
QString mainUrl;
|
QString mainUrl;
|
||||||
|
|
||||||
auto text = textWithEntities.text;
|
auto text = textWithEntities.text;
|
||||||
auto &entities = textWithEntities.entities;
|
const auto &entities = textWithEntities.entities;
|
||||||
int32 from = 0, till = text.size(), lnk = entities.size();
|
int32 from = 0, till = text.size(), lnk = entities.size();
|
||||||
for_const (auto &entity, entities) {
|
for (const auto &entity : entities) {
|
||||||
auto type = entity.type();
|
auto type = entity.type();
|
||||||
if (type != EntityInTextUrl && type != EntityInTextCustomUrl && type != EntityInTextEmail) {
|
if (type != EntityInTextUrl && type != EntityInTextCustomUrl && type != EntityInTextEmail) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto customUrl = entity.data(), entityText = text.mid(entity.offset(), entity.length());
|
const auto customUrl = entity.data();
|
||||||
auto url = customUrl.isEmpty() ? entityText : customUrl;
|
const auto entityText = text.mid(entity.offset(), entity.length());
|
||||||
|
const auto url = customUrl.isEmpty() ? entityText : customUrl;
|
||||||
if (_links.isEmpty()) {
|
if (_links.isEmpty()) {
|
||||||
mainUrl = url;
|
mainUrl = url;
|
||||||
}
|
}
|
||||||
|
@ -1235,8 +1311,11 @@ int32 Link::resizeGetHeight(int32 width) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
|
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;
|
auto selected = (selection == FullSelection);
|
||||||
if (clip.intersects(rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width))) {
|
|
||||||
|
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) {
|
if (_page && _page->photo) {
|
||||||
QPixmap pix;
|
QPixmap pix;
|
||||||
if (_page->photo->medium->loaded()) {
|
if (_page->photo->medium->loaded()) {
|
||||||
|
@ -1246,39 +1325,46 @@ void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const P
|
||||||
} else {
|
} else {
|
||||||
pix = _page->photo->thumb->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small);
|
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()) {
|
} else if (_page && _page->document && !_page->document->thumb->isNull()) {
|
||||||
auto roundRadius = _page->document->isRoundVideo() ? ImageRoundRadius::Ellipse : ImageRoundRadius::Small;
|
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 {
|
} 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) {
|
switch (index) {
|
||||||
case 0: App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::msgFile1Bg, Doc1Corners); break;
|
case 0: fill(st::msgFile1Bg, Doc1Corners); break;
|
||||||
case 1: App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::msgFile2Bg, Doc2Corners); break;
|
case 1: fill(st::msgFile2Bg, Doc2Corners); break;
|
||||||
case 2: App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::msgFile3Bg, Doc3Corners); break;
|
case 2: fill(st::msgFile3Bg, Doc3Corners); break;
|
||||||
case 3: App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::msgFile4Bg, Doc4Corners); break;
|
case 3: fill(st::msgFile4Bg, Doc4Corners); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_letter.isEmpty()) {
|
if (!_letter.isEmpty()) {
|
||||||
p.setFont(st::linksLetterFont);
|
p.setFont(st::linksLetterFont);
|
||||||
p.setPen(st::linksLetterFg);
|
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) {
|
const auto left = st::linksPhotoSize + st::linksPhotoPadding;
|
||||||
App::roundRect(p, rtlrect(0, top, st::linksPhotoSize, st::linksPhotoSize, _width), st::overviewPhotoSelectOverlay, PhotoSelectOverlayCorners);
|
const auto w = _width - left;
|
||||||
st::overviewLinksChecked.paint(p, QPoint(st::linksPhotoSize - st::overviewLinksChecked.width(), top + st::linksPhotoSize - st::overviewLinksChecked.height()), _width);
|
auto top = [&] {
|
||||||
} else if (context->selecting) {
|
if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) {
|
||||||
st::overviewLinksCheck.paint(p, QPoint(st::linksPhotoSize - st::overviewLinksCheck.width(), top + st::linksPhotoSize - st::overviewLinksCheck.height()), _width);
|
return pixTop + (st::linksPhotoSize - st::semiboldFont->height - st::normalFont->height) / 2;
|
||||||
}
|
}
|
||||||
}
|
return st::linksTextTop;
|
||||||
|
}();
|
||||||
if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) {
|
|
||||||
top += (st::linksPhotoSize - st::semiboldFont->height - st::normalFont->height) / 2;
|
|
||||||
} else {
|
|
||||||
top = st::linksTextTop;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.setPen(st::linksTextFg);
|
p.setPen(st::linksTextFg);
|
||||||
p.setFont(st::semiboldFont);
|
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)) {
|
if (!context->isAfterDate && clip.intersects(border)) {
|
||||||
p.fillRect(clip.intersected(border), st::linksBorderFg);
|
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(
|
HistoryTextState Link::getState(
|
||||||
|
@ -1341,6 +1433,10 @@ HistoryTextState Link::getState(
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const style::RoundCheckbox &Link::checkboxStyle() const {
|
||||||
|
return st::overviewSmallCheck;
|
||||||
|
}
|
||||||
|
|
||||||
Link::LinkEntry::LinkEntry(const QString &url, const QString &text)
|
Link::LinkEntry::LinkEntry(const QString &url, const QString &text)
|
||||||
: text(text)
|
: text(text)
|
||||||
, width(st::normalFont->width(text))
|
, width(st::normalFont->width(text))
|
||||||
|
|
|
@ -25,9 +25,15 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "ui/effects/radial_animation.h"
|
#include "ui/effects/radial_animation.h"
|
||||||
#include "styles/style_overview.h"
|
#include "styles/style_overview.h"
|
||||||
|
|
||||||
|
namespace style {
|
||||||
|
struct RoundCheckbox;
|
||||||
|
} // namespace style
|
||||||
|
|
||||||
namespace Overview {
|
namespace Overview {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
|
|
||||||
|
class Checkbox;
|
||||||
|
|
||||||
class PaintContext : public PaintContextBase {
|
class PaintContext : public PaintContextBase {
|
||||||
public:
|
public:
|
||||||
PaintContext(TimeMs ms, bool selecting) : PaintContextBase(ms, selecting), isAfterDate(false) {
|
PaintContext(TimeMs ms, bool selecting) : PaintContextBase(ms, selecting), isAfterDate(false) {
|
||||||
|
@ -66,8 +72,7 @@ public:
|
||||||
|
|
||||||
class ItemBase : public AbstractItem {
|
class ItemBase : public AbstractItem {
|
||||||
public:
|
public:
|
||||||
ItemBase(not_null<HistoryItem*> parent) : _parent(parent) {
|
ItemBase(not_null<HistoryItem*> parent);
|
||||||
}
|
|
||||||
|
|
||||||
void setPosition(int position) {
|
void setPosition(int position) {
|
||||||
_position = position;
|
_position = position;
|
||||||
|
@ -89,9 +94,27 @@ public:
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
|
||||||
void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
|
void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override;
|
||||||
|
|
||||||
|
void invalidateCache() override;
|
||||||
|
|
||||||
|
~ItemBase();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
not_null<HistoryItem*> _parent;
|
not_null<HistoryItem*> 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;
|
int _position = 0;
|
||||||
|
not_null<HistoryItem*> _parent;
|
||||||
|
std::unique_ptr<Checkbox> _check;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -178,8 +201,6 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PhotoVideoCheckbox;
|
|
||||||
|
|
||||||
class Photo : public ItemBase {
|
class Photo : public ItemBase {
|
||||||
public:
|
public:
|
||||||
Photo(
|
Photo(
|
||||||
|
@ -193,18 +214,7 @@ public:
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
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:
|
private:
|
||||||
void ensureCheckboxCreated();
|
|
||||||
|
|
||||||
std::unique_ptr<PhotoVideoCheckbox> _check;
|
|
||||||
|
|
||||||
not_null<PhotoData*> _data;
|
not_null<PhotoData*> _data;
|
||||||
ClickHandlerPtr _link;
|
ClickHandlerPtr _link;
|
||||||
|
|
||||||
|
@ -226,13 +236,6 @@ public:
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
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:
|
protected:
|
||||||
float64 dataProgress() const override;
|
float64 dataProgress() const override;
|
||||||
bool dataFinished() const override;
|
bool dataFinished() const override;
|
||||||
|
@ -240,10 +243,6 @@ protected:
|
||||||
bool iconAnimated() const override;
|
bool iconAnimated() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ensureCheckboxCreated();
|
|
||||||
|
|
||||||
std::unique_ptr<PhotoVideoCheckbox> _check;
|
|
||||||
|
|
||||||
not_null<DocumentData*> _data;
|
not_null<DocumentData*> _data;
|
||||||
StatusText _status;
|
StatusText _status;
|
||||||
|
|
||||||
|
@ -273,6 +272,7 @@ protected:
|
||||||
bool dataFinished() const override;
|
bool dataFinished() const override;
|
||||||
bool dataLoaded() const override;
|
bool dataLoaded() const override;
|
||||||
bool iconAnimated() const override;
|
bool iconAnimated() const override;
|
||||||
|
const style::RoundCheckbox &checkboxStyle() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
not_null<DocumentData*> _data;
|
not_null<DocumentData*> _data;
|
||||||
|
@ -311,6 +311,7 @@ protected:
|
||||||
bool dataFinished() const override;
|
bool dataFinished() const override;
|
||||||
bool dataLoaded() const override;
|
bool dataLoaded() const override;
|
||||||
bool iconAnimated() const override;
|
bool iconAnimated() const override;
|
||||||
|
const style::RoundCheckbox &checkboxStyle() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
not_null<DocumentData*> _data;
|
not_null<DocumentData*> _data;
|
||||||
|
@ -345,6 +346,9 @@ public:
|
||||||
QPoint point,
|
QPoint point,
|
||||||
HistoryStateRequest request) const override;
|
HistoryStateRequest request) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const style::RoundCheckbox &checkboxStyle() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClickHandlerPtr _photol;
|
ClickHandlerPtr _photol;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue