void FlowLayout::updateLayout(const MFUnrecComponentPtr* Components, const Component* ParentComponent) const { /*! totalMajorAxis will hold the width of its container, and cumMajorAxis will hold the width of all of the buttons. That way it will always know when to move to the next line. In addition, maxMinorAxis keeps track of the largest height so it knows how far down to move the next row. Also, oneInRow is used to make sure that it places at least one component in every row. */ UInt32 AxisIndex(0); if(getOrientation() != HORIZONTAL_ORIENTATION ) AxisIndex = 1; Vec2f gap(getHorizontalGap(), getVerticalGap()); UInt32 numGaps(0); /*! When finding the cumMinor Axis, the gap is included, because there is no count for how many stacks there are. When finding cumMajor, the gap isn't included because the total distance relies on how many components there are in that row/column. */ Pnt2f borderTopLeft, borderBottomRight; dynamic_cast<const ComponentContainer*>(ParentComponent)->getInsideInsetsBounds(borderTopLeft, borderBottomRight); Vec2f borderSize(borderBottomRight-borderTopLeft); Real64 totalMajorAxis(borderSize[AxisIndex]); Real32 cumMajorAxis(0); Real32 maxMinorAxis(0); Real32 cumMinorAxis(0); Real32 prevComponent(0); Real64 offsetMajorAxis(0); Real64 offsetMinorAxis(0); Real64 offsetX(borderTopLeft.x()); Real64 offsetY(borderTopLeft.y()); bool firstOne = true; for(UInt32 i=0 ; i<Components->size(); ++i) { } for(UInt32 i=0 ; i<Components->size(); ++i) { // set the component to its preferred size (*Components)[i]->setSize(getAppropriateComponentSize((*Components)[i])); // if there is only one so far, then it can't draw it using cumMajorAxis // because it hasn't been set yet if (firstOne) // this one might draw it { firstOne = false; // if this is the last component or it is already too big for the // container, draw it centered on its line if (i == Components->size() || (*Components)[i]->getSize()[AxisIndex] >= totalMajorAxis) { // find how far to translate to make it properly aligned offsetMajorAxis = getMajorAxisAlignment()*(totalMajorAxis - (*Components)[i]->getSize()[AxisIndex]); if (AxisIndex) { offsetY+= offsetMajorAxis; } else { offsetX += offsetMajorAxis; } (*Components)[i]->setPosition(Pnt2f(offsetX, offsetY)); // get to the next row if (AxisIndex) { offsetX += (*Components)[i]->getSize()[(AxisIndex+1)%2]+gap[(AxisIndex+1)%2]; offsetY += -offsetMajorAxis; } else { offsetX += -offsetMajorAxis; offsetY += (*Components)[i]->getSize()[(AxisIndex+1)%2]+gap[(AxisIndex+1)%2]; } // update cumMinorAxis, other values should still be at 0 cumMinorAxis += (*Components)[i]->getSize()[(AxisIndex+1)%2]; if(i < Components->size()-1) { cumMinorAxis += gap[(AxisIndex+1)%2]; } // update prevComponent prevComponent++; // next component is still just like the first one firstOne = true; } else { // update the maxMinorAxis maxMinorAxis = (*Components)[i]->getSize()[(AxisIndex+1)%2]; // update cumMajorAxis cumMajorAxis += (*Components)[i]->getSize()[AxisIndex]; } } else if (cumMajorAxis + (*Components)[i]->getSize()[AxisIndex] + gap[AxisIndex]*(i-prevComponent) > totalMajorAxis) // this one draws up to i { // The numGaps is one less than the number of components being drawn, but it // is actually translates once for each component, so it must be compensated // when returning to the next row. numGaps = i-prevComponent-1; // find how far to translate to make it properly aligned offsetMajorAxis = getMajorAxisAlignment()*(totalMajorAxis - (cumMajorAxis+numGaps*gap[AxisIndex])); if (AxisIndex){ offsetY += offsetMajorAxis; } else { offsetX += offsetMajorAxis; } for (int j = prevComponent; j < i; j++) { // find how far to translate to make this button properly aligned offsetMinorAxis = (maxMinorAxis-(*Components)[j]->getSize()[(AxisIndex+1)%2])*getComponentAlignment(); // translate to make it properly aligned if (AxisIndex) { offsetX += offsetMinorAxis; } else { offsetY += offsetMinorAxis; } (*Components)[j]->setPosition(Pnt2f(offsetX, offsetY)); // translate to next button if (AxisIndex) { offsetX+=-(Real64)offsetMinorAxis; offsetY+= (*Components)[j]->getSize()[AxisIndex] + gap[AxisIndex]; } else { offsetX+=(*Components)[j]->getSize()[AxisIndex] + gap[AxisIndex]; offsetY+= -offsetMinorAxis; } } // translate to the next row if (AxisIndex) { offsetX += maxMinorAxis+gap[(AxisIndex+1)%2]; offsetY += -(offsetMajorAxis+cumMajorAxis+(numGaps+1)*gap[AxisIndex]); } else { offsetX += -(offsetMajorAxis+cumMajorAxis+(numGaps+1)*gap[AxisIndex]); offsetY += maxMinorAxis+gap[(AxisIndex+1)%2]; } cumMinorAxis += maxMinorAxis + gap[(AxisIndex+1)%2]; maxMinorAxis = (*Components)[i]->getSize()[(AxisIndex+1)%2]; prevComponent = i; cumMajorAxis = (*Components)[i]->getSize()[AxisIndex]; } else { // update the maxMinorAxis if ((*Components)[i]->getSize()[(AxisIndex+1)%2] > maxMinorAxis) maxMinorAxis = (*Components)[i]->getSize()[(AxisIndex+1)%2]; // update cumMajorAxis cumMajorAxis += (*Components)[i]->getSize()[AxisIndex]; } if (i+1 == Components->size() && !firstOne) // if on the last one, draw the last buttons { numGaps = i-prevComponent; // find how far to translate to make it properly aligned offsetMajorAxis = getMajorAxisAlignment()*(totalMajorAxis - (cumMajorAxis+numGaps*gap[AxisIndex])); if (AxisIndex) { offsetY += offsetMajorAxis; } else { offsetX += offsetMajorAxis; } for (int j = prevComponent; j < i+1; j++) { // find how far to translate to make this button properly aligned offsetMinorAxis = (maxMinorAxis-(*Components)[j]->getSize()[(AxisIndex+1)%2])*getComponentAlignment(); // translate to make it properly aligned if (AxisIndex) { offsetX += offsetMinorAxis; } else { offsetY += offsetMinorAxis; } (*Components)[j]->setPosition(Pnt2f(offsetX, offsetY)); if (AxisIndex) { offsetX += -(Real64)offsetMinorAxis; offsetY += (*Components)[j]->getSize()[AxisIndex] + gap[AxisIndex]; } else { offsetX += (*Components)[j]->getSize()[AxisIndex] + gap[AxisIndex]; offsetY+= -(Real64)offsetMinorAxis; } } // translate to the next row if (AxisIndex) { offsetX += maxMinorAxis+gap[(AxisIndex+1)%2]; offsetY += -(offsetMajorAxis+cumMajorAxis+(numGaps+1)*gap[AxisIndex]); } else { offsetX += -(offsetMajorAxis+cumMajorAxis+(numGaps+1)*gap[AxisIndex]); offsetY += maxMinorAxis+gap[(AxisIndex+1)%2]; } cumMinorAxis += maxMinorAxis; } } //Minor Axis Alignment Real32 displacement(borderSize[(AxisIndex+1)%2]-cumMinorAxis); Pnt2f offset; displacement *= getMinorAxisAlignment(); for (UInt32 i = 0; i < Components->size(); ++i) { offset = (*Components)[i]->getPosition(); offset[(AxisIndex+1)%2] += displacement; (*Components)[i]->setPosition(offset); } for(UInt32 i=0 ; i<Components->size(); ++i) { } }
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); } } }