| 215 | } |
| 216 | |
| 217 | void OverlayTree::InsertHandle(ref_ptr<OverlayHandle> handle, int currentRank, |
| 218 | ref_ptr<OverlayHandle> const & parentOverlay) |
| 219 | { |
| 220 | /// @todo Fires when updating country (delete-add) ?! |
| 221 | // ASSERT(handle->GetOverlayID().IsValid(), ()); |
| 222 | ASSERT(IsNeedUpdate(), ()); |
| 223 | |
| 224 | #ifdef DEBUG_OVERLAYS_OUTPUT |
| 225 | std::string str = handle->GetOverlayDebugInfo(); |
| 226 | if (!str.empty()) |
| 227 | LOG(LINFO, (str)); |
| 228 | #endif |
| 229 | |
| 230 | ScreenBase const & modelView = GetModelView(); |
| 231 | ASSERT(handle->IsCachingEnabled(), ()); |
| 232 | m2::RectD const pixelRect = handle->GetExtendedPixelRect(modelView); |
| 233 | |
| 234 | if (!m_isDisplacementEnabled) |
| 235 | { |
| 236 | m_handlesCache.insert(handle); |
| 237 | m_overlayIdCache[handle->GetOverlayID()].push_back(handle); |
| 238 | TBase::Add(handle, pixelRect); |
| 239 | return; |
| 240 | } |
| 241 | |
| 242 | TOverlayContainer rivals; |
| 243 | HandleComparator comparator(true /* enableMask */); |
| 244 | |
| 245 | // Find elements that already on OverlayTree and it's pixel rect |
| 246 | // intersect with handle pixel rect ("Intersected elements"). |
| 247 | ForEachInRect(pixelRect, [&](ref_ptr<OverlayHandle> const & h) |
| 248 | { |
| 249 | bool const isParent = (h == parentOverlay) || (h->GetOverlayID() == handle->GetOverlayID() && |
| 250 | h->GetOverlayRank() < handle->GetOverlayRank()); |
| 251 | if (!isParent && handle->IsIntersect(modelView, h)) |
| 252 | rivals.push_back(h); |
| 253 | }); |
| 254 | |
| 255 | // If handle is bound to its parent, parent's handle will be used. |
| 256 | ref_ptr<OverlayHandle> handleToCompare = handle; |
| 257 | bool const boundToParent = (parentOverlay != nullptr && handle->IsBound()); |
| 258 | if (boundToParent) |
| 259 | handleToCompare = parentOverlay; |
| 260 | |
| 261 | bool const selected = |
| 262 | m_selectedFeatureID.IsValid() && handleToCompare->GetOverlayID().m_featureId == m_selectedFeatureID; |
| 263 | |
| 264 | if (!selected) |
| 265 | { |
| 266 | // In this loop we decide which element must be visible. |
| 267 | // If input element "handle" has more priority than all "Intersected elements", |
| 268 | // then we remove all "Intersected elements" and insert input element "handle". |
| 269 | // But if some of already inserted elements have more priority, then we don't insert "handle". |
| 270 | for (auto const & rivalHandle : rivals) |
| 271 | { |
| 272 | bool reject = m_selectedFeatureID.IsValid() && rivalHandle->GetOverlayID().m_featureId == m_selectedFeatureID; |
| 273 | if (!reject) |
| 274 | { |
nothing calls this directly
no test coverage detected