//-------------------------------------------------------------------------- void LLScreenChannel::hideToast(const LLUUID& notification_id) { std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), notification_id); if(mToastList.end() != it) { LLToast* toast = it->getToast(); if (toast) { toast->hide(); } else { llwarns << "Attempt to hide a deleted toast." << llendl; } } }
//-------------------------------------------------------------------------- void LLScreenChannel::showToastsBottom() { LLRect toast_rect; S32 bottom = getRect().mBottom - gFloaterView->getRect().mBottom; S32 toast_margin = 0; std::vector<ToastElem>::reverse_iterator it; updateRect(); LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get()); // <FS:Ansariel> Show toasts in front of other floaters BOOL toasts_in_front = gSavedSettings.getBOOL("FSShowToastsInFront"); // Use a local variable instead of mToastList. // mToastList can be modified during recursive calls and then all iteratos will be invalidated. std::vector<ToastElem> vToastList( mToastList ); for(it = vToastList.rbegin(); it != vToastList.rend(); ++it) { if(it != vToastList.rbegin()) { LLToast* toast = (it-1)->getToast(); if (!toast) { llwarns << "Attempt to display a deleted toast." << llendl; return; } bottom = toast->getRect().mTop - toast->getTopPad(); toast_margin = gSavedSettings.getS32("ToastGap"); } LLToast* toast = it->getToast(); if(!toast) { llwarns << "Attempt to display a deleted toast." << llendl; return; } toast_rect = toast->getRect(); toast_rect.setOriginAndSize(getRect().mRight - toast_rect.getWidth(), bottom + toast_margin, toast_rect.getWidth(), toast_rect.getHeight()); toast->setRect(toast_rect); if(floater && floater->overlapsScreenChannel()) { if(it == vToastList.rbegin()) { // move first toast above docked floater S32 shift = floater->getRect().getHeight(); if(floater->getDockControl()) { shift += floater->getDockControl()->getTongueHeight(); } toast->translate(0, shift); } LLRect channel_rect = getChannelRect(); // don't show toasts if there is not enough space if(toast_rect.mTop > channel_rect.mTop) { break; } } bool stop_showing_toasts = toast->getRect().mTop > getRect().mTop; if(!stop_showing_toasts) { if( it != vToastList.rend()-1) { S32 toast_top = toast->getRect().mTop + gSavedSettings.getS32("ToastGap"); stop_showing_toasts = toast_top > getRect().mTop; } } // at least one toast should be visible if(it == vToastList.rbegin()) { stop_showing_toasts = false; } if(stop_showing_toasts) break; if( !toast->getVisible() ) { // HACK // EXT-2653: it is necessary to prevent overlapping for secondary showed toasts toast->setVisible(TRUE); } // <FS:Ansariel> Show toasts in front of other floaters //if(!toast->hasFocus()) if(!toast->hasFocus() && !toasts_in_front) // </FS:Ansariel> Show toasts in front of other floaters { // Fixing Z-order of toasts (EXT-4862) // Next toast will be positioned under this one. gFloaterView->sendChildToBack(toast); } } // Dismiss toasts we don't have space for (STORM-391). if(it != vToastList.rend()) { mHiddenToastsNum = 0; for(; it != vToastList.rend(); it++) { LLToast* toast = it->getToast(); if (toast) { toast->hide(); } } } }