void TabPanel::updateLayout(void) { Pnt2f InsideInsetsTopLeft,InsideInsetsBottomRight; getInsideInsetsBounds(InsideInsetsTopLeft,InsideInsetsBottomRight); UInt16 AxisIndex(0); if (getTabPlacement() == PLACEMENT_EAST || getTabPlacement() == PLACEMENT_WEST) { AxisIndex=1; } Real32 largestMinorAxis(0.0f); Real32 cumMajorAxis(0.0f); Pnt2f alignOffset(0.0f,0.0f); Vec2f offset(0.0f,0.0f); Vec2f TabBorderTopLeftWidth, TabBorderBottomRightWidth; calculateMaxTabBorderLengths(TabBorderTopLeftWidth[0], TabBorderBottomRightWidth[0],TabBorderTopLeftWidth[1], TabBorderBottomRightWidth[1]); // first layout all of the tabs // naturally the alignments and such is necessary // on the first sweep, get the maximum size and cumLength const Real32 TabMajorAxisSpacing(5.0f); Vec2f TabReqSize; for (UInt32 i=0; i < getMFTabs()->size(); ++i) { TabReqSize = getTabs(i)->getRequestedSize() + Vec2f(getTabBorderInsets().x() + getTabBorderInsets().y(), getTabBorderInsets().z() + getTabBorderInsets().w()); cumMajorAxis += TabReqSize[AxisIndex]; if (TabReqSize[(AxisIndex+1)%2] > largestMinorAxis) { largestMinorAxis = TabReqSize[(AxisIndex+1)%2]; } } cumMajorAxis += TabMajorAxisSpacing * 2.0f * getMFTabs()->size(); cumMajorAxis += static_cast<Real32>(getMFTabs()->size()) * (TabBorderTopLeftWidth[AxisIndex] + TabBorderBottomRightWidth[AxisIndex]); largestMinorAxis += (TabBorderTopLeftWidth[(AxisIndex+1)%2] + TabBorderBottomRightWidth[(AxisIndex+1)%2]); // set up the alignment and offset Vec2f TabSize; TabSize[AxisIndex] = cumMajorAxis; TabSize[(AxisIndex+1)%2] = largestMinorAxis; Vec2f Alignment; Alignment[(AxisIndex+1)%2] = getTabAlignment(); switch(getTabPlacement()) { case PLACEMENT_SOUTH: case PLACEMENT_EAST: Alignment[AxisIndex] = 1.0; break; case PLACEMENT_NORTH: case PLACEMENT_WEST: Alignment[AxisIndex] = 0.0; break; } alignOffset = calculateAlignment(InsideInsetsTopLeft, (InsideInsetsBottomRight-InsideInsetsTopLeft),TabSize,Alignment.x(),Alignment.y()); offset = Vec2f(InsideInsetsTopLeft); offset[(AxisIndex+1)%2] += TabBorderTopLeftWidth[(AxisIndex+1)%2]; // set sizes and positions of all tabs Vec2f Size; Pnt2f Pos; for (UInt32 i=0; i < getMFTabs()->size(); ++i) { offset[AxisIndex] += TabBorderTopLeftWidth[AxisIndex]; Size = getTabs(i)->getRequestedSize() + Vec2f(getTabBorderInsets().x() + getTabBorderInsets().y(), getTabBorderInsets().z() + getTabBorderInsets().w()); if(getTabs(i)->getSize() != Size) { getTabs(i)->setSize(Size); } Pos = alignOffset + offset; if(getTabs(i)->getPosition() != Pos) { getTabs(i)->setPosition(Pos); } offset[AxisIndex] += getTabs(i)->getSize()[AxisIndex] + TabBorderBottomRightWidth[AxisIndex]; } if((getSelectedIndex()+1) > getMFTabContents()->size()) { setSelectedIndex(getMFTabContents()->size()-1); } if(getMFTabContents()->size() > 0 && getSelectedIndex() != -1) { Vec2f ContentBorderTopLeftWidth, ContentBorderBottomRightWidth; calculateContentBorderLengths(getContentBorder(), ContentBorderTopLeftWidth[0], ContentBorderBottomRightWidth[0],ContentBorderTopLeftWidth[1], ContentBorderBottomRightWidth[1]); // now set size and position of the active tab's contents offset = Vec2f(InsideInsetsTopLeft); if (getTabPlacement() == PLACEMENT_NORTH || getTabPlacement() == PLACEMENT_WEST) { offset[(AxisIndex+1)%2] += largestMinorAxis; } Size = InsideInsetsBottomRight-InsideInsetsTopLeft-(ContentBorderTopLeftWidth + ContentBorderBottomRightWidth); Size[(AxisIndex+1)%2] -= TabSize[(AxisIndex+1)%2]; if(getTabContents(getSelectedIndex())->getSize() != Size) { getTabContents(getSelectedIndex())->setSize(Size); } Pos = Pnt2f(0.0f,0.0f) + offset + ContentBorderTopLeftWidth; if(getTabContents(getSelectedIndex())->getPosition() != Pos) { getTabContents(getSelectedIndex())->setPosition(Pos); } } }
void BoxLayout::updateLayout(const MFUnrecComponentPtr* Components, const Component* ParentComponent) const { /*! totalMajorAxis will be the sum of the MajorAxis of all of the components, which is compared to MajorAxis, which is MajorAxis of the parent component. These two variables will be used to determine the spacing of each of the objects. */ UInt32 AxisIndex(0); if(getOrientation() != HORIZONTAL_ORIENTATION ) AxisIndex = 1; Pnt2f borderTopLeft, borderBottomRight; dynamic_cast<const ComponentContainer*>(ParentComponent)->getInsideInsetsBounds(borderTopLeft, borderBottomRight); Vec2f borderSize(borderBottomRight-borderTopLeft); Real32 MajorAxis(borderSize[AxisIndex]); Real32 totalMajorAxis(0); Real32 largestMinorAxis(0); Real32 spacing(0); Vec2f size; Vec2f offset(0,0); /*! This first sweep through the components sets each component to its preferred size, gets a sum of all the MajorAxes, and finds the largest height. */ for(UInt32 i=0 ; i<Components->size() ; ++i) { // set the component to its preferred size // get sum of all components totalMajorAxis += (*Components)[i]->getPreferredSize()[AxisIndex]; if ((*Components)[i]->getPreferredSize()[(AxisIndex+1)%2] > largestMinorAxis) largestMinorAxis = (*Components)[i]->getPreferredSize()[(AxisIndex+1)%2]; } if(MajorAxis > totalMajorAxis) { spacing = (MajorAxis-totalMajorAxis)/(Components->size()+1); // in the case where there isn't equal spacing between each button, // translate more the first time to center the components if(spacing < getMajorAxisMinimumGap()) { spacing = getMajorAxisMinimumGap(); } if(spacing > getMajorAxisMaximumGap()) { spacing = getMajorAxisMaximumGap(); } borderTopLeft[AxisIndex] += (MajorAxis - (spacing*(Components->size()+1)+totalMajorAxis))*getMajorAxisAlignment() + spacing; } else { spacing = getMajorAxisMinimumGap(); } if(getOrientation() == HORIZONTAL_ORIENTATION) { borderTopLeft = calculateAlignment(borderTopLeft, borderSize, Vec2f(0.0f,largestMinorAxis), getMinorAxisAlignment(), 0.0f); } else { borderTopLeft = calculateAlignment(borderTopLeft, borderSize, Vec2f(largestMinorAxis,0.0f), 0.0f, getMinorAxisAlignment()); } /*! This second sweep through the components sets each component to the matching highest height, then positions each component equally spaced apart */ for(UInt32 i=0; i<Components->size(); ++i) { // for each individual button, keep track of the offsetMinorAxis in height // for use in keeping them vertically centered offset[(AxisIndex+1)%2] = 0; // change the component's height only if necessary if (largestMinorAxis > (*Components)[i]->getPreferredSize()[(AxisIndex+1)%2]) { if (largestMinorAxis <= (*Components)[i]->getMaxSize()[(AxisIndex+1)%2]) { // for when the max height is larger than the largestMinorAxis size[AxisIndex] = (*Components)[i]->getPreferredSize()[AxisIndex]; size[(AxisIndex+1)%2] = largestMinorAxis; } else { // in this case, max out the button to its max height size[AxisIndex] = (*Components)[i]->getPreferredSize()[AxisIndex]; size[(AxisIndex+1)%2] = (*Components)[i]->getMaxSize()[(AxisIndex+1)%2]; // find how far to set offset to make this button properly aligned if(getOrientation() == HORIZONTAL_ORIENTATION) { offset = Vec2f(calculateAlignment(Pnt2f(0,0), Vec2f(0.0f, largestMinorAxis), Vec2f(0.0f,(*Components)[i]->getMaxSize().y()), getComponentAlignment(), 0.0f)); } else { offset = Vec2f(calculateAlignment(Pnt2f(0,0), Vec2f(largestMinorAxis,0.0f), Vec2f((*Components)[i]->getMaxSize().x(),0.0f), 0.0f, getComponentAlignment())); } } } else { size = (*Components)[i]->getPreferredSize(); } (*Components)[i]->setSize(size); (*Components)[i]->setPosition(borderTopLeft + offset); // now set offset for the next button offset[AxisIndex] += spacing + (*Components)[i]->getPreferredSize()[AxisIndex]; } }