GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / svtools / source / toolpanel / tabbargeometry.cxx
blob43036233ed90abbd379623f04197eca6c4a91fbd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "tabbargeometry.hxx"
23 #include <basegfx/range/b2drange.hxx>
24 #include <basegfx/matrix/b2dhommatrix.hxx>
25 #include <basegfx/numeric/ftools.hxx>
27 #include <vcl/window.hxx>
29 #include <algorithm>
31 // the width (or height, depending on alignment) of the scroll buttons
32 #define BUTTON_FLOW_WIDTH 20
33 // the space between the scroll buttons and the items
34 #define BUTTON_FLOW_SPACE 2
35 // outer space to apply between the tab bar borders and any content. Note that those refer to a "normalized" geometry,
36 // i.e. if the tab bar were aligned at the top
37 #define OUTER_SPACE_LEFT 2
38 #define OUTER_SPACE_TOP 4
39 #define OUTER_SPACE_RIGHT 4
40 #define OUTER_SPACE_BOTTOM 2
42 // outer space to apply between the area for the items, and the actual items. They refer to a normalized geometry.
43 #define ITEMS_INSET_LEFT 4
44 #define ITEMS_INSET_TOP 3
45 #define ITEMS_INSET_RIGHT 4
46 #define ITEMS_INSET_BOTTOM 0
48 //......................................................................................................................
49 namespace svt
51 //......................................................................................................................
53 //==================================================================================================================
54 //= helper
55 //==================================================================================================================
56 namespace
58 //--------------------------------------------------------------------------------------------------------------
59 static void lcl_transform( Rectangle& io_rRect, const ::basegfx::B2DHomMatrix& i_rTransformation )
61 ::basegfx::B2DRange aRect( io_rRect.Left(), io_rRect.Top(), io_rRect.Right(), io_rRect.Bottom() );
62 aRect.transform( i_rTransformation );
63 io_rRect.Left() = long( aRect.getMinX() );
64 io_rRect.Top() = long( aRect.getMinY() );
65 io_rRect.Right() = long( aRect.getMaxX() );
66 io_rRect.Bottom() = long( aRect.getMaxY() );
69 //--------------------------------------------------------------------------------------------------------------
70 /** transforms the given, possible rotated playground,
72 void lcl_rotate( const Rectangle& i_rReference, Rectangle& io_rArea, const bool i_bRight )
74 // step 1: move the to-be-upper-left corner (left/bottom) of the rectangle to (0,0)
75 ::basegfx::B2DHomMatrix aTransformation;
76 aTransformation.translate(
77 i_bRight ? -i_rReference.Left() : -i_rReference.Right(),
78 i_bRight ? -i_rReference.Bottom() : -i_rReference.Top()
81 // step 2: rotate by -90 degrees
82 aTransformation.rotate( i_bRight ? +F_PI2 : -F_PI2 );
83 // note:
84 // on the screen, the ordinate goes top-down, while basegfx calculates in a system where the
85 // ordinate goes bottom-up; thus the "wrong" sign before F_PI2 here
87 // step 3: move back to original coordinates
88 aTransformation.translate( i_rReference.Left(), i_rReference.Top() );
90 // apply transformation
91 lcl_transform( io_rArea, aTransformation );
95 //------------------------------------------------------------------------------------------------------------------
96 void lcl_mirrorHorizontally( const Rectangle& i_rReferenceArea, Rectangle& io_rArea )
98 io_rArea.Left() = i_rReferenceArea.Left() + i_rReferenceArea.Right() - io_rArea.Left();
99 io_rArea.Right() = i_rReferenceArea.Left() + i_rReferenceArea.Right() - io_rArea.Right();
100 ::std::swap( io_rArea.Left(), io_rArea.Right() );
103 //------------------------------------------------------------------------------------------------------------------
104 void lcl_mirrorVertically( const Rectangle& i_rReferenceArea, Rectangle& io_rArea )
106 io_rArea.Top() = i_rReferenceArea.Top() + i_rReferenceArea.Bottom() - io_rArea.Top();
107 io_rArea.Bottom() = i_rReferenceArea.Top() + i_rReferenceArea.Bottom() - io_rArea.Bottom();
108 ::std::swap( io_rArea.Top(), io_rArea.Bottom() );
111 //==================================================================================================================
112 //= NormalizedArea
113 //==================================================================================================================
114 //------------------------------------------------------------------------------------------------------------------
115 NormalizedArea::NormalizedArea()
116 :m_aReference()
120 //------------------------------------------------------------------------------------------------------------------
121 NormalizedArea::NormalizedArea( const Rectangle& i_rReference, const bool i_bIsVertical )
122 :m_aReference( i_bIsVertical ? Rectangle( i_rReference.TopLeft(), Size( i_rReference.GetHeight(), i_rReference.GetWidth() ) ) : i_rReference )
126 //------------------------------------------------------------------------------------------------------------------
127 Rectangle NormalizedArea::getTransformed( const Rectangle& i_rArea, const TabAlignment i_eTargetAlignment ) const
129 Rectangle aResult( i_rArea );
131 if ( ( i_eTargetAlignment == TABS_RIGHT )
132 || ( i_eTargetAlignment == TABS_LEFT )
135 lcl_rotate( m_aReference, aResult, true );
137 if ( i_eTargetAlignment == TABS_LEFT )
139 Rectangle aReference( m_aReference );
140 aReference.Transpose();
141 lcl_mirrorHorizontally( aReference, aResult );
144 else if ( i_eTargetAlignment == TABS_BOTTOM )
146 lcl_mirrorVertically( m_aReference, aResult );
149 return aResult;
152 //------------------------------------------------------------------------------------------------------------------
153 Rectangle NormalizedArea::getNormalized( const Rectangle& i_rArea, const TabAlignment i_eTargetAlignment ) const
155 Rectangle aResult( i_rArea );
157 if ( ( i_eTargetAlignment == TABS_RIGHT )
158 || ( i_eTargetAlignment == TABS_LEFT )
161 Rectangle aReference( m_aReference );
162 lcl_rotate( m_aReference, aReference, true );
164 if ( i_eTargetAlignment == TABS_LEFT )
166 lcl_mirrorHorizontally( aReference, aResult );
169 lcl_rotate( aReference, aResult, false );
171 else if ( i_eTargetAlignment == TABS_BOTTOM )
173 lcl_mirrorVertically( m_aReference, aResult );
175 return aResult;
178 //==================================================================================================================
179 //= TabBarGeometry
180 //==================================================================================================================
181 //------------------------------------------------------------------------------------------------------------------
182 TabBarGeometry::TabBarGeometry( const TabItemContent i_eItemContent )
183 :m_eTabItemContent( i_eItemContent )
184 ,m_aItemsInset()
185 ,m_aButtonBackRect()
186 ,m_aItemsRect()
187 ,m_aButtonForwardRect()
189 m_aItemsInset.Left() = ITEMS_INSET_LEFT;
190 m_aItemsInset.Top() = ITEMS_INSET_TOP;
191 m_aItemsInset.Right() = ITEMS_INSET_RIGHT;
192 m_aItemsInset.Bottom() = ITEMS_INSET_BOTTOM;
195 //------------------------------------------------------------------------------------------------------------------
196 TabBarGeometry::~TabBarGeometry()
200 //------------------------------------------------------------------------------------------------------------------
201 bool TabBarGeometry::impl_fitItems( ItemDescriptors& io_rItems ) const
203 if ( io_rItems.empty() )
204 // nothing to do, "no items" perfectly fit into any space we have ...
205 return true;
207 // the available size
208 Size aOutputSize( getItemsRect().GetSize() );
209 // shrunk by the outer space
210 aOutputSize.Width() -= m_aItemsInset.Right();
211 aOutputSize.Height() -= m_aItemsInset.Bottom();
212 const Rectangle aFitInto( Point( 0, 0 ), aOutputSize );
214 TabItemContent eItemContent( getItemContent() );
215 if ( eItemContent == TABITEM_AUTO )
217 // the "content modes" to try
218 TabItemContent eTryThis[] =
220 TABITEM_IMAGE_ONLY, // assumed to have the smallest rects
221 TABITEM_TEXT_ONLY,
222 TABITEM_IMAGE_AND_TEXT // assumed to have the largest rects
226 // determine which of the different version fits
227 eItemContent = eTryThis[0];
228 size_t nTryIndex = 2;
229 while ( nTryIndex > 0 )
231 const Point aBottomRight( io_rItems.rbegin()->GetRect( eTryThis[ nTryIndex ] ).BottomRight() );
232 if ( aFitInto.IsInside( aBottomRight ) )
234 eItemContent = eTryThis[ nTryIndex ];
235 break;
237 --nTryIndex;
241 // propagate to the items
242 for ( ItemDescriptors::iterator item = io_rItems.begin();
243 item != io_rItems.end();
244 ++item
247 item->eContent = eItemContent;
250 const ItemDescriptor& rLastItem( *io_rItems.rbegin() );
251 const Point aLastItemBottomRight( rLastItem.GetCurrentRect().BottomRight() );
252 return aFitInto.Left() <= aLastItemBottomRight.X()
253 && aFitInto.Right() >= aLastItemBottomRight.X();
256 //------------------------------------------------------------------------------------------------------------------
257 Size TabBarGeometry::getOptimalSize(ItemDescriptors& io_rItems) const
259 if ( io_rItems.empty() )
260 return Size(
261 m_aItemsInset.Left() + m_aItemsInset.Right(),
262 m_aItemsInset.Top() + m_aItemsInset.Bottom()
265 // the rect of the last item
266 const Rectangle& rLastItemRect(io_rItems.rbegin()->aCompleteArea);
267 return Size(
268 rLastItemRect.Left() + 1 + m_aItemsInset.Right(),
269 rLastItemRect.Top() + 1 + rLastItemRect.Bottom() + m_aItemsInset.Bottom()
273 //------------------------------------------------------------------------------------------------------------------
274 void TabBarGeometry::relayout( const Size& i_rActualOutputSize, ItemDescriptors& io_rItems )
276 // assume all items fit
277 Point aButtonBackPos( OUTER_SPACE_LEFT, OUTER_SPACE_TOP );
278 m_aButtonBackRect = Rectangle( aButtonBackPos, Size( 1, 1 ) );
279 m_aButtonBackRect.SetEmpty();
281 Point aButtonForwardPos( i_rActualOutputSize.Width(), OUTER_SPACE_TOP );
282 m_aButtonForwardRect = Rectangle( aButtonForwardPos, Size( 1, 1 ) );
283 m_aButtonForwardRect.SetEmpty();
285 Point aItemsPos( OUTER_SPACE_LEFT, 0 );
286 Size aItemsSize( i_rActualOutputSize.Width() - OUTER_SPACE_LEFT - OUTER_SPACE_RIGHT, i_rActualOutputSize.Height() );
287 m_aItemsRect = Rectangle( aItemsPos, aItemsSize );
289 if ( !impl_fitItems( io_rItems ) )
291 // assumption was wrong, the items do not fit => calculate rects for the scroll buttons
292 const Size aButtonSize( BUTTON_FLOW_WIDTH, i_rActualOutputSize.Height() - OUTER_SPACE_TOP - OUTER_SPACE_BOTTOM );
294 aButtonBackPos = Point( OUTER_SPACE_LEFT, OUTER_SPACE_TOP );
295 m_aButtonBackRect = Rectangle( aButtonBackPos, aButtonSize );
297 aButtonForwardPos = Point( i_rActualOutputSize.Width() - BUTTON_FLOW_WIDTH - OUTER_SPACE_RIGHT, OUTER_SPACE_TOP );
298 m_aButtonForwardRect = Rectangle( aButtonForwardPos, aButtonSize );
300 aItemsPos.X() = aButtonBackPos.X() + aButtonSize.Width() + BUTTON_FLOW_SPACE;
301 aItemsSize.Width() = aButtonForwardPos.X() - BUTTON_FLOW_SPACE - aItemsPos.X();
302 m_aItemsRect = Rectangle( aItemsPos, aItemsSize );
304 // fit items, again. In the TABITEM_AUTO case, the smaller playground for the items might lead to another
305 // item content.
306 impl_fitItems( io_rItems );
310 //------------------------------------------------------------------------------------------------------------------
311 Point TabBarGeometry::getFirstItemPosition() const
313 return Point( m_aItemsInset.Left(), m_aItemsInset.Top() );
316 //......................................................................................................................
317 } // namespace svt
318 //......................................................................................................................
320 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */