summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2019-06-16 21:41:31 +0000
committerJan-Marek Glogowski <glogow@fbihome.de>2019-06-21 16:47:47 +0200
commit6540912ae1a570fd8c2318f77b757e07b87c0707 (patch)
treef2da76bb78e4d785915be2ceb282d519600f49f2
parentd25e5069176ab53cdc917e3501a81e9546ec46f7 (diff)
VCL merge most of NotebookbarTabControlBase
NotebookbarTabControlBase (NBBTCB) tried to be clever and save a bool per TabControl page, by not adding a mbVisible to the ImplTabItem and misuse mbEnabled. The result is not only a bug with tab highlighting in notebook bars, but also a lot of duplicate code and additional virtual functions. Normal TabControls highlight correct. I'm not 100% sure about the dropped Resize()s, but the code in ImplPaint() and calculateRequisition() differs by three lines; which can be merged by adding the TabControl feature to hide tabs and not just disable them. I first tried to additionally merge ImplPlaceTabs() too, but the NBBTCB version differs much more and I didn't want to touch larger parts of TabControl. Change-Id: Ie6e18fb03b76b46e3627923eb1ac0f674c3eb7e8 Reviewed-on: https://gerrit.libreoffice.org/74126 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
-rw-r--r--include/vcl/tabctrl.hxx21
-rw-r--r--toolkit/source/awt/vclxtabpagecontainer.cxx2
-rw-r--r--vcl/source/control/tabctrl.cxx569
3 files changed, 154 insertions, 438 deletions
diff --git a/include/vcl/tabctrl.hxx b/include/vcl/tabctrl.hxx
index cf64e66efc64..956c5ece7a6b 100644
--- a/include/vcl/tabctrl.hxx
+++ b/include/vcl/tabctrl.hxx
@@ -64,8 +64,10 @@ protected:
using Control::ImplInitSettings;
SAL_DLLPRIVATE void ImplInitSettings( bool bBackground );
SAL_DLLPRIVATE ImplTabItem* ImplGetItem( sal_uInt16 nId ) const;
+ SAL_DLLPRIVATE ImplTabItem* ImplGetItem(const Point& rPt) const;
SAL_DLLPRIVATE Size ImplGetItemSize( ImplTabItem* pItem, long nMaxWidth );
SAL_DLLPRIVATE tools::Rectangle ImplGetTabRect( sal_uInt16 nPos, long nWidth = -1, long nHeight = -1 );
+ SAL_DLLPRIVATE tools::Rectangle ImplGetTabRect(const ImplTabItem*, long nWidth = -1, long nHeight = -1);
SAL_DLLPRIVATE void ImplChangeTabPage( sal_uInt16 nId, sal_uInt16 nOldId );
SAL_DLLPRIVATE bool ImplPosCurTabPage();
virtual void ImplActivateTabPage( bool bNext );
@@ -85,9 +87,8 @@ protected:
virtual void FillLayoutData() const override;
virtual const vcl::Font& GetCanonicalFont( const StyleSettings& _rStyle ) const override;
virtual const Color& GetCanonicalTextColor( const StyleSettings& _rStyle ) const override;
- SAL_DLLPRIVATE tools::Rectangle* ImplFindPartRect( const Point& rPt );
virtual bool ImplPlaceTabs( long nWidth );
- virtual void ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect);
+ SAL_DLLPRIVATE Size ImplCalculateRequisition(sal_uInt16& nHeaderHeight) const;
public:
TabControl( vcl::Window* pParent,
@@ -124,21 +125,23 @@ public:
sal_uInt16 nPos = TAB_APPEND );
void RemovePage( sal_uInt16 nPageId );
void Clear();
- void EnablePage( sal_uInt16 nPageId, bool bEnable = true );
+
+ void SetPageEnabled(sal_uInt16 nPageId, bool bEnable = true);
+ void SetPageVisible(sal_uInt16 nPageId, bool bVisible = true);
sal_uInt16 GetPagePos( sal_uInt16 nPageId ) const;
sal_uInt16 GetPageCount() const;
sal_uInt16 GetPageId( sal_uInt16 nPos ) const;
- virtual sal_uInt16 GetPageId( const Point& rPos ) const;
+ sal_uInt16 GetPageId(const Point& rPos) const;
sal_uInt16 GetPageId( const TabPage& rPage ) const;
sal_uInt16 GetPageId( const OString& rName ) const;
- virtual void SetCurPageId( sal_uInt16 nPageId );
+ void SetCurPageId(sal_uInt16 nPageId);
sal_uInt16 GetCurPageId() const;
- virtual void SelectTabPage( sal_uInt16 nPageId );
+ void SelectTabPage( sal_uInt16 nPageId );
- void SetTabPage( sal_uInt16 nPageId, TabPage* pPage );
+ void SetTabPage(sal_uInt16 nPageId, TabPage* pPage);
TabPage* GetTabPage( sal_uInt16 nPageId ) const;
void SetPageText( sal_uInt16 nPageId, const OUString& rText );
@@ -203,15 +206,11 @@ public:
ToolBox* GetToolBox() { return m_pShortcuts; }
PushButton* GetOpenMenu() { return m_pOpenMenu; }
- virtual sal_uInt16 GetPageId( const Point& rPos ) const override;
- virtual void SelectTabPage( sal_uInt16 nPageId ) override;
- virtual void SetCurPageId( sal_uInt16 nPageId ) override;
virtual Size calculateRequisition() const override;
static sal_uInt16 GetHeaderHeight();
protected:
virtual bool ImplPlaceTabs( long nWidth ) override;
- virtual void ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
virtual void ImplActivateTabPage( bool bNext ) override;
private:
diff --git a/toolkit/source/awt/vclxtabpagecontainer.cxx b/toolkit/source/awt/vclxtabpagecontainer.cxx
index 56e492ea8069..25ff686c5466 100644
--- a/toolkit/source/awt/vclxtabpagecontainer.cxx
+++ b/toolkit/source/awt/vclxtabpagecontainer.cxx
@@ -190,7 +190,7 @@ void SAL_CALL VCLXTabPageContainer::elementInserted( const css::container::Conta
pTabCtrl->SetHelpText(nPageID,xP->getToolTip());
pTabCtrl->SetPageImage(nPageID,TkResMgr::getImageFromURL(xP->getImageURL()));
pTabCtrl->SelectTabPage(nPageID);
- pTabCtrl->EnablePage(nPageID,xP->getEnabled());
+ pTabCtrl->SetPageEnabled(nPageID,xP->getEnabled());
m_aTabPages.push_back(xTabPage);
}
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index d5b9eeeeacfa..d23db1eaf9cf 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -56,12 +56,15 @@ struct ImplTabItem
tools::Rectangle maRect;
sal_uInt16 mnLine;
bool mbFullVisible;
- bool mbEnabled;
+ bool m_bEnabled; ///< the tab / page is selectable
+ bool m_bVisible; ///< the tab / page can be visible
Image maTabImage;
ImplTabItem()
: mnId( 0 ), mpTabPage( nullptr ),
- mnLine( 0 ), mbFullVisible( false ), mbEnabled( true )
+ mnLine( 0 ), mbFullVisible( false )
+ , m_bEnabled(true)
+ , m_bVisible(true)
{}
};
@@ -400,6 +403,9 @@ bool TabControl::ImplPlaceTabs( long nWidth )
for (auto & item : mpTabCtrlData->maItemList)
{
+ if (!item.m_bVisible)
+ continue;
+
Size aSize = ImplGetItemSize( &item, nMaxWidth );
bool bNewLine = false;
@@ -531,8 +537,8 @@ tools::Rectangle TabControl::ImplGetTabRect( sal_uInt16 nItemPos, long nWidth, l
long nW = nWidth-TAB_OFFSET*2;
long nH = nHeight-TAB_OFFSET*2;
return (nW > 0 && nH > 0)
- ? tools::Rectangle( Point( TAB_OFFSET, TAB_OFFSET ), Size( nW, nH ) )
- : tools::Rectangle();
+ ? tools::Rectangle(Point(TAB_OFFSET, TAB_OFFSET), Size(nW, nH))
+ : tools::Rectangle();
}
if ( nItemPos == TAB_PAGERECT )
@@ -546,19 +552,26 @@ tools::Rectangle TabControl::ImplGetTabRect( sal_uInt16 nItemPos, long nWidth, l
tools::Rectangle aRect = ImplGetTabRect( nLastPos, nWidth, nHeight );
if (aRect.IsEmpty())
return aRect;
+
long nW = nWidth-TAB_OFFSET*2;
long nH = nHeight-aRect.Bottom()-TAB_OFFSET*2;
- aRect = (nW > 0 && nH > 0)
+ return (nW > 0 && nH > 0)
? tools::Rectangle( Point( TAB_OFFSET, aRect.Bottom()+TAB_OFFSET ), Size( nW, nH ) )
: tools::Rectangle();
- return aRect;
}
- nWidth -= 1;
+ ImplTabItem* const pItem = (nItemPos < mpTabCtrlData->maItemList.size())
+ ? &mpTabCtrlData->maItemList[nItemPos] : nullptr;
+ return ImplGetTabRect(pItem, nWidth, nHeight);
+}
- if ( (nWidth <= 0) || (nHeight <= 0) )
+tools::Rectangle TabControl::ImplGetTabRect(const ImplTabItem* pItem, long nWidth, long nHeight)
+{
+ if ((nWidth <= 1) || (nHeight <= 0) || !pItem || !pItem->m_bVisible)
return tools::Rectangle();
+ nWidth -= 1;
+
if ( mbFormat || (mnLastWidth != nWidth) || (mnLastHeight != nHeight) )
{
vcl::Font aFont( GetFont() );
@@ -574,7 +587,7 @@ tools::Rectangle TabControl::ImplGetTabRect( sal_uInt16 nItemPos, long nWidth, l
mbFormat = false;
}
- return size_t(nItemPos) < mpTabCtrlData->maItemList.size() ? mpTabCtrlData->maItemList[nItemPos].maRect : tools::Rectangle();
+ return pItem->maRect;
}
void TabControl::ImplChangeTabPage( sal_uInt16 nId, sal_uInt16 nOldId )
@@ -763,7 +776,7 @@ void TabControl::ImplShowFocus()
void TabControl::ImplDrawItem(vcl::RenderContext& rRenderContext, ImplTabItem const * pItem, const tools::Rectangle& rCurRect,
bool bFirstInGroup, bool bLastInGroup )
{
- if (pItem->maRect.IsEmpty())
+ if (!pItem->m_bVisible || pItem->maRect.IsEmpty())
return;
const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
@@ -827,13 +840,12 @@ void TabControl::ImplDrawItem(vcl::RenderContext& rRenderContext, ImplTabItem co
{
nState |= ControlState::ROLLOVER;
for (auto const& item : mpTabCtrlData->maItemList)
- {
- if( (&item != pItem) && (item.maRect.IsInside(GetPointerPosPixel())))
+ if ((&item != pItem) && item.m_bVisible && item.maRect.IsInside(GetPointerPosPixel()))
{
nState &= ~ControlState::ROLLOVER; // avoid multiple highlighted tabs
break;
}
- }
+ assert(nState & ControlState::ROLLOVER);
}
bNativeOK = rRenderContext.IsNativeControlSupported(ControlType::TabItem, ControlPart::Entire);
@@ -923,7 +935,7 @@ void TabControl::ImplDrawItem(vcl::RenderContext& rRenderContext, ImplTabItem co
if (!pItem->maFormatText.isEmpty())
{
DrawTextFlags nStyle = DrawTextFlags::Mnemonic;
- if (!pItem->mbEnabled)
+ if (!pItem->m_bEnabled)
nStyle |= DrawTextFlags::Disable;
Color aColor(rStyleSettings.GetTabTextColor());
@@ -948,7 +960,7 @@ void TabControl::ImplDrawItem(vcl::RenderContext& rRenderContext, ImplTabItem co
Point aImgTL( nXPos, aRect.Top() );
if (aImageSize.Height() < aRect.GetHeight())
aImgTL.AdjustY((aRect.GetHeight() - aImageSize.Height()) / 2 );
- rRenderContext.DrawImage(aImgTL, pItem->maTabImage, pItem->mbEnabled ? DrawImageFlags::NONE : DrawImageFlags::Disable );
+ rRenderContext.DrawImage(aImgTL, pItem->maTabImage, pItem->m_bEnabled ? DrawImageFlags::NONE : DrawImageFlags::Disable );
}
}
@@ -1005,16 +1017,12 @@ IMPL_LINK( TabControl, ImplWindowEventListener, VclWindowEvent&, rEvent, void )
void TabControl::MouseButtonDown( const MouseEvent& rMEvt )
{
- if( mpTabCtrlData->mpListBox.get() == nullptr )
- {
- if( rMEvt.IsLeft() )
- {
- sal_uInt16 nPageId = GetPageId( rMEvt.GetPosPixel() );
- ImplTabItem* pItem = ImplGetItem( nPageId );
- if( pItem && pItem->mbEnabled )
- SelectTabPage( nPageId );
- }
- }
+ if (mpTabCtrlData->mpListBox.get() != nullptr || !rMEvt.IsLeft())
+ return;
+
+ ImplTabItem *pItem = ImplGetItem(rMEvt.GetPosPixel());
+ if (pItem && pItem->m_bEnabled)
+ SelectTabPage(pItem->mnId);
}
void TabControl::KeyInput( const KeyEvent& rKEvt )
@@ -1036,14 +1044,21 @@ void TabControl::KeyInput( const KeyEvent& rKEvt )
Control::KeyInput( rKEvt );
}
-void TabControl::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
+static bool lcl_canPaint(const vcl::RenderContext& rRenderContext, const tools::Rectangle& rDrawRect,
+ const tools::Rectangle& rItemRect)
{
- if (!(GetStyle() & WB_NOBORDER))
- ImplPaint(rRenderContext, rRect);
+ vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
+ aClipRgn.Intersect(rItemRect);
+ if (!rDrawRect.IsEmpty())
+ aClipRgn.Intersect(rDrawRect);
+ return !aClipRgn.IsEmpty();
}
-void TabControl::ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
+void TabControl::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
{
+ if (GetStyle() & WB_NOBORDER)
+ return;
+
HideFocus();
// reformat if needed
@@ -1091,31 +1106,16 @@ void TabControl::ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rect
if (HasFocus())
nState |= ControlState::FOCUSED;
- vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
- aClipRgn.Intersect(aRect);
- if (!rRect.IsEmpty())
- aClipRgn.Intersect(rRect);
-
- if (!aClipRgn.IsEmpty())
- {
+ if (lcl_canPaint(rRenderContext, rRect, aRect))
rRenderContext.DrawNativeControl(ControlType::TabPane, ControlPart::Entire,
aRect, nState, aControlValue, OUString());
- }
if (rRenderContext.IsNativeControlSupported(ControlType::TabHeader, ControlPart::Entire))
{
tools::Rectangle aHeaderRect(aRect.Left(), 0, aRect.Right(), aRect.Top());
-
- aClipRgn = rRenderContext.GetActiveClipRegion();
- aClipRgn.Intersect(aHeaderRect);
- if (!rRect.IsEmpty())
- aClipRgn.Intersect(rRect);
-
- if (!aClipRgn.IsEmpty())
- {
+ if (lcl_canPaint(rRenderContext, rRect, aHeaderRect))
rRenderContext.DrawNativeControl(ControlType::TabHeader, ControlPart::Entire,
aHeaderRect, nState, aControlValue, OUString());
- }
}
}
else
@@ -1195,18 +1195,8 @@ void TabControl::ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rect
{
ImplTabItem* pItem = &mpTabCtrlData->maItemList[idx];
- if (pItem != pCurItem)
- {
- vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
- aClipRgn.Intersect(pItem->maRect);
- if (!rRect.IsEmpty())
- aClipRgn.Intersect(rRect);
- if (!aClipRgn.IsEmpty())
- {
- ImplDrawItem(rRenderContext, pItem, aCurRect,
- pItem == pFirstTab, pItem == pLastTab);
- }
- }
+ if (pItem != pCurItem && pItem->m_bVisible && lcl_canPaint(rRenderContext, rRect, pItem->maRect))
+ ImplDrawItem(rRenderContext, pItem, aCurRect, pItem == pFirstTab, pItem == pLastTab);
if (bDrawTabsRTL)
idx--;
@@ -1214,24 +1204,16 @@ void TabControl::ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rect
idx++;
}
- if (pCurItem)
- {
- vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
- aClipRgn.Intersect(pCurItem->maRect);
- if (!rRect.IsEmpty())
- aClipRgn.Intersect(rRect);
- if (!aClipRgn.IsEmpty())
- {
- ImplDrawItem(rRenderContext, pCurItem, aCurRect,
- pCurItem == pFirstTab, pCurItem == pLastTab);
- }
- }
+ if (pCurItem && lcl_canPaint(rRenderContext, rRect, pCurItem->maRect))
+ ImplDrawItem(rRenderContext, pCurItem, aCurRect, pCurItem == pFirstTab, pCurItem == pLastTab);
}
if (HasFocus())
ImplShowFocus();
mbSmallInvalidate = true;
+
+ Control::Paint(rRenderContext, rRect);
}
void TabControl::setAllocation(const Size &rAllocation)
@@ -1263,8 +1245,9 @@ void TabControl::setAllocation(const Size &rAllocation)
long nNewWidth = aNewSize.Width();
for (auto const& item : mpTabCtrlData->maItemList)
{
- if ( !item.mbFullVisible ||
- (item.maRect.Right()-2 >= nNewWidth) )
+ if (!item.m_bVisible)
+ continue;
+ if (!item.mbFullVisible || (item.maRect.Right()-2 >= nNewWidth))
{
mbSmallInvalidate = false;
break;
@@ -1501,21 +1484,22 @@ void TabControl::DataChanged( const DataChangedEvent& rDCEvt )
}
}
-tools::Rectangle* TabControl::ImplFindPartRect( const Point& rPt )
+ImplTabItem* TabControl::ImplGetItem(const Point& rPt) const
{
ImplTabItem* pFoundItem = nullptr;
int nFound = 0;
for (auto & item : mpTabCtrlData->maItemList)
{
- if ( item.maRect.IsInside( rPt ) )
+ if (item.m_bVisible && item.maRect.IsInside(rPt))
{
- // assure that only one tab is highlighted at a time
nFound++;
pFoundItem = &item;
}
}
+
// assure that only one tab is highlighted at a time
- return nFound == 1 ? &pFoundItem->maRect : nullptr;
+ assert(nFound <= 1);
+ return nFound == 1 ? pFoundItem : nullptr;
}
bool TabControl::PreNotify( NotifyEvent& rNEvt )
@@ -1529,33 +1513,35 @@ bool TabControl::PreNotify( NotifyEvent& rNEvt )
// trigger redraw if mouse over state has changed
if( IsNativeControlSupported(ControlType::TabItem, ControlPart::Entire) )
{
- tools::Rectangle* pRect = ImplFindPartRect( GetPointerPosPixel() );
- tools::Rectangle* pLastRect = ImplFindPartRect( GetLastPointerPosPixel() );
- if( pRect != pLastRect || (pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow()) )
+ ImplTabItem *pItem = ImplGetItem(GetPointerPosPixel());
+ ImplTabItem *pLastItem = ImplGetItem(GetLastPointerPosPixel());
+ if ((pItem != pLastItem) || pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow())
{
vcl::Region aClipRgn;
- if( pLastRect )
+ if (pLastItem)
{
// allow for slightly bigger tabitems
// as used by gtk
// TODO: query for the correct sizes
- tools::Rectangle aRect(*pLastRect);
+ tools::Rectangle aRect(pLastItem->maRect);
aRect.AdjustLeft( -2 );
aRect.AdjustRight(2 );
aRect.AdjustTop( -3 );
aClipRgn.Union( aRect );
}
- if( pRect )
+
+ if (pItem)
{
// allow for slightly bigger tabitems
// as used by gtk
// TODO: query for the correct sizes
- tools::Rectangle aRect(*pRect);
+ tools::Rectangle aRect(pItem->maRect);
aRect.AdjustLeft( -2 );
aRect.AdjustRight(2 );
aRect.AdjustTop( -3 );
aClipRgn.Union( aRect );
}
+
if( !aClipRgn.IsEmpty() )
Invalidate( aClipRgn );
}
@@ -1719,27 +1705,46 @@ void TabControl::Clear()
CallEventListeners( VclEventId::TabpageRemovedAll );
}
-void TabControl::EnablePage( sal_uInt16 i_nPageId, bool i_bEnable )
+void TabControl::SetPageEnabled( sal_uInt16 i_nPageId, bool i_bEnable )
{
ImplTabItem* pItem = ImplGetItem( i_nPageId );
- if ( pItem && pItem->mbEnabled != i_bEnable )
+ if (pItem && pItem->m_bEnabled != i_bEnable)
{
- pItem->mbEnabled = i_bEnable;
+ pItem->m_bEnabled = i_bEnable;
+ if (!pItem->m_bVisible)
+ return;
+
mbFormat = true;
if( mpTabCtrlData->mpListBox )
mpTabCtrlData->mpListBox->SetEntryFlags( GetPagePos( i_nPageId ),
i_bEnable ? ListBoxEntryFlags::NONE : (ListBoxEntryFlags::DisableSelection | ListBoxEntryFlags::DrawDisabled) );
- if( pItem->mnId == mnCurPageId )
- {
- // SetCurPageId will change to an enabled page
+
+ // SetCurPageId will change to a valid page
+ if (pItem->mnId == mnCurPageId)
SetCurPageId( mnCurPageId );
- }
else if ( IsUpdateMode() )
Invalidate();
}
}
+void TabControl::SetPageVisible( sal_uInt16 nPageId, bool bVisible )
+{
+ ImplTabItem* pItem = ImplGetItem( nPageId );
+ if (!pItem || pItem->m_bVisible == bVisible)
+ return;
+
+ pItem->m_bVisible = bVisible;
+ pItem->maRect.SetEmpty();
+ mbFormat = true;
+
+ // SetCurPageId will change to a valid page
+ if (pItem->mnId == mnCurPageId)
+ SetCurPageId(mnCurPageId);
+ else if (IsUpdateMode())
+ Invalidate();
+}
+
sal_uInt16 TabControl::GetPageCount() const
{
return static_cast<sal_uInt16>(mpTabCtrlData->maItemList.size());
@@ -1767,42 +1772,32 @@ sal_uInt16 TabControl::GetPagePos( sal_uInt16 nPageId ) const
sal_uInt16 TabControl::GetPageId( const Point& rPos ) const
{
- for( size_t i = 0; i < mpTabCtrlData->maItemList.size(); ++i )
- {
- if ( const_cast<TabControl*>(this)->ImplGetTabRect( static_cast<sal_uInt16>(i) ).IsInside( rPos ) )
- return mpTabCtrlData->maItemList[ i ].mnId;
- }
-
- return 0;
+ const auto &rList = mpTabCtrlData->maItemList;
+ const auto it = std::find_if(rList.begin(), rList.end(), [&rPos, this](const auto &item) {
+ return const_cast<TabControl*>(this)->ImplGetTabRect(&item).IsInside(rPos); });
+ return (it != rList.end()) ? it->mnId : 0;
}
sal_uInt16 TabControl::GetPageId( const TabPage& rPage ) const
{
- for (auto const& item : mpTabCtrlData->maItemList)
- {
- if ( item.mpTabPage == &rPage )
- return item.mnId;
- }
-
- return 0;
+ const auto &rList = mpTabCtrlData->maItemList;
+ const auto it = std::find_if(rList.begin(), rList.end(), [&rPage](const auto &item) {
+ return item.mpTabPage == &rPage; });
+ return (it != rList.end()) ? it->mnId : 0;
}
sal_uInt16 TabControl::GetPageId( const OString& rName ) const
{
- for (auto const& item : mpTabCtrlData->maItemList)
- {
- if ( item.maTabName == rName )
- return item.mnId;
- }
-
- return 0;
+ const auto &rList = mpTabCtrlData->maItemList;
+ const auto it = std::find_if(rList.begin(), rList.end(), [&rName](const auto &item) {
+ return item.maTabName == rName; });
+ return (it != rList.end()) ? it->mnId : 0;
}
void TabControl::SetCurPageId( sal_uInt16 nPageId )
{
sal_uInt16 nPos = GetPagePos( nPageId );
- while( nPos != TAB_PAGE_NOTFOUND &&
- ! mpTabCtrlData->maItemList[nPos].mbEnabled )
+ while (nPos != TAB_PAGE_NOTFOUND && !mpTabCtrlData->maItemList[nPos].m_bEnabled)
{
nPos++;
if( size_t(nPos) >= mpTabCtrlData->maItemList.size() )
@@ -2055,7 +2050,7 @@ tools::Rectangle TabControl::GetTabBounds( sal_uInt16 nPageId ) const
tools::Rectangle aRet;
ImplTabItem* pItem = ImplGetItem( nPageId );
- if(pItem)
+ if (pItem && pItem->m_bVisible)
aRet = pItem->maRect;
return aRet;
@@ -2075,7 +2070,7 @@ Point TabControl::GetItemsOffset() const
return Point();
}
-Size TabControl::calculateRequisition() const
+Size TabControl::ImplCalculateRequisition(sal_uInt16& nHeaderHeight) const
{
Size aOptimalPageSize(0, 0);
@@ -2122,8 +2117,11 @@ Size TabControl::calculateRequisition() const
tools::Rectangle aTabRect = pThis->ImplGetTabRect(nPos, aOptimalPageSize.Width(), LONG_MAX);
if (aTabRect.Bottom() > nTabLabelsBottom)
+ {
nTabLabelsBottom = aTabRect.Bottom();
- if (aTabRect.Right() > nTabLabelsRight)
+ nHeaderHeight = nTabLabelsBottom;
+ }
+ if (!aTabRect.IsEmpty() && aTabRect.Right() > nTabLabelsRight)
nTabLabelsRight = aTabRect.Right();
}
@@ -2137,6 +2135,12 @@ Size TabControl::calculateRequisition() const
return aOptimalSize;
}
+Size TabControl::calculateRequisition() const
+{
+ sal_uInt16 nHeaderHeight;
+ return ImplCalculateRequisition(nHeaderHeight);
+}
+
Size TabControl::GetOptimalSize() const
{
return calculateRequisition();
@@ -2201,10 +2205,7 @@ void NotebookbarTabControlBase::SetContext( vcl::EnumContext::Context eContext )
if (pPage)
{
- if (pPage->HasContext(eContext) || pPage->HasContext(vcl::EnumContext::Context::Any))
- EnablePage(nPageId);
- else
- EnablePage(nPageId, false);
+ SetPageVisible(nPageId, pPage->HasContext(eContext) || pPage->HasContext(vcl::EnumContext::Context::Any));
if (!bHandled && bLastContextWasSupported
&& pPage->HasContext(vcl::EnumContext::Context::Default))
@@ -2244,62 +2245,34 @@ void NotebookbarTabControlBase::SetIconClickHdl( Link<NotebookBar*, void> aHdl )
m_aIconClickHdl = aHdl;
}
-sal_uInt16 NotebookbarTabControlBase::GetPageId( const Point& rPos ) const
+static bool lcl_isValidPage(const ImplTabItem& rItem, bool& bFound)
{
- for( size_t i = 0; i < mpTabCtrlData->maItemList.size(); ++i )
- {
- if ( const_cast<NotebookbarTabControlBase*>(this)->ImplGetTabRect( static_cast<sal_uInt16>(i) ).IsInside( rPos ) )
- if ( mpTabCtrlData->maItemList[ i ].mbEnabled )
- return mpTabCtrlData->maItemList[ i ].mnId;
- }
-
- return 0;
-}
-
-void NotebookbarTabControlBase::SelectTabPage( sal_uInt16 nPageId )
-{
- TabControl::SelectTabPage( nPageId );
- Resize();
-}
-
-void NotebookbarTabControlBase::SetCurPageId( sal_uInt16 nPageId )
-{
- TabControl::SetCurPageId( nPageId );
- Resize();
- if ( nPageId == GetPageCount() )
- ImplActivateTabPage( true );
+ if (rItem.m_bVisible && rItem.m_bEnabled)
+ bFound = true;
+ return bFound;
}
void NotebookbarTabControlBase::ImplActivateTabPage( bool bNext )
{
- sal_uInt16 nCurPos = GetPagePos( GetCurPageId() );
+ const sal_uInt16 nOldPos = GetPagePos(GetCurPageId());
+ bool bFound = false;
+ sal_Int32 nCurPos = nOldPos;
- if ( bNext && nCurPos + 1 < GetPageCount() )
+ if (bNext)
{
- sal_uInt16 nOldPos = nCurPos;
- nCurPos++;
-
- ImplTabItem* pItem = &mpTabCtrlData->maItemList[nCurPos];
- while ( !pItem->mbEnabled && nCurPos + 1 < GetPageCount())
- {
- nCurPos++;
- pItem = &mpTabCtrlData->maItemList[nCurPos];
- }
-
- if ( !pItem->mbEnabled )
- nCurPos = nOldPos;
+ for (nCurPos++; nCurPos < GetPageCount(); nCurPos++)
+ if (lcl_isValidPage(mpTabCtrlData->maItemList[nCurPos], bFound))
+ break;
}
- else if ( !bNext && nCurPos )
+ else
{
- nCurPos--;
- ImplTabItem* pItem = &mpTabCtrlData->maItemList[nCurPos];
- while ( nCurPos && !pItem->mbEnabled )
- {
- nCurPos--;
- pItem = &mpTabCtrlData->maItemList[nCurPos];
- }
+ for (nCurPos--; nCurPos >= 0; nCurPos--)
+ if (lcl_isValidPage(mpTabCtrlData->maItemList[nCurPos], bFound))
+ break;
}
+ if (!bFound)
+ nCurPos = nOldPos;
SelectTabPage( TabControl::GetPageId( nCurPos ) );
}
@@ -2331,7 +2304,7 @@ bool NotebookbarTabControlBase::ImplPlaceTabs( long nWidth )
std::vector<sal_Int32> aWidths;
for (auto & item : mpTabCtrlData->maItemList)
{
- if( item.mbEnabled )
+ if (item.m_bVisible)
{
long aSize = ImplGetItemSize( &item, nMaxWidth ).getWidth();
if( !item.maText.isEmpty() && aSize < 100)
@@ -2358,12 +2331,10 @@ bool NotebookbarTabControlBase::ImplPlaceTabs( long nWidth )
for (auto & item : mpTabCtrlData->maItemList)
{
- Size aSize = ImplGetItemSize( &item, nMaxWidth );
-
- if ( !item.mbEnabled )
- {
+ if (!item.m_bVisible)
continue;
- }
+
+ Size aSize = ImplGetItemSize( &item, nMaxWidth );
// set minimum tab size
if( nFullWidth < nMaxWidth && !item.maText.isEmpty() && aSize.getWidth() < 100)
@@ -2409,263 +2380,9 @@ bool NotebookbarTabControlBase::ImplPlaceTabs( long nWidth )
return true;
}
-void NotebookbarTabControlBase::ImplPaint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
-{
- HideFocus();
-
- // reformat if needed
- tools::Rectangle aRect = ImplGetTabRect(TAB_PAGERECT);
-
- // find current item
- ImplTabItem* pCurItem = nullptr;
- for (auto & item : mpTabCtrlData->maItemList)
- {
- if (item.mnId == mnCurPageId)
- {
- pCurItem = &item;
- break;
- }
- }
-
- // Draw the TabPage border
- const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
- tools::Rectangle aCurRect;
- aRect.AdjustLeft( -(TAB_OFFSET) );
- aRect.AdjustTop( -(TAB_OFFSET) );
- aRect.AdjustRight(TAB_OFFSET );
- aRect.AdjustBottom(TAB_OFFSET );
-
- // if we have an invisible tabpage or no tabpage at all the tabpage rect should be
- // increased to avoid round corners that might be drawn by a theme
- // in this case we're only interested in the top border of the tabpage because the tabitems are used
- // standalone (eg impress)
- bool bNoTabPage = false;
- TabPage* pCurPage = pCurItem ? pCurItem->mpTabPage.get() : nullptr;
- if (!pCurPage || !pCurPage->IsVisible())
- {
- bNoTabPage = true;
- aRect.AdjustLeft( -10 );
- aRect.AdjustRight(10 );
- }
-
- if (rRenderContext.IsNativeControlSupported(ControlType::TabPane, ControlPart::Entire))
- {
- const ImplControlValue aControlValue;
-
- ControlState nState = ControlState::ENABLED;
- if (!IsEnabled())
- nState &= ~ControlState::ENABLED;
- if (HasFocus())
- nState |= ControlState::FOCUSED;
-
- vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
- aClipRgn.Intersect(aRect);
- if (!rRect.IsEmpty())
- aClipRgn.Intersect(rRect);
-
- if (!aClipRgn.IsEmpty())
- {
- rRenderContext.DrawNativeControl(ControlType::TabPane, ControlPart::Entire,
- aRect, nState, aControlValue, OUString());
- }
-
- if (rRenderContext.IsNativeControlSupported(ControlType::TabHeader, ControlPart::Entire))
- {
- tools::Rectangle aHeaderRect(aRect.Left(), 0, aRect.Right(), aRect.Top());
-
- aClipRgn = rRenderContext.GetActiveClipRegion();
- aClipRgn.Intersect(aHeaderRect);
- if (!rRect.IsEmpty())
- aClipRgn.Intersect(rRect);
-
- if (!aClipRgn.IsEmpty())
- {
- rRenderContext.DrawNativeControl(ControlType::TabHeader, ControlPart::Entire,
- aHeaderRect, nState, aControlValue, OUString());
- }
- }
- }
- else
- {
- long nTopOff = 1;
- if (!(rStyleSettings.GetOptions() & StyleSettingsOptions::Mono))
- rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
- else
- rRenderContext.SetLineColor(COL_BLACK);
- if (pCurItem && !pCurItem->maRect.IsEmpty())
- {
- aCurRect = pCurItem->maRect;
- rRenderContext.DrawLine(aRect.TopLeft(), Point(aCurRect.Left() - 2, aRect.Top()));
- if (aCurRect.Right() + 1 < aRect.Right())
- {
- rRenderContext.DrawLine(Point(aCurRect.Right(), aRect.Top()), aRect.TopRight());
- }
- else
- {
- nTopOff = 0;
- }
- }
- else
- rRenderContext.DrawLine(aRect.TopLeft(), aRect.TopRight());
-
- rRenderContext.DrawLine(aRect.TopLeft(), aRect.BottomLeft());
-
- if (!(rStyleSettings.GetOptions() & StyleSettingsOptions::Mono))
- {
- // if we have not tab page the bottom line of the tab page
- // directly touches the tab items, so choose a color that fits seamlessly
- if (bNoTabPage)
- rRenderContext.SetLineColor(rStyleSettings.GetDialogColor());
- else
- rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
- rRenderContext.DrawLine(Point(1, aRect.Bottom() - 1), Point(aRect.Right() - 1, aRect.Bottom() - 1));
- rRenderContext.DrawLine(Point(aRect.Right() - 1, aRect.Top() + nTopOff), Point(aRect.Right() - 1, aRect.Bottom() - 1));
- if (bNoTabPage)
- rRenderContext.SetLineColor(rStyleSettings.GetDialogColor());
- else
- rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
- rRenderContext.DrawLine(Point(0, aRect.Bottom()), Point(aRect.Right(), aRect.Bottom()));
- rRenderContext.DrawLine(Point(aRect.Right(), aRect.Top() + nTopOff), Point(aRect.Right(), aRect.Bottom()));
- }
- else
- {
- rRenderContext.DrawLine(aRect.TopRight(), aRect.BottomRight());
- rRenderContext.DrawLine(aRect.BottomLeft(), aRect.BottomRight());
- }
- }
-
- if (!mpTabCtrlData->maItemList.empty() && mpTabCtrlData->mpListBox == nullptr)
- {
- // Some native toolkits (GTK+) draw tabs right-to-left, with an
- // overlap between adjacent tabs
- bool bDrawTabsRTL = rRenderContext.IsNativeControlSupported(ControlType::TabItem, ControlPart::TabsDrawRtl);
- ImplTabItem* pFirstTab = nullptr;
- ImplTabItem* pLastTab = nullptr;
- size_t idx;
-
- // Event though there is a tab overlap with GTK+, the first tab is not
- // overlapped on the left side. Other toolkits ignore this option.
- if (bDrawTabsRTL)
- {
- pFirstTab = mpTabCtrlData->maItemList.data();
- pLastTab = pFirstTab + mpTabCtrlData->maItemList.size() - 1;
- idx = mpTabCtrlData->maItemList.size() - 1;
- }
- else
- {
- pLastTab = mpTabCtrlData->maItemList.data();
- pFirstTab = pLastTab + mpTabCtrlData->maItemList.size() - 1;
- idx = 0;
- }
-
- while (idx < mpTabCtrlData->maItemList.size())
- {
- ImplTabItem* pItem = &mpTabCtrlData->maItemList[idx];
-
- if ((pItem != pCurItem) && (pItem->mbEnabled))
- {
- vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
- aClipRgn.Intersect(pItem->maRect);
- if (!rRect.IsEmpty())
- aClipRgn.Intersect(rRect);
- if (!aClipRgn.IsEmpty())
- {
- ImplDrawItem(rRenderContext, pItem, aCurRect,
- pItem == pFirstTab, pItem == pLastTab);
- }
- }
-
- if (bDrawTabsRTL)
- idx--;
- else
- idx++;
- }
-
- if (pCurItem)
- {
- vcl::Region aClipRgn(rRenderContext.GetActiveClipRegion());
- aClipRgn.Intersect(pCurItem->maRect);
- if (!rRect.IsEmpty())
- aClipRgn.Intersect(rRect);
- if (!aClipRgn.IsEmpty())
- {
- ImplDrawItem(rRenderContext, pCurItem, aCurRect,
- pCurItem == pFirstTab, pCurItem == pLastTab);
- }
- }
- }
-
- if (HasFocus())
- ImplShowFocus();
-
- mbSmallInvalidate = true;
-
- Control::Paint(rRenderContext, rRect);
-}
-
Size NotebookbarTabControlBase::calculateRequisition() const
{
- Size aOptimalPageSize(0, 0);
-
- sal_uInt16 nOrigPageId = GetCurPageId();
- for (auto const& item : mpTabCtrlData->maItemList)
- {
- const TabPage *pPage = item.mpTabPage;
- //it's a real nuisance if the page is not inserted yet :-(
- //We need to force all tabs to exist to get overall optimal size for dialog
- if (!pPage)
- {
- NotebookbarTabControlBase *pThis = const_cast<NotebookbarTabControlBase*>(this);
- pThis->SetCurPageId(item.mnId);
- pThis->ActivatePage();
- pPage = item.mpTabPage;
- }
-
- if (!pPage)
- continue;
-
- Size aPageSize(VclContainer::getLayoutRequisition(*pPage));
-
- if (aPageSize.Width() > aOptimalPageSize.Width())
- aOptimalPageSize.setWidth( aPageSize.Width() );
- if (aPageSize.Height() > aOptimalPageSize.Height())
- aOptimalPageSize.setHeight( aPageSize.Height() );
- }
-
- //fdo#61940 If we were forced to activate pages in order to on-demand
- //create them to get their optimal size, then switch back to the original
- //page and re-activate it
- if (nOrigPageId != GetCurPageId())
- {
- NotebookbarTabControlBase *pThis = const_cast<NotebookbarTabControlBase*>(this);
- pThis->SetCurPageId(nOrigPageId);
- pThis->ActivatePage();
- }
-
- long nTabLabelsBottom = 0, nTabLabelsRight = 0;
- for (sal_uInt16 nPos(0), sizeList(static_cast <sal_uInt16> (mpTabCtrlData->maItemList.size()));
- nPos < sizeList; ++nPos)
- {
- NotebookbarTabControlBase* pThis = const_cast<NotebookbarTabControlBase*>(this);
-
- tools::Rectangle aTabRect = pThis->ImplGetTabRect(nPos, aOptimalPageSize.Width(), LONG_MAX);
- if (aTabRect.Bottom() > nTabLabelsBottom)
- {
- nTabLabelsBottom = aTabRect.Bottom();
- m_nHeaderHeight = aTabRect.Bottom();
- }
- if (aTabRect.Right() > nTabLabelsRight)
- nTabLabelsRight = aTabRect.Right();
- }
-
- Size aOptimalSize(aOptimalPageSize);
- aOptimalSize.AdjustHeight(nTabLabelsBottom );
- aOptimalSize.setWidth( std::max(nTabLabelsRight, aOptimalSize.Width()) );
-
- aOptimalSize.AdjustWidth(TAB_OFFSET * 2 );
- aOptimalSize.AdjustHeight(TAB_OFFSET * 2 );
-
- return aOptimalSize;
+ return TabControl::ImplCalculateRequisition(m_nHeaderHeight);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */