static LLPanel *childGetVisiblePanelWithHelp(LLView *parent) { LLView *child; // look through immediate children first for an active panel with help for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child)) { // do we have a panel with a help topic? LLPanel *panel = dynamic_cast<LLPanel *>(child); if (panel && panel->getVisible() && !panel->getHelpTopic().empty()) { return panel; } } // then try a bit harder and recurse through all children for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child)) { if (child->getVisible()) { LLPanel* panel = ::childGetVisiblePanelWithHelp(child); if (panel) { return panel; } } } // couldn't find any active panels with a help topic string return NULL; }
// Checked: 2010-02-28 (RLVa-1.4.0a) | Added: RLVa-1.2.0a void RlvUIEnabler::onToggleShowMinimap() { bool fEnable = !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWMINIMAP); // Start or stop filtering showing the mini-map floater if (!fEnable) addGenericFloaterFilter("mini_map"); else removeGenericFloaterFilter("mini_map"); // Hide the mini-map floater if it's currently visible (or restore it if it was previously visible) static bool fPrevVisibile = false; if ( (!fEnable) && ((fPrevVisibile = LLFloaterReg::instanceVisible("mini_map"))) ) LLFloaterReg::hideInstance("mini_map"); else if ( (fEnable) && (fPrevVisibile) ) LLFloaterReg::showInstance("mini_map"); // Break/reestablish the visibility connection for the nearby people panel embedded minimap instance LLPanel* pPeoplePanel = LLFloaterSidePanelContainer::getPanel("people", "panel_people"); LLPanel* pNetMapPanel = (pPeoplePanel) ? pPeoplePanel->getChild<LLPanel>("minimaplayout", TRUE) : NULL; //AO: firestorm specific RLV_ASSERT( (pPeoplePanel) && (pNetMapPanel) ); if (pNetMapPanel) { pNetMapPanel->setMakeVisibleControlVariable( (fEnable) ? gSavedSettings.getControl("ShowRadarMinimap").get() : NULL); // Reestablishing the visiblity connection will show the panel if needed so we only need to take care of hiding it when needed if ( (!fEnable) && (pNetMapPanel->getVisible()) ) pNetMapPanel->setVisible(false); } // Break/reestablish the visibility connection for the radar panel embedded minimap instance LLFloater* pRadarFloater = LLFloaterReg::getInstance("fs_radar"); LLPanel* pRadarNetMapPanel = (pRadarFloater) ? pRadarFloater->getChild<LLPanel>("minimaplayout", TRUE) : NULL; //AO: firestorm specific RLV_ASSERT( (pRadarFloater) && (pRadarNetMapPanel) ); if (pRadarNetMapPanel) { pRadarNetMapPanel->setMakeVisibleControlVariable( (fEnable) ? gSavedSettings.getControl("ShowRadarMinimap").get() : NULL); // Reestablishing the visiblity connection will show the panel if needed so we only need to take care of hiding it when needed if ( (!fEnable) && (pRadarNetMapPanel->getVisible()) ) pRadarNetMapPanel->setVisible(false); } }
//----------------------------------------------------------------------------- // rebuild() //----------------------------------------------------------------------------- void LLUICtrlFactory::rebuild() { built_panel_t built_panels = mBuiltPanels; mBuiltPanels.clear(); built_panel_t::iterator built_panel_it; for (built_panel_it = built_panels.begin(); built_panel_it != built_panels.end(); ++built_panel_it) { std::string filename = built_panel_it->second; LLPanel* panelp = built_panel_it->first.get(); if (!panelp) { continue; } llinfos << "Rebuilding UI panel " << panelp->getName() << " from " << filename << llendl; BOOL visible = panelp->getVisible(); panelp->setVisible(FALSE); panelp->setFocus(FALSE); panelp->deleteAllChildren(); buildPanel(panelp, filename.c_str(), &panelp->getFactoryMap()); panelp->setVisible(visible); } built_floater_t::iterator built_floater_it; for (built_floater_it = mBuiltFloaters.begin(); built_floater_it != mBuiltFloaters.end(); ++built_floater_it) { LLFloater* floaterp = built_floater_it->first.get(); if (!floaterp) { continue; } std::string filename = built_floater_it->second; llinfos << "Rebuilding UI floater " << floaterp->getName() << " from " << filename << llendl; BOOL visible = floaterp->getVisible(); floaterp->setVisible(FALSE); floaterp->setFocus(FALSE); floaterp->deleteAllChildren(); gFloaterView->removeChild(floaterp); buildFloater(floaterp, filename, &floaterp->getFactoryMap()); floaterp->setVisible(visible); } }
LLPanel *LLPanel::childGetVisiblePanelWithHelp() { LLView *child; bfs_tree_iterator_t it = beginTreeBFS(); // skip ourselves ++it; for (; it != endTreeBFS(); ++it) { child = *it; // do we have a panel with a help topic? LLPanel *panel = dynamic_cast<LLPanel *>(child); if (panel && panel->getVisible() && !panel->getHelpTopic().empty()) { return panel; } } // couldn't find any active panels with a help topic string return NULL; }
bool LLPanelMe::notifyChildren(const LLSD& info) { if (info.has("task-panel-action") && info["task-panel-action"].asString() == "handle-tri-state") { // Implement task panel tri-state behavior. // // When the button of an active open task panel is clicked, side tray // calls notifyChildren() on the panel, passing task-panel-action=>handle-tri-state as an argument. // The task panel is supposed to handle this by reverting to the default view, // i.e. closing any dependent panels like "pick info" or "profile edit". bool on_default_view = true; const LLRect& task_panel_rect = getRect(); for (LLView* child = getFirstChild(); child; child = findNextSibling(child)) { LLPanel* panel = dynamic_cast<LLPanel*>(child); if (!panel) continue; // *HACK: implement panel stack instead (e.g. me->pick_info->pick_edit). if (panel->getRect().getWidth() == task_panel_rect.getWidth() && panel->getRect().getHeight() == task_panel_rect.getHeight() && panel->getVisible()) { panel->setVisible(FALSE); on_default_view = false; } } if (on_default_view) LLSideTray::getInstance()->collapseSideBar(); return true; // this notification is only supposed to be handled by task panels } return LLPanel::notifyChildren(info); }
void LLLayoutStack::updateLayout(BOOL force_resize) { LLFastTimer ft(FTM_UPDATE_LAYOUT); static LLUICachedControl<S32> resize_bar_overlap ("UIResizeBarOverlap", 0); calcMinExtents(); createResizeBars(); // calculate current extents S32 total_width = 0; S32 total_height = 0; e_panel_list_t::iterator panel_it; for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { LLPanel* panelp = (*panel_it); if (panelp->getVisible()) { if (mAnimate) { if (!mAnimatedThisFrame) { (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(mOpenTimeConstant)); if ((*panel_it)->mVisibleAmt > 0.99f) { (*panel_it)->mVisibleAmt = 1.f; } } } else { (*panel_it)->mVisibleAmt = 1.f; } } else // not visible { if (mAnimate) { if (!mAnimatedThisFrame) { (*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); if ((*panel_it)->mVisibleAmt < 0.001f) { (*panel_it)->mVisibleAmt = 0.f; } } } else { (*panel_it)->mVisibleAmt = 0.f; } } if ((*panel_it)->mCollapsed) { (*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); } else { (*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant)); } if (mOrientation == HORIZONTAL) { // enforce minimize size constraint by default if (panelp->getRect().getWidth() < (*panel_it)->mMinDim) { panelp->reshape((*panel_it)->mMinDim, panelp->getRect().getHeight()); } total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor(mOrientation)); // want n-1 panel gaps for n panels if (panel_it != mPanels.begin()) { total_width += mPanelSpacing; } } else //VERTICAL { // enforce minimize size constraint by default if (panelp->getRect().getHeight() < (*panel_it)->mMinDim) { panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinDim); } total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor(mOrientation)); if (panel_it != mPanels.begin()) { total_height += mPanelSpacing; } } } S32 num_resizable_panels = 0; S32 shrink_headroom_available = 0; S32 shrink_headroom_total = 0; for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { // panels that are not fully visible do not count towards shrink headroom if ((*panel_it)->getCollapseFactor(mOrientation) < 1.f) { continue; } // if currently resizing a panel or the panel is flagged as not automatically resizing // only track total available headroom, but don't use it for automatic resize logic if ((*panel_it)->mResizeBar->hasMouseCapture() || (!(*panel_it)->mAutoResize && !force_resize)) { if (mOrientation == HORIZONTAL) { shrink_headroom_total += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim; } else //VERTICAL { shrink_headroom_total += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim; } } else { num_resizable_panels++; if (mOrientation == HORIZONTAL) { shrink_headroom_available += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim; shrink_headroom_total += (*panel_it)->getRect().getWidth() - (*panel_it)->mMinDim; } else //VERTICAL { shrink_headroom_available += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim; shrink_headroom_total += (*panel_it)->getRect().getHeight() - (*panel_it)->mMinDim; } } } // calculate how many pixels need to be distributed among layout panels // positive means panels need to grow, negative means shrink S32 pixels_to_distribute; if (mOrientation == HORIZONTAL) { pixels_to_distribute = getRect().getWidth() - total_width; } else //VERTICAL { pixels_to_distribute = getRect().getHeight() - total_height; } // now we distribute the pixels... S32 cur_x = 0; S32 cur_y = getRect().getHeight(); for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { LLPanel* panelp = (*panel_it); S32 cur_width = panelp->getRect().getWidth(); S32 cur_height = panelp->getRect().getHeight(); S32 new_width = cur_width; S32 new_height = cur_height; if (mOrientation == HORIZONTAL) { new_width = llmax((*panel_it)->mMinDim, new_width); } else { new_height = llmax((*panel_it)->mMinDim, new_height); } S32 delta_size = 0; // if panel can automatically resize (not animating, and resize flag set)... if ((*panel_it)->getCollapseFactor(mOrientation) == 1.f && (force_resize || (*panel_it)->mAutoResize) && !(*panel_it)->mResizeBar->hasMouseCapture()) { if (mOrientation == HORIZONTAL) { // if we're shrinking if (pixels_to_distribute < 0) { // shrink proportionally to amount over minimum // so we can do this in one pass delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_width - (*panel_it)->mMinDim) / (F32)shrink_headroom_available)) : 0; shrink_headroom_available -= (cur_width - (*panel_it)->mMinDim); } else { // grow all elements equally delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels); num_resizable_panels--; } pixels_to_distribute -= delta_size; new_width = llmax((*panel_it)->mMinDim, cur_width + delta_size); } else { new_width = getDefaultWidth(new_width); } if (mOrientation == VERTICAL) { if (pixels_to_distribute < 0) { // shrink proportionally to amount over minimum // so we can do this in one pass delta_size = (shrink_headroom_available > 0) ? llround((F32)pixels_to_distribute * ((F32)(cur_height - (*panel_it)->mMinDim) / (F32)shrink_headroom_available)) : 0; shrink_headroom_available -= (cur_height - (*panel_it)->mMinDim); } else { delta_size = llround((F32)pixels_to_distribute / (F32)num_resizable_panels); num_resizable_panels--; } pixels_to_distribute -= delta_size; new_height = llmax((*panel_it)->mMinDim, cur_height + delta_size); } else { new_height = getDefaultHeight(new_height); } } else { if (mOrientation == HORIZONTAL) { new_height = getDefaultHeight(new_height); } else // VERTICAL { new_width = getDefaultWidth(new_width); } } // adjust running headroom count based on new sizes shrink_headroom_total += delta_size; LLRect panel_rect; panel_rect.setLeftTopAndSize(cur_x, cur_y, new_width, new_height); panelp->setShape(panel_rect); LLRect resize_bar_rect = panel_rect; if (mOrientation == HORIZONTAL) { resize_bar_rect.mLeft = panel_rect.mRight - resize_bar_overlap; resize_bar_rect.mRight = panel_rect.mRight + mPanelSpacing + resize_bar_overlap; } else { resize_bar_rect.mTop = panel_rect.mBottom + resize_bar_overlap; resize_bar_rect.mBottom = panel_rect.mBottom - mPanelSpacing - resize_bar_overlap; } (*panel_it)->mResizeBar->setRect(resize_bar_rect); if (mOrientation == HORIZONTAL) { cur_x += llround(new_width * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing; } else //VERTICAL { cur_y -= llround(new_height * (*panel_it)->getCollapseFactor(mOrientation)) + mPanelSpacing; } } // update resize bars with new limits LLResizeBar* last_resize_bar = NULL; for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it) { LLPanel* panelp = (*panel_it); if (mOrientation == HORIZONTAL) { (*panel_it)->mResizeBar->setResizeLimits( (*panel_it)->mMinDim, (*panel_it)->mMinDim + shrink_headroom_total); } else //VERTICAL { (*panel_it)->mResizeBar->setResizeLimits( (*panel_it)->mMinDim, (*panel_it)->mMinDim + shrink_headroom_total); } // toggle resize bars based on panel visibility, resizability, etc BOOL resize_bar_enabled = panelp->getVisible() && (*panel_it)->mUserResize; (*panel_it)->mResizeBar->setVisible(resize_bar_enabled); if (resize_bar_enabled) { last_resize_bar = (*panel_it)->mResizeBar; } } // hide last resize bar as there is nothing past it // resize bars need to be in between two resizable panels if (last_resize_bar) { last_resize_bar->setVisible(FALSE); } // not enough room to fit existing contents if (force_resize == FALSE // layout did not complete by reaching target position && ((mOrientation == VERTICAL && cur_y != -mPanelSpacing) || (mOrientation == HORIZONTAL && cur_x != getRect().getWidth() + mPanelSpacing))) { // do another layout pass with all stacked elements contributing // even those that don't usually resize llassert_always(force_resize == FALSE); updateLayout(TRUE); } mAnimatedThisFrame = true; } // end LLLayoutStack::updateLayout
void LLFlatListView::rearrangeItems() { static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0); setNoItemsCommentVisible(mItemPairs.empty()); if (mItemPairs.empty()) return; //calculating required height - assuming items can be of different height //list should accommodate all its items S32 height = 0; S32 invisible_children_count = 0; pairs_iterator_t it = mItemPairs.begin(); for (; it != mItemPairs.end(); ++it) { LLPanel* item = (*it)->first; // skip invisible child if (!item->getVisible()) { ++invisible_children_count; continue; } height += item->getRect().getHeight(); } // add paddings between items, excluding invisible ones height += mItemPad * (mItemPairs.size() - invisible_children_count - 1); LLRect rc = mItemsPanel->getRect(); S32 width = mItemsNoScrollWidth; // update width to avoid horizontal scrollbar if (height > getRect().getHeight() - 2 * mBorderThickness) width -= scrollbar_size; //changes the bottom, end of the list goes down in the scroll container rc.setLeftTopAndSize(rc.mLeft, rc.mTop, width, height); mItemsPanel->setRect(rc); //reshaping items S32 item_new_top = height; pairs_iterator_t it2, first_it = mItemPairs.begin(); for (it2 = first_it; it2 != mItemPairs.end(); ++it2) { LLPanel* item = (*it2)->first; // skip invisible child if (!item->getVisible()) continue; LLRect rc = item->getRect(); rc.setLeftTopAndSize(rc.mLeft, item_new_top, width, rc.getHeight()); item->reshape(rc.getWidth(), rc.getHeight()); item->setRect(rc); // move top for next item in list item_new_top -= (rc.getHeight() + mItemPad); } // Stretch selected item rect to ensure it won't be clipped mSelectedItemsBorder->setRect(getLastSelectedItemRect().stretch(-1)); }