Allow media reordering when sending an album.

This commit is contained in:
John Preston 2017-12-25 22:26:08 +03:00
parent 5d18d7c813
commit 1fc7dabd3e
9 changed files with 832 additions and 202 deletions

View File

@ -2015,15 +2015,6 @@ namespace {
}
}
int msgRadius() {
static int MsgRadius = ([]() {
return st::historyMessageRadius;
auto minMsgHeight = (st::msgPadding.top() + st::msgFont->height + st::msgPadding.bottom());
return minMsgHeight / 2;
})();
return MsgRadius;
}
void createMaskCorners() {
QImage mask[4];
prepareCorners(SmallMaskCorners, st::buttonRadius, QColor(255, 255, 255), nullptr, mask);
@ -2031,7 +2022,7 @@ namespace {
::cornersMaskSmall[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied);
::cornersMaskSmall[i].setDevicePixelRatio(cRetinaFactor());
}
prepareCorners(LargeMaskCorners, msgRadius(), QColor(255, 255, 255), nullptr, mask);
prepareCorners(LargeMaskCorners, st::historyMessageRadius, QColor(255, 255, 255), nullptr, mask);
for (int i = 0; i < 4; ++i) {
::cornersMaskLarge[i] = mask[i].convertToFormat(QImage::Format_ARGB32_Premultiplied);
::cornersMaskLarge[i].setDevicePixelRatio(cRetinaFactor());
@ -2045,12 +2036,12 @@ namespace {
prepareCorners(StickerCorners, st::dateRadius, st::msgServiceBg);
prepareCorners(StickerSelectedCorners, st::dateRadius, st::msgServiceBgSelected);
prepareCorners(SelectedOverlaySmallCorners, st::buttonRadius, st::msgSelectOverlay);
prepareCorners(SelectedOverlayLargeCorners, msgRadius(), st::msgSelectOverlay);
prepareCorners(SelectedOverlayLargeCorners, st::historyMessageRadius, st::msgSelectOverlay);
prepareCorners(DateCorners, st::dateRadius, st::msgDateImgBg);
prepareCorners(DateSelectedCorners, st::dateRadius, st::msgDateImgBgSelected);
prepareCorners(InShadowCorners, msgRadius(), st::msgInShadow);
prepareCorners(InSelectedShadowCorners, msgRadius(), st::msgInShadowSelected);
prepareCorners(ForwardCorners, msgRadius(), st::historyForwardChooseBg);
prepareCorners(InShadowCorners, st::historyMessageRadius, st::msgInShadow);
prepareCorners(InSelectedShadowCorners, st::historyMessageRadius, st::msgInShadowSelected);
prepareCorners(ForwardCorners, st::historyMessageRadius, st::historyForwardChooseBg);
prepareCorners(MediaviewSaveCorners, st::mediaviewControllerRadius, st::mediaviewSaveMsgBg);
prepareCorners(EmojiHoverCorners, st::buttonRadius, st::emojiPanHover);
prepareCorners(StickerHoverCorners, st::buttonRadius, st::emojiPanHover);
@ -2062,10 +2053,10 @@ namespace {
prepareCorners(Doc3Corners, st::buttonRadius, st::msgFile3Bg);
prepareCorners(Doc4Corners, st::buttonRadius, st::msgFile4Bg);
prepareCorners(MessageInCorners, msgRadius(), st::msgInBg, &st::msgInShadow);
prepareCorners(MessageInSelectedCorners, msgRadius(), st::msgInBgSelected, &st::msgInShadowSelected);
prepareCorners(MessageOutCorners, msgRadius(), st::msgOutBg, &st::msgOutShadow);
prepareCorners(MessageOutSelectedCorners, msgRadius(), st::msgOutBgSelected, &st::msgOutShadowSelected);
prepareCorners(MessageInCorners, st::historyMessageRadius, st::msgInBg, &st::msgInShadow);
prepareCorners(MessageInSelectedCorners, st::historyMessageRadius, st::msgInBgSelected, &st::msgInShadowSelected);
prepareCorners(MessageOutCorners, st::historyMessageRadius, st::msgOutBg, &st::msgOutShadow);
prepareCorners(MessageOutSelectedCorners, st::historyMessageRadius, st::msgOutBgSelected, &st::msgOutShadowSelected);
}
void createCorners() {
@ -2663,7 +2654,7 @@ namespace {
QImage images[4];
switch (radius) {
case ImageRoundRadius::Small: prepareCorners(SmallMaskCorners, st::buttonRadius, bg, nullptr, images); break;
case ImageRoundRadius::Large: prepareCorners(LargeMaskCorners, msgRadius(), bg, nullptr, images); break;
case ImageRoundRadius::Large: prepareCorners(LargeMaskCorners, st::historyMessageRadius, bg, nullptr, images); break;
default: p.fillRect(x, y, w, h, bg); return;
}

File diff suppressed because it is too large Load Diff

View File

@ -72,7 +72,6 @@ protected:
private:
class AlbumPreview;
struct AlbumThumb;
void initSendWay();
void initPreview(rpl::producer<int> desiredPreviewHeight);
@ -86,6 +85,7 @@ private:
void prepareSingleFilePreview();
void prepareAlbumPreview();
void applyAlbumOrder();
void send(bool ctrlShiftEnter = false);
void captionResized();

View File

@ -554,7 +554,7 @@ ListWidget::ListWidget(
, _migrated(_controller->migrated())
, _type(_controller->section().mediaType())
, _slice(sliceKey(_universalAroundId)) {
setAttribute(Qt::WA_MouseTracking);
setMouseTracking(true);
start();
}

View File

@ -120,11 +120,13 @@ void PrepareAlbum(PreparedList &result, int previewWidth) {
}
if (waiting > 0) {
semaphore.acquire(waiting);
const auto badIt = ranges::find(
result.files,
PreparedFile::AlbumType::None,
[](const PreparedFile &file) { return file.type; });
result.albumIsPossible = (badIt == result.files.end());
if (result.albumIsPossible) {
const auto badIt = ranges::find(
result.files,
PreparedFile::AlbumType::None,
[](const PreparedFile &file) { return file.type; });
result.albumIsPossible = (badIt == result.files.end());
}
}
}
@ -269,5 +271,21 @@ PreparedList PrepareMediaFromImage(
return result;
}
PreparedList PreparedList::Reordered(
PreparedList &&list,
std::vector<int> order) {
Expects(list.error == PreparedList::Error::None);
Expects(list.files.size() == order.size());
auto result = PreparedList(list.error, list.errorData);
result.albumIsPossible = list.albumIsPossible;
result.allFilesForCompress = list.allFilesForCompress;
result.files.reserve(list.files.size());
for (auto index : order) {
result.files.push_back(std::move(list.files[index]));
}
return result;
}
} // namespace Storage

View File

@ -68,6 +68,9 @@ struct PreparedList {
: error(error)
, errorData(errorData) {
}
static PreparedList Reordered(
PreparedList &&list,
std::vector<int> order);
Error error = Error::None;
QString errorData;

View File

@ -454,9 +454,11 @@ std::vector<float64> ComplexLayouter::CropRatios(
return ranges::view::all(
ratios
) | ranges::view::transform([&](float64 ratio) {
constexpr auto kMaxRatio = 2.75;
constexpr auto kMinRatio = 0.6667;
return (averageRatio > 1.1)
? snap(ratio, 1., 1.7)
: snap(ratio, 0.66667, 1.);
? snap(ratio, 1., kMaxRatio)
: snap(ratio, kMinRatio, 1.);
}) | ranges::to_vector;
}

View File

@ -191,24 +191,16 @@ void prepareCircle(QImage &img) {
p.drawPixmap(0, 0, mask);
}
void prepareRound(QImage &image, ImageRoundRadius radius, RectParts corners) {
if (!static_cast<int>(corners)) {
return;
} else if (radius == ImageRoundRadius::Ellipse) {
Assert((corners & RectPart::AllCorners) == RectPart::AllCorners);
prepareCircle(image);
void prepareRound(
QImage &image,
QImage *cornerMasks,
RectParts corners,
QRect target) {
if (target.isNull()) {
target = QRect(QPoint(), image.size());
} else {
Assert(QRect(QPoint(), image.size()).contains(target));
}
Assert(!image.isNull());
image.setDevicePixelRatio(cRetinaFactor());
image = std::move(image).convertToFormat(QImage::Format_ARGB32_Premultiplied);
Assert(!image.isNull());
auto masks = App::cornersMask(radius);
prepareRound(image, masks, corners);
}
void prepareRound(QImage &image, QImage *cornerMasks, RectParts corners) {
auto cornerWidth = cornerMasks[0].width();
auto cornerHeight = cornerMasks[0].height();
auto imageWidth = image.width();
@ -222,10 +214,10 @@ void prepareRound(QImage &image, QImage *cornerMasks, RectParts corners) {
Assert(image.bytesPerLine() == (imageIntsPerLine << 2));
auto ints = reinterpret_cast<uint32*>(image.bits());
auto intsTopLeft = ints;
auto intsTopRight = ints + imageWidth - cornerWidth;
auto intsBottomLeft = ints + (imageHeight - cornerHeight) * imageWidth;
auto intsBottomRight = ints + (imageHeight - cornerHeight + 1) * imageWidth - cornerWidth;
auto intsTopLeft = ints + target.x() + target.y() * imageWidth;
auto intsTopRight = ints + target.x() + target.width() - cornerWidth + target.y() * imageWidth;
auto intsBottomLeft = ints + target.x() + (target.y() + target.height() - cornerHeight) * imageWidth;
auto intsBottomRight = ints + target.x() + target.width() - cornerWidth + (target.y() + target.height() - cornerHeight) * imageWidth;
auto maskCorner = [imageWidth, imageHeight, imageIntsPerPixel, imageIntsPerLine](uint32 *imageInts, const QImage &mask) {
auto maskWidth = mask.width();
auto maskHeight = mask.height();
@ -254,6 +246,28 @@ void prepareRound(QImage &image, QImage *cornerMasks, RectParts corners) {
if (corners & RectPart::BottomRight) maskCorner(intsBottomRight, cornerMasks[3]);
}
void prepareRound(
QImage &image,
ImageRoundRadius radius,
RectParts corners,
QRect target) {
if (!static_cast<int>(corners)) {
return;
} else if (radius == ImageRoundRadius::Ellipse) {
Assert((corners & RectPart::AllCorners) == RectPart::AllCorners);
Assert(target.isNull());
prepareCircle(image);
}
Assert(!image.isNull());
image.setDevicePixelRatio(cRetinaFactor());
image = std::move(image).convertToFormat(QImage::Format_ARGB32_Premultiplied);
Assert(!image.isNull());
auto masks = App::cornersMask(radius);
prepareRound(image, masks, corners, target);
}
QImage prepareColored(style::color add, QImage image) {
auto format = image.format();
if (format != QImage::Format_RGB32 && format != QImage::Format_ARGB32_Premultiplied) {

View File

@ -195,8 +195,7 @@ inline bool operator!=(const WebFileImageLocation &a, const WebFileImageLocation
namespace Images {
QImage prepareBlur(QImage image);
void prepareRound(QImage &image, ImageRoundRadius radius, RectParts corners = RectPart::AllCorners);
void prepareRound(QImage &image, QImage *cornerMasks, RectParts corners = RectPart::AllCorners);
void prepareRound(QImage &image, ImageRoundRadius radius, RectParts corners = RectPart::AllCorners, QRect target = QRect());
void prepareCircle(QImage &image);
QImage prepareColored(style::color add, QImage image);
QImage prepareOpaque(QImage image);