mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Handle clicks on location areas in stories.
This commit is contained in:
parent
ebe2088561
commit
066dbfe8fc
6 changed files with 89 additions and 2 deletions
|
@ -33,8 +33,11 @@ using UpdateFlag = StoryUpdate::Flag;
|
|||
|
||||
[[nodiscard]] StoryArea ParseArea(const MTPMediaAreaCoordinates &area) {
|
||||
const auto &data = area.data();
|
||||
const auto center = QPointF(data.vx().v, data.vy().v);
|
||||
const auto size = QSizeF(data.vw().v, data.vh().v);
|
||||
const auto corner = center - QPointF(size.width(), size.height()) / 2.;
|
||||
return {
|
||||
.geometry = { data.vx().v, data.vy().v, data.vw().v, data.vh().v },
|
||||
.geometry = { corner / 100., size / 100. },
|
||||
.rotation = data.vrotation().v,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -118,6 +118,19 @@ struct SameDayRange {
|
|||
return { QString() + QChar(10084) };
|
||||
}
|
||||
|
||||
[[nodiscard]] QPoint Rotated(QPoint point, QPoint origin, float64 angle) {
|
||||
if (std::abs(angle) < 1.) {
|
||||
return point;
|
||||
}
|
||||
const auto alpha = angle / 180. * M_PI;
|
||||
const auto acos = cos(alpha);
|
||||
const auto asin = sin(alpha);
|
||||
point -= origin;
|
||||
return origin + QPoint(
|
||||
int(base::SafeRound(acos * point.x() - asin * point.y())),
|
||||
int(base::SafeRound(asin * point.x() + acos * point.y())));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class Controller::PhotoPlayback final {
|
||||
|
@ -531,11 +544,30 @@ void Controller::initLayout() {
|
|||
.nameBoundingRect = nameBoundingRect(right, false),
|
||||
.nameFontSize = nameFontSize,
|
||||
};
|
||||
|
||||
if (!_locationAreas.empty()) {
|
||||
rebuildLocationAreas(layout);
|
||||
}
|
||||
return layout;
|
||||
});
|
||||
}
|
||||
|
||||
void Controller::rebuildLocationAreas(const Layout &layout) const {
|
||||
Expects(_locations.size() == _locationAreas.size());
|
||||
|
||||
const auto origin = layout.content.topLeft();
|
||||
const auto scale = layout.content.size();
|
||||
for (auto i = 0, count = int(_locations.size()); i != count; ++i) {
|
||||
auto &area = _locationAreas[i];
|
||||
const auto &general = _locations[i].area.geometry;
|
||||
area.geometry = QRect(
|
||||
int(base::SafeRound(general.x() * scale.width())),
|
||||
int(base::SafeRound(general.y() * scale.height())),
|
||||
int(base::SafeRound(general.width() * scale.width())),
|
||||
int(base::SafeRound(general.height() * scale.height()))
|
||||
).translated(origin);
|
||||
}
|
||||
}
|
||||
|
||||
Data::Story *Controller::story() const {
|
||||
if (!_session) {
|
||||
return nullptr;
|
||||
|
@ -918,6 +950,14 @@ bool Controller::changeShown(Data::Story *story) {
|
|||
Data::Stories::Polling::Viewer);
|
||||
}
|
||||
_liked = false;
|
||||
const auto &locations = story
|
||||
? story->locations()
|
||||
: std::vector<Data::StoryLocation>();
|
||||
if (_locations != locations) {
|
||||
_locations = locations;
|
||||
_locationAreas.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1082,6 +1122,32 @@ void Controller::updatePlayback(const Player::TrackState &state) {
|
|||
}
|
||||
}
|
||||
|
||||
ClickHandlerPtr Controller::lookupLocationHandler(QPoint point) const {
|
||||
const auto &layout = _layout.current();
|
||||
if (_locations.empty() || !layout) {
|
||||
return nullptr;
|
||||
} else if (_locationAreas.empty()) {
|
||||
_locationAreas = _locations | ranges::views::transform([](
|
||||
const Data::StoryLocation &location) {
|
||||
return LocationArea{
|
||||
.rotation = location.area.rotation,
|
||||
.handler = std::make_shared<LocationClickHandler>(
|
||||
location.point),
|
||||
};
|
||||
}) | ranges::to_vector;
|
||||
rebuildLocationAreas(*layout);
|
||||
}
|
||||
|
||||
for (const auto &area : _locationAreas) {
|
||||
const auto center = area.geometry.center();
|
||||
const auto angle = -area.rotation;
|
||||
if (area.geometry.contains(Rotated(point, center, angle))) {
|
||||
return area.handler;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Controller::maybeMarkAsRead(const Player::TrackState &state) {
|
||||
const auto length = state.length;
|
||||
const auto position = Player::IsStoppedAtEnd(state.state)
|
||||
|
|
|
@ -135,6 +135,7 @@ public:
|
|||
void ready();
|
||||
|
||||
void updateVideoPlayback(const Player::TrackState &state);
|
||||
[[nodiscard]] ClickHandlerPtr lookupLocationHandler(QPoint point) const;
|
||||
|
||||
[[nodiscard]] bool subjumpAvailable(int delta) const;
|
||||
[[nodiscard]] bool subjumpFor(int delta);
|
||||
|
@ -188,6 +189,11 @@ private:
|
|||
return peerId != 0;
|
||||
}
|
||||
};
|
||||
struct LocationArea {
|
||||
QRect geometry;
|
||||
float64 rotation = 0.;
|
||||
ClickHandlerPtr handler;
|
||||
};
|
||||
class PhotoPlayback;
|
||||
class Unsupported;
|
||||
|
||||
|
@ -203,6 +209,7 @@ private:
|
|||
void updateContentFaded();
|
||||
void updatePlayingAllowed();
|
||||
void setPlayingAllowed(bool allowed);
|
||||
void rebuildLocationAreas(const Layout &layout) const;
|
||||
|
||||
void hideSiblings();
|
||||
void showSiblings(not_null<Main::Session*> session);
|
||||
|
@ -275,6 +282,9 @@ private:
|
|||
bool _started = false;
|
||||
bool _viewed = false;
|
||||
|
||||
std::vector<Data::StoryLocation> _locations;
|
||||
mutable std::vector<LocationArea> _locationAreas;
|
||||
|
||||
std::vector<CachedSource> _cachedSourcesList;
|
||||
int _cachedSourceIndex = -1;
|
||||
bool _showingUnreadSources = false;
|
||||
|
|
|
@ -59,6 +59,10 @@ void View::updatePlayback(const Player::TrackState &state) {
|
|||
_controller->updateVideoPlayback(state);
|
||||
}
|
||||
|
||||
ClickHandlerPtr View::lookupLocationHandler(QPoint point) const {
|
||||
return _controller->lookupLocationHandler(point);
|
||||
}
|
||||
|
||||
bool View::subjumpAvailable(int delta) const {
|
||||
return _controller->subjumpAvailable(delta);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ public:
|
|||
void showFullCaption();
|
||||
|
||||
void updatePlayback(const Player::TrackState &state);
|
||||
[[nodiscard]] ClickHandlerPtr lookupLocationHandler(QPoint point) const;
|
||||
|
||||
[[nodiscard]] bool subjumpAvailable(int delta) const;
|
||||
[[nodiscard]] bool subjumpFor(int delta) const;
|
||||
|
|
|
@ -5666,6 +5666,9 @@ void OverlayWidget::updateOver(QPoint pos) {
|
|||
const auto point = pos - QPoint(_groupThumbsLeft, _groupThumbsTop);
|
||||
lnk = _groupThumbs->getState(point);
|
||||
lnkhost = this;
|
||||
} else if (_stories) {
|
||||
lnk = _stories->lookupLocationHandler(pos);
|
||||
lnkhost = this;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue