class Layouter::Implementation
{ public:
VclPtr<sd::Window> mpWindow; staticconst sal_Int32 mnRequestedLeftBorder = 5; staticconst sal_Int32 mnRequestedRightBorder = 5; staticconst sal_Int32 mnRequestedTopBorder = 5; staticconst sal_Int32 mnRequestedBottomBorder = 5;
sal_Int32 mnLeftBorder;
sal_Int32 mnRightBorder;
sal_Int32 mnTopBorder;
sal_Int32 mnBottomBorder; staticconst sal_Int32 gnVerticalGap = 10 - 2*Theme_FocusIndicatorWidth; staticconst sal_Int32 gnHorizontalGap = 10 - 2*Theme_FocusIndicatorWidth;
Size maMinimalSize;
Size maPreferredSize;
Size maMaximalSize;
sal_Int32 mnMinimalColumnCount;
sal_Int32 mnMaximalColumnCount;
sal_Int32 mnPageCount;
sal_Int32 mnColumnCount;
sal_Int32 mnRowCount; /// The maximum number of columns. Can only be larger than the current /// number of columns when there are not enough pages to fill all /// available columns.
sal_Int32 mnMaxColumnCount; /// The maximum number of rows. Can only be larger than the current /// number of rows when there are not enough pages to fill all available /// rows.
sal_Int32 mnMaxRowCount;
Size maPageObjectSize;
std::shared_ptr<PageObjectLayouter> mpPageObjectLayouter;
std::shared_ptr<view::Theme> mpTheme;
/** Specify how the gap between two page objects is associated with the pageobjects.
*/ enumclass GapMembership {
None, // Gap is not associated with any page object.
Previous, // The whole gap is associated with the previous page // object (left or above the gap.)
Both, // Half of the gap is associated with previous, half // with the next page object.
Next // The whole gap is associated with the next page // object (right or below the gap.)
};
/** Calculate the row that the point with the given vertical coordinate isover.Thehorizontalcomponentisignored. @paramnYPosition Verticalpositioninmodelcoordinates. @parambIncludeBordersAndGaps Whenthisflagis<TRUE/>thentheareaofbordersandgapsare interpretedasbelongingtooneoftherows. @parameGapMembership Specifiestowhatrowthegapareasbelong.HereGapMembership::None correspondstobIncludeBordersAndGapsbeing<FALSE/>.When GapMembership::Bothisgiventhentheupperhalfisassociatedtotherow aboveandthelowerhalftotherowbelow.Valuesof GapMembership::PreviousandGapMembership::Nextassociatethewholegapareawiththe rowaboveorbelowrespectively.
*/
sal_Int32 GetRowAtPosition (
sal_Int32 nYPosition, bool bIncludeBordersAndGaps,
GapMembership eGapMembership) const;
/** Calculate the column that the point with the given horizontal coordinateisover.Theverticalcomponentisignored. @paramnXPosition Horizontalpositioninmodelcoordinates. @parambIncludeBordersAndGaps Whenthisflagis<TRUE/>thentheareaofbordersandgapsare interpretedasbelongingtooneofthecolumns. @parameGapMembership Specifiestowhatcolumnthegapareasbelong.
*/
sal_Int32 GetColumnAtPosition (
sal_Int32 nXPosition, bool bIncludeBordersAndGaps,
GapMembership eGapMembership) const;
/** This method is typically called from GetRowAtPosition() and GetColumnAtPosition()tohandleapositionthatliesinsidethegap betweentwoadjacentrowsorcolumns. @paramnDistanceIntoGap Verticaldistancefromthebottomoftheupperrowdownintothe gaporhorizontaldistancefromtherightedgerightintothe gap. @parameGapMemberhship Thisvaluedecideswhatareasinthegapbelongtowhich(orno) roworcolumn. @paramnIndex Therowindexoftheupperroworthecolumnindexoftheleft column. @paramnGap Widthorheightofthegapinmodelcoordinatesbetweenthe pageborders. @return Returnseithertheindexoftheupperrow(asgivenasnRow),the indexofthelowerrow(nRow+1)or-1toindicatethatthe positionbelongstonorow.
*/ static sal_Int32 ResolvePositionInGap (
sal_Int32 nDistanceIntoGap,
GapMembership eGapMembership,
sal_Int32 nIndex,
sal_Int32 nGap);
/** Calculate the logical part of the insert position, i.e. the page afterwhichtoinsert.
*/ virtualvoid CalculateLogicalInsertPosition ( const Point& rModelPosition,
InsertPosition& rPosition) const = 0;
/** Calculate the geometrical part of the insert position, i.e. the locationofwheretodisplaytheinsertionindicatorandthe distancesaboutwhichtheleadingandtrailingpageshavetobe movedtomakeroomfortheindicator.
*/ void CalculateGeometricPosition (
InsertPosition& rPosition, const Size& rIndicatorSize, constbool bIsVertical,
model::SlideSorterModel const & rModel) const;
/** Return the bounding box of the preview or, when selected, of the page object.Thus,itreturnssomethinglikeavisualboundingbox.
*/
::tools::Rectangle GetInnerBoundingBox (
model::SlideSorterModel const & rModel, const sal_Int32 nIndex) const;
Range GetValidHorizontalSizeRange() const;
Range GetValidVerticalSizeRange() const;
/** The vertical layouter has one column and as many rows as there are pages.
*/ class VerticalImplementation : public Layouter::Implementation
{ public: explicit VerticalImplementation (const Implementation& rImplementation);
/** The horizontal layouter has one row and as many columns as there are pages.
*/ class HorizontalImplementation : public Layouter::Implementation
{ public: explicit HorizontalImplementation(const Implementation& rImplementation);
/** The number of columns of the grid layouter is defined via a control in theslidesortertoolbar.Thenumberofrowsiscalculatedfromthe numberofcolumnsandthenumberofpages.
*/ class GridImplementation : public Layouter::Implementation
{ public:
GridImplementation (
sd::Window *pWindow, const std::shared_ptr<view::Theme>& rpTheme); explicit GridImplementation(const Implementation& rImplementation);
// Return early when the window or the model have not yet been initialized. if (rWindowSize.IsEmpty()) returnfalse; if (rPreviewModelSize.IsEmpty()) returnfalse;
CalculateRowAndColumnCount(rWindowSize);
// Update the border values.
mnLeftBorder = mnRequestedLeftBorder;
mnTopBorder = mnRequestedTopBorder;
mnRightBorder = mnRequestedRightBorder;
mnBottomBorder = mnRequestedBottomBorder; if (mnColumnCount > 1)
{ int nMinimumBorderWidth = gnHorizontalGap/2; if (mnLeftBorder < nMinimumBorderWidth)
mnLeftBorder = nMinimumBorderWidth; if (mnRightBorder < nMinimumBorderWidth)
mnRightBorder = nMinimumBorderWidth;
} else
{ int nMinimumBorderHeight = gnVerticalGap/2; if (mnTopBorder < nMinimumBorderHeight)
mnTopBorder = nMinimumBorderHeight; if (mnBottomBorder < nMinimumBorderHeight)
mnBottomBorder = nMinimumBorderHeight;
}
const sal_Int32 nY = nYPosition - mnTopBorder; if (nY >= 0)
{ // Vertical distance from one row to the next. const sal_Int32 nRowOffset (maPageObjectSize.Height() + gnVerticalGap);
// Calculate row consisting of page objects and gap below.
nRow = nY / nRowOffset;
const sal_Int32 nDistanceIntoGap ((nY - nRow*nRowOffset) - maPageObjectSize.Height()); // When inside the gap below then nYPosition is not over a page // object. if (nDistanceIntoGap > 0)
{
sal_Int32 nResolvedRow = ResolvePositionInGap(
nDistanceIntoGap,
eGapMembership,
nRow,
gnVerticalGap); if (!bIncludeBordersAndGaps || nResolvedRow != -1)
nRow = nResolvedRow;
}
} elseif (bIncludeBordersAndGaps)
{ // We are in the top border area. Set nRow to the first row when // the top border shall be considered to belong to the first row.
nRow = 0;
}
sal_Int32 nX = nXPosition - mnLeftBorder; if (nX >= 0)
{ // Horizontal distance from one column to the next. const sal_Int32 nColumnOffset (maPageObjectSize.Width() + gnHorizontalGap);
// Calculate row consisting of page objects and gap below.
nColumn = nX / nColumnOffset; if (nColumn < 0)
nColumn = 0; elseif (nColumn >= mnColumnCount)
nColumn = mnColumnCount-1;
const sal_Int32 nDistanceIntoGap ((nX - nColumn*nColumnOffset) - maPageObjectSize.Width()); // When inside the gap at the right then nXPosition is not over a // page object. if (nDistanceIntoGap > 0)
{
sal_Int32 nResolvedColumn = ResolvePositionInGap(
nDistanceIntoGap,
eGapMembership,
nColumn,
gnHorizontalGap); if (!bIncludeBordersAndGaps || nResolvedColumn != -1)
nColumn = nResolvedColumn;
}
} elseif (bIncludeBordersAndGaps)
{ // We are in the left border area. Set nColumn to the first column // when the left border shall be considered to belong to the first // column.
nColumn = 0;
} return nColumn;
}
sal_Int32 Layouter::Implementation::ResolvePositionInGap (
sal_Int32 nDistanceIntoGap,
GapMembership eGapMembership,
sal_Int32 nIndex,
sal_Int32 nGap)
{ switch (eGapMembership)
{ case GapMembership::None: // The gap is no man's land.
nIndex = -1; break;
case GapMembership::Both:
{ // The lower half of the gap belongs to the next row or column.
sal_Int32 nFirstHalfGapWidth = nGap / 2; if (nDistanceIntoGap > nFirstHalfGapWidth)
nIndex ++; break;
}
case GapMembership::Previous: // Row or column already at correct value. break;
case GapMembership::Next: // The complete gap belongs to the next row or column.
nIndex ++; break;
default:
nIndex = -1;
}
return nIndex;
}
void Layouter::Implementation::CalculateGeometricPosition (
InsertPosition& rPosition, const Size& rIndicatorSize, constbool bIsVertical,
model::SlideSorterModel const & rModel) const
{ // 1. Determine right/bottom of the leading page and the left/top of the // trailing page object and how to distribute the missing space.
sal_Int32 nLeadingLocation (0);
sal_Int32 nTrailingLocation (0); bool bIsLeadingFixed (false); bool bIsTrailingFixed (false);
sal_Int32 nSecondaryLocation (0); const sal_Int32 nIndex (rPosition.GetIndex());
if (rPosition.IsAtRunStart())
{ // Place indicator at the top of the column. const ::tools::Rectangle aOuterBox (GetPageObjectBox(nIndex)); const ::tools::Rectangle aInnerBox (GetInnerBoundingBox(rModel, nIndex)); if (bIsVertical)
{
nLeadingLocation = aOuterBox.Top();
nTrailingLocation = aInnerBox.Top();
nSecondaryLocation = aInnerBox.Center().X();
} else
{
nLeadingLocation = aOuterBox.Left();
nTrailingLocation = aInnerBox.Left();
nSecondaryLocation = aInnerBox.Center().Y();
}
bIsLeadingFixed = true;
} elseif (rPosition.IsAtRunEnd())
{ // Place indicator at the bottom/right of the column/row.
Range Layouter::Implementation::GetRangeOfVisiblePageObjects (const ::tools::Rectangle& aVisibleArea) const
{ // technically that's not empty, but it's the default, so... if (aVisibleArea.IsEmpty()) return Range(-1, -1);
// When start and end lie in different rows then the range may include // slides outside (left or right of) the given area. return Range(GetIndex(nRow0,nCol0,true), GetIndex(nRow1,nCol1,true));
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.