diff --git a/map/bookmark_helpers.cpp b/map/bookmark_helpers.cpp index a989b6ab24..118f496e80 100644 --- a/map/bookmark_helpers.cpp +++ b/map/bookmark_helpers.cpp @@ -511,7 +511,7 @@ bool IsMyCategory(User const & user, kml::CategoryData const & categoryData) return IsMyCategory(user.GetUserId(), categoryData); } -void ExpandBookmarksRectForPreview(m2::RectD & rect) +void ExpandRectForPreview(m2::RectD & rect) { if (!rect.IsValid()) return; diff --git a/map/bookmark_helpers.hpp b/map/bookmark_helpers.hpp index 9bab7f9ef2..85a9763826 100644 --- a/map/bookmark_helpers.hpp +++ b/map/bookmark_helpers.hpp @@ -115,4 +115,4 @@ bool FromCatalog(kml::CategoryData const & categoryData, std::string const & ser bool IsMyCategory(std::string const & userId, kml::CategoryData const & categoryData); bool IsMyCategory(User const & user, kml::CategoryData const & categoryData); -void ExpandBookmarksRectForPreview(m2::RectD & rect); +void ExpandRectForPreview(m2::RectD & rect); diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index 503dd572ec..377ac4492e 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -1812,28 +1812,33 @@ std::string BookmarkManager::GetCategoryFileName(kml::MarkGroupId categoryId) co return category->GetFileName(); } -m2::RectD BookmarkManager::GetCategoryRect(kml::MarkGroupId categoryId) const +m2::RectD BookmarkManager::GetCategoryRect(kml::MarkGroupId categoryId, bool addIconsSize) const { CHECK_THREAD_CHECKER(m_threadChecker, ()); auto const category = GetBmCategory(categoryId); CHECK(category != nullptr, ()); - m2::RectD rect; + m2::RectD categoryRect; if (category->IsEmpty()) - return rect; + return categoryRect; for (auto markId : category->GetUserMarks()) { auto const bookmark = GetBookmark(markId); - rect.Add(bookmark->GetPivot()); + categoryRect.Add(bookmark->GetPivot()); + } + if (addIconsSize && !category->GetUserMarks().empty()) + { + double const coeff = m_maxBookmarkSymbolSize.y / (m_viewport.PixelRect().SizeY() - m_maxBookmarkSymbolSize.y); + categoryRect.Add(categoryRect.LeftTop() + m2::PointD(0.0, categoryRect.SizeY() * coeff)); } for (auto trackId : category->GetUserLines()) { auto const track = GetTrack(trackId); - rect.Add(track->GetLimitRect()); + categoryRect.Add(track->GetLimitRect()); } - return rect; + return categoryRect; } kml::CategoryData const & BookmarkManager::GetCategoryData(kml::MarkGroupId categoryId) const @@ -1952,18 +1957,19 @@ void BookmarkManager::RequestSymbolSizes() symbols.push_back(kLargestBookmarkSymbolName); symbols.push_back(TrackSelectionMark::GetInitialSymbolName()); - m_drapeEngine.SafeCall(&df::DrapeEngine::RequestSymbolsSize, symbols, - [this](std::map && sizes) - { - GetPlatform().RunTask(Platform::Thread::Gui, - [this, sizes = move(sizes)]() mutable - { - auto es = GetEditSession(); - auto infoMark = GetMarkForEdit(m_trackInfoMarkId); - auto const & sz = sizes.at(TrackSelectionMark::GetInitialSymbolName()); - infoMark->SetOffset(m2::PointF(0.0, -sz.y / 2)); - m_maxBookmarkSymbolSize = sizes.at(kLargestBookmarkSymbolName); - }); + m_drapeEngine.SafeCall( + &df::DrapeEngine::RequestSymbolsSize, symbols, + [this](std::map && sizes) { + GetPlatform().RunTask(Platform::Thread::Gui, [this, sizes = std::move(sizes)]() mutable { + auto es = GetEditSession(); + auto infoMark = GetMarkForEdit(m_trackInfoMarkId); + auto const & sz = sizes.at(TrackSelectionMark::GetInitialSymbolName()); + infoMark->SetOffset(m2::PointF(0.0, -sz.y / 2)); + m_maxBookmarkSymbolSize = sizes.at(kLargestBookmarkSymbolName); + m_symbolSizesAcquired = true; + if (m_onSymbolSizesAcquiredFn) + m_onSymbolSizesAcquiredFn(); + }); }); } @@ -2007,6 +2013,16 @@ void BookmarkManager::SetAsyncLoadingCallbacks(AsyncLoadingCallbacks && callback m_asyncLoadingCallbacks = std::move(callbacks); } +bool BookmarkManager::AreSymbolSizesAcquired( + BookmarkManager::OnSymbolSizesAcquiredCallback && callback) +{ + CHECK_THREAD_CHECKER(m_threadChecker, ()); + if (m_symbolSizesAcquired) + return true; + m_onSymbolSizesAcquiredFn = std::move(callback); + return false; +} + void BookmarkManager::Teardown() { m_needTeardown = true; diff --git a/map/bookmark_manager.hpp b/map/bookmark_manager.hpp index 3de16bc48b..56f28ab2b9 100644 --- a/map/bookmark_manager.hpp +++ b/map/bookmark_manager.hpp @@ -62,6 +62,8 @@ public: using ElevationActivePointChangedCallback = std::function; using ElevationMyPositionChangedCallback = std::function; + using OnSymbolSizesAcquiredCallback = std::function; + using AsyncLoadingStartedCallback = std::function; using AsyncLoadingFinishedCallback = std::function; using AsyncLoadingFileCallback = std::function; @@ -185,6 +187,8 @@ public: void SetAsyncLoadingCallbacks(AsyncLoadingCallbacks && callbacks); bool IsAsyncLoadingInProgress() const { return m_asyncLoadingInProgress; } + bool AreSymbolSizesAcquired(OnSymbolSizesAcquiredCallback && callback); + EditSession GetEditSession(); void UpdateViewport(ScreenBase const & screen); @@ -265,7 +269,7 @@ public: std::string GetCategoryName(kml::MarkGroupId categoryId) const; std::string GetCategoryFileName(kml::MarkGroupId categoryId) const; - m2::RectD GetCategoryRect(kml::MarkGroupId categoryId) const; + m2::RectD GetCategoryRect(kml::MarkGroupId categoryId, bool addIconsSize) const; kml::CategoryData const & GetCategoryData(kml::MarkGroupId categoryId) const; kml::MarkGroupId GetCategoryId(std::string const & name) const; @@ -789,6 +793,9 @@ private: ElevationMyPositionChangedCallback m_elevationMyPositionChanged; m2::PointD m_lastElevationMyPosition = m2::PointD::Zero(); + OnSymbolSizesAcquiredCallback m_onSymbolSizesAcquiredFn; + bool m_symbolSizesAcquired = false; + AsyncLoadingCallbacks m_asyncLoadingCallbacks; std::atomic m_needTeardown; size_t m_openedEditSessionsCount = 0; diff --git a/map/framework.cpp b/map/framework.cpp index 55185932ff..ff5529fa27 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -1154,7 +1154,7 @@ void Framework::ShowTrack(kml::TrackId trackId) return; auto rect = track->GetLimitRect(); - ExpandBookmarksRectForPreview(rect); + ExpandRectForPreview(rect); StopLocationFollow(); ShowRect(rect); @@ -1169,11 +1169,11 @@ void Framework::ShowTrack(kml::TrackId trackId) void Framework::ShowBookmarkCategory(kml::MarkGroupId categoryId, bool animation) { auto & bm = GetBookmarkManager(); - auto rect = bm.GetCategoryRect(categoryId); + auto rect = bm.GetCategoryRect(categoryId, true /* addIconsSize */); if (!rect.IsValid()) return; - ExpandBookmarksRectForPreview(rect); + ExpandRectForPreview(rect); StopLocationFollow(); ShowRect(rect, -1 /* maxScale */, animation); diff --git a/qt/mainwindow.cpp b/qt/mainwindow.cpp index a69df22fc1..ea30bd469e 100644 --- a/qt/mainwindow.cpp +++ b/qt/mainwindow.cpp @@ -183,10 +183,8 @@ MainWindow::MainWindow(Framework & framework, bool apiOpenGLES3, if (m_screenshotMode) { - QSize size(width, height); - size.setHeight(size.height() + statusBar()->height()); - m_pDrawWidget->setFixedSize(size); - setFixedSize(size); + m_pDrawWidget->setFixedSize(width, height); + setFixedSize(width, height + statusBar()->height()); } QObject::connect(m_pDrawWidget, SIGNAL(BeforeEngineCreation()), this, SLOT(OnBeforeEngineCreation())); diff --git a/qt/screenshoter.cpp b/qt/screenshoter.cpp index 43ffe68f8a..ec7c416357 100644 --- a/qt/screenshoter.cpp +++ b/qt/screenshoter.cpp @@ -114,7 +114,7 @@ bool ParseRectsStr(std::string const & rectsStr, std::list & rects) namespace qt { Screenshoter::Screenshoter(ScreenshotParams const & screenshotParams, Framework & framework, - QWidget * widget) + QOpenGLWidget * widget) : m_screenshotParams(screenshotParams) , m_framework(framework) , m_widget(widget) @@ -159,13 +159,19 @@ void Screenshoter::ProcessNextItem() switch (m_screenshotParams.m_mode) { - case ScreenshotParams::Mode::KmlFiles: return ProcessNextKml(); + case ScreenshotParams::Mode::KmlFiles: return PrepareToProcessKml(); case ScreenshotParams::Mode::Points: return ProcessNextPoint(); case ScreenshotParams::Mode::Rects: return ProcessNextRect(); } UNREACHABLE(); } +void Screenshoter::PrepareToProcessKml() +{ + if (m_framework.GetBookmarkManager().AreSymbolSizesAcquired([this] { ProcessNextKml(); })) + ProcessNextKml(); +} + void Screenshoter::ProcessNextKml() { std::string const postfix = "_" + languages::GetCurrentNorm(); @@ -203,11 +209,6 @@ void Screenshoter::ProcessNextKml() ChangeState(State::WaitPosition); auto const newCatId = bookmarkManager.GetBmGroupsIdList().front(); - - auto rect = bookmarkManager.GetCategoryRect(newCatId); - ExpandBookmarksRectForPreview(rect); - CHECK(rect.IsValid(), ()); - m_framework.ShowBookmarkCategory(newCatId, false); WaitPosition(); } @@ -348,10 +349,14 @@ void Screenshoter::SaveScreenshot() return; } - QPixmap pixmap(QSize(m_screenshotParams.m_width, m_screenshotParams.m_height)); - m_widget->render(&pixmap, QPoint(), QRegion(m_widget->geometry())); - if (!pixmap.save(QString::fromStdString(base::JoinPath(m_screenshotParams.m_dstPath, m_nextScreenshotName + ".png")), - nullptr, 100)) + QSize screenshotSize(m_screenshotParams.m_width, m_screenshotParams.m_height); + QImage framebuffer = m_widget->grabFramebuffer(); + ASSERT_EQUAL(framebuffer.width() % screenshotSize.width(), 0, ()); + ASSERT_EQUAL(framebuffer.height() % screenshotSize.height(), 0, ()); + QImage screenshot = framebuffer.scaled(screenshotSize); + if (!screenshot.save(QString::fromStdString(base::JoinPath(m_screenshotParams.m_dstPath, + m_nextScreenshotName + ".png")), + "PNG", 100)) { ChangeState(State::FileError); return; diff --git a/qt/screenshoter.hpp b/qt/screenshoter.hpp index 7d289d9cf8..4a9201ac76 100644 --- a/qt/screenshoter.hpp +++ b/qt/screenshoter.hpp @@ -1,12 +1,12 @@ #pragma once -#include "drape_frontend/visual_params.hpp" - #include "storage/storage_defines.hpp" +#include "drape_frontend/visual_params.hpp" + #include "geometry/rect2d.hpp" -#include +#include #include #include @@ -43,7 +43,8 @@ struct ScreenshotParams class Screenshoter { public: - Screenshoter(ScreenshotParams const & screenshotParams, Framework & framework, QWidget * widget); + Screenshoter(ScreenshotParams const & screenshotParams, Framework & framework, + QOpenGLWidget * widget); void Start(); @@ -67,6 +68,7 @@ private: }; void ProcessNextItem(); + void PrepareToProcessKml(); void ProcessNextKml(); void ProcessNextRect(); void ProcessNextPoint(); @@ -91,7 +93,7 @@ private: State m_state = State::NotStarted; ScreenshotParams m_screenshotParams; Framework & m_framework; - QWidget * m_widget; + QOpenGLWidget * m_widget; std::list m_filesToProcess; std::list> m_pointsToProcess; std::list m_rectsToProcess;