summaryrefslogtreecommitdiffstats
path: root/vcl/source/treelist/svlbitm.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/treelist/svlbitm.cxx')
-rw-r--r--vcl/source/treelist/svlbitm.cxx551
1 files changed, 551 insertions, 0 deletions
diff --git a/vcl/source/treelist/svlbitm.cxx b/vcl/source/treelist/svlbitm.cxx
new file mode 100644
index 0000000000..26b3da4547
--- /dev/null
+++ b/vcl/source/treelist/svlbitm.cxx
@@ -0,0 +1,551 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <utility>
+#include <vcl/toolkit/treelistbox.hxx>
+#include <vcl/toolkit/svlbitm.hxx>
+#include <vcl/toolkit/treelistentry.hxx>
+#include <vcl/toolkit/viewdataentry.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/toolkit/button.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/salnativewidgets.hxx>
+#include <vcl/settings.hxx>
+
+struct SvLBoxButtonData_Impl
+{
+ SvTreeListEntry* pEntry;
+ SvLBoxButton* pBox;
+ bool bDefaultImages;
+ bool bShowRadioButton;
+
+ SvLBoxButtonData_Impl() : pEntry(nullptr), pBox(nullptr), bDefaultImages(false), bShowRadioButton(false) {}
+};
+
+void SvLBoxButtonData::InitData( bool _bRadioBtn, const Control* pCtrl )
+{
+ nWidth = nHeight = 0;
+
+ aBmps.resize(int(SvBmp::HITRISTATE)+1);
+
+ bDataOk = false;
+ pImpl->bDefaultImages = true;
+ pImpl->bShowRadioButton = _bRadioBtn;
+
+ SetDefaultImages( pCtrl );
+}
+
+SvLBoxButtonData::SvLBoxButtonData( const Control* pControlForSettings, bool _bRadioBtn )
+ : pImpl( new SvLBoxButtonData_Impl )
+{
+ InitData( _bRadioBtn, pControlForSettings );
+}
+
+SvLBoxButtonData::~SvLBoxButtonData()
+{
+}
+
+void SvLBoxButtonData::CallLink()
+{
+ aLink.Call( this );
+}
+
+SvBmp SvLBoxButtonData::GetIndex( SvItemStateFlags nItemState )
+{
+ SvBmp nIdx;
+ if (nItemState == SvItemStateFlags::UNCHECKED)
+ nIdx = SvBmp::UNCHECKED;
+ else if (nItemState == SvItemStateFlags::CHECKED)
+ nIdx = SvBmp::CHECKED;
+ else if (nItemState == SvItemStateFlags::TRISTATE)
+ nIdx = SvBmp::TRISTATE;
+ else if (nItemState == (SvItemStateFlags::UNCHECKED | SvItemStateFlags::HIGHLIGHTED))
+ nIdx = SvBmp::HIUNCHECKED;
+ else if (nItemState == (SvItemStateFlags::CHECKED | SvItemStateFlags::HIGHLIGHTED))
+ nIdx = SvBmp::HICHECKED;
+ else if (nItemState == (SvItemStateFlags::TRISTATE | SvItemStateFlags::HIGHLIGHTED))
+ nIdx = SvBmp::HITRISTATE;
+ else
+ nIdx = SvBmp::UNCHECKED;
+ return nIdx;
+}
+
+void SvLBoxButtonData::SetWidthAndHeight()
+{
+ Size aSize = aBmps[int(SvBmp::UNCHECKED)].GetSizePixel();
+ nWidth = aSize.Width();
+ nHeight = aSize.Height();
+ bDataOk = true;
+}
+
+void SvLBoxButtonData::StoreButtonState(SvTreeListEntry* pActEntry, SvLBoxButton* pActBox)
+{
+ pImpl->pEntry = pActEntry;
+ pImpl->pBox = pActBox;
+}
+
+SvButtonState SvLBoxButtonData::ConvertToButtonState( SvItemStateFlags nItemFlags )
+{
+ nItemFlags &= SvItemStateFlags::UNCHECKED |
+ SvItemStateFlags::CHECKED |
+ SvItemStateFlags::TRISTATE;
+ switch( nItemFlags )
+ {
+ case SvItemStateFlags::UNCHECKED:
+ return SvButtonState::Unchecked;
+ case SvItemStateFlags::CHECKED:
+ return SvButtonState::Checked;
+ case SvItemStateFlags::TRISTATE:
+ return SvButtonState::Tristate;
+ default:
+ return SvButtonState::Unchecked;
+ }
+}
+
+SvTreeListEntry* SvLBoxButtonData::GetActEntry() const
+{
+ assert(pImpl && "-SvLBoxButtonData::GetActEntry(): don't use me that way!");
+ return pImpl->pEntry;
+}
+
+SvLBoxButton* SvLBoxButtonData::GetActBox() const
+{
+ assert(pImpl && "-SvLBoxButtonData::GetActBox(): don't use me that way!");
+ return pImpl->pBox;
+}
+
+void SvLBoxButtonData::SetDefaultImages( const Control* pCtrl )
+{
+ const AllSettings& rSettings = pCtrl? pCtrl->GetSettings() : Application::GetSettings();
+
+ if ( pImpl->bShowRadioButton )
+ {
+ SetImage(SvBmp::UNCHECKED, RadioButton::GetRadioImage( rSettings, DrawButtonFlags::Default ) );
+ SetImage(SvBmp::CHECKED, RadioButton::GetRadioImage( rSettings, DrawButtonFlags::Checked ) );
+ SetImage(SvBmp::HICHECKED, RadioButton::GetRadioImage( rSettings, DrawButtonFlags::Checked | DrawButtonFlags::Pressed ) );
+ SetImage(SvBmp::HIUNCHECKED, RadioButton::GetRadioImage( rSettings, DrawButtonFlags::Default | DrawButtonFlags::Pressed ) );
+ SetImage(SvBmp::TRISTATE, RadioButton::GetRadioImage( rSettings, DrawButtonFlags::DontKnow ) );
+ SetImage(SvBmp::HITRISTATE, RadioButton::GetRadioImage( rSettings, DrawButtonFlags::DontKnow | DrawButtonFlags::Pressed ) );
+ }
+ else
+ {
+ SetImage(SvBmp::UNCHECKED, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::Default ) );
+ SetImage(SvBmp::CHECKED, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::Checked ) );
+ SetImage(SvBmp::HICHECKED, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::Checked | DrawButtonFlags::Pressed ) );
+ SetImage(SvBmp::HIUNCHECKED, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::Default | DrawButtonFlags::Pressed ) );
+ SetImage(SvBmp::TRISTATE, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::DontKnow ) );
+ SetImage(SvBmp::HITRISTATE, CheckBox::GetCheckImage( rSettings, DrawButtonFlags::DontKnow | DrawButtonFlags::Pressed ) );
+ }
+}
+
+bool SvLBoxButtonData::HasDefaultImages() const
+{
+ return pImpl->bDefaultImages;
+}
+
+bool SvLBoxButtonData::IsRadio() const {
+ return pImpl->bShowRadioButton;
+}
+
+// ***************************************************************
+// class SvLBoxString
+// ***************************************************************
+
+
+SvLBoxString::SvLBoxString(OUString aStr)
+ : mbEmphasized(false)
+ , mbCustom(false)
+ , mfAlign(0.0)
+ , maText(std::move(aStr))
+{
+}
+
+SvLBoxString::SvLBoxString()
+ : mbEmphasized(false)
+ , mbCustom(false)
+ , mfAlign(0.0)
+{
+}
+
+SvLBoxString::~SvLBoxString()
+{
+}
+
+SvLBoxItemType SvLBoxString::GetType() const
+{
+ return SvLBoxItemType::String;
+}
+
+namespace
+{
+ void drawSeparator(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRegion)
+ {
+ Color aOldLineColor(rRenderContext.GetLineColor());
+ const StyleSettings& rStyle = rRenderContext.GetSettings().GetStyleSettings();
+ Point aTmpPos = rRegion.TopLeft();
+ Size aSize = rRegion.GetSize();
+ aTmpPos.AdjustY(aSize.Height() / 2 );
+ rRenderContext.SetLineColor(rStyle.GetShadowColor());
+ rRenderContext.DrawLine(aTmpPos, Point(aSize.Width() + aTmpPos.X(), aTmpPos.Y()));
+ rRenderContext.SetLineColor(aOldLineColor);
+ }
+}
+
+void SvLBoxString::Paint(
+ const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext,
+ const SvViewDataEntry* /*pView*/, const SvTreeListEntry& rEntry)
+{
+ DrawTextFlags nStyle = (rDev.IsEnabled() && !mbDisabled) ? DrawTextFlags::NONE : DrawTextFlags::Disable;
+ if (bool(rEntry.GetFlags() & SvTLEntryFlags::IS_SEPARATOR))
+ {
+ Point aStartPos(0, rPos.Y() - 2);
+ tools::Rectangle aRegion(aStartPos, Size(rDev.GetSizePixel().Width(), 4));
+ drawSeparator(rRenderContext, aRegion);
+ return;
+ }
+
+ Size aSize;
+ if (rDev.TextCenterAndClipEnabled())
+ {
+ nStyle |= DrawTextFlags::PathEllipsis | DrawTextFlags::Center;
+ aSize.setWidth( rDev.GetEntryWidth() );
+ }
+ else
+ {
+ if (mfAlign < 0.5 )
+ {
+ nStyle |= DrawTextFlags::Left;
+ aSize.setWidth(GetWidth(&rDev, &rEntry));
+ }
+ else if (mfAlign == 0.5)
+ {
+ nStyle |= DrawTextFlags::Center;
+ aSize.setWidth(rDev.GetBoundingRect(&rEntry).getOpenWidth());
+ }
+ else if (mfAlign > 0.5)
+ {
+ nStyle |= DrawTextFlags::Right;
+ aSize.setWidth(rDev.GetBoundingRect(&rEntry).getOpenWidth());
+ }
+ }
+ aSize.setHeight(GetHeight(&rDev, &rEntry));
+
+ if (mbEmphasized)
+ {
+ rRenderContext.Push();
+ vcl::Font aFont(rRenderContext.GetFont());
+ aFont.SetWeight(WEIGHT_BOLD);
+ rRenderContext.SetFont(aFont);
+ }
+
+ tools::Rectangle aRect(rPos, aSize);
+
+ if (mbCustom)
+ rDev.DrawCustomEntry(rRenderContext, aRect, rEntry);
+ else
+ rRenderContext.DrawText(aRect, maText, nStyle);
+
+ if (mbEmphasized)
+ rRenderContext.Pop();
+}
+
+std::unique_ptr<SvLBoxItem> SvLBoxString::Clone(SvLBoxItem const * pSource) const
+{
+ std::unique_ptr<SvLBoxString> pNew(new SvLBoxString);
+
+ const SvLBoxString* pOther = static_cast<const SvLBoxString*>(pSource);
+ pNew->maText = pOther->maText;
+ pNew->mbEmphasized = pOther->mbEmphasized;
+ pNew->mbCustom = pOther->mbCustom;
+ pNew->mfAlign = pOther->mfAlign;
+
+ return std::unique_ptr<SvLBoxItem>(pNew.release());
+}
+
+void SvLBoxString::InitViewData(
+ SvTreeListBox* pView, SvTreeListEntry* pEntry, SvViewDataItem* pViewData)
+{
+ if( !pViewData )
+ pViewData = pView->GetViewDataItem( pEntry, this );
+
+ if (bool(pEntry->GetFlags() & SvTLEntryFlags::IS_SEPARATOR))
+ {
+ pViewData->mnWidth = -1;
+ pViewData->mnHeight = 0;
+ return;
+ }
+
+ if (mbEmphasized)
+ {
+ pView->GetOutDev()->Push();
+ vcl::Font aFont( pView->GetFont());
+ aFont.SetWeight(WEIGHT_BOLD);
+ pView->Control::SetFont( aFont );
+ }
+
+ if (mbCustom)
+ {
+ Size aSize = pView->MeasureCustomEntry(*pView->GetOutDev(), *pEntry);
+ pViewData->mnWidth = aSize.Width();
+ pViewData->mnHeight = aSize.Height();
+ }
+ else
+ {
+ pViewData->mnWidth = -1; // calc on demand
+ pViewData->mnHeight = pView->GetTextHeight();
+ }
+
+ if (mbEmphasized)
+ pView->GetOutDev()->Pop();
+}
+
+int SvLBoxString::CalcWidth(const SvTreeListBox* pView) const
+{
+ return pView->GetTextWidth(maText);
+}
+
+// ***************************************************************
+// class SvLBoxButton
+// ***************************************************************
+
+
+SvLBoxButton::SvLBoxButton( SvLBoxButtonData* pBData )
+ : isVis(true)
+ , pData(pBData)
+ , nItemFlags(SvItemStateFlags::NONE)
+{
+ SetStateUnchecked();
+}
+
+SvLBoxButton::SvLBoxButton()
+ : isVis(false)
+ , pData(nullptr)
+ , nItemFlags(SvItemStateFlags::NONE)
+{
+ SetStateUnchecked();
+}
+
+SvLBoxButton::~SvLBoxButton()
+{
+}
+
+SvLBoxItemType SvLBoxButton::GetType() const
+{
+ return SvLBoxItemType::Button;
+}
+
+void SvLBoxButton::ClickHdl( SvTreeListEntry* pEntry )
+{
+ if ( IsStateChecked() )
+ SetStateUnchecked();
+ else
+ SetStateChecked();
+ pData->StoreButtonState(pEntry, this);
+ pData->CallLink();
+}
+
+void SvLBoxButton::Paint(
+ const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext,
+ const SvViewDataEntry* /*pView*/, const SvTreeListEntry& /*rEntry*/)
+{
+ SvBmp nIndex = SvLBoxButtonData::GetIndex(nItemFlags);
+ DrawImageFlags nStyle = (rDev.IsEnabled() && !mbDisabled) ? DrawImageFlags::NONE : DrawImageFlags::Disable;
+
+ //Native drawing
+ bool bNativeOK = false;
+ ControlType eCtrlType = (pData->IsRadio())? ControlType::Radiobutton : ControlType::Checkbox;
+ if ( rRenderContext.IsNativeControlSupported( eCtrlType, ControlPart::Entire) )
+ {
+ Size aSize(pData->Width(), pData->Height());
+ ImplAdjustBoxSize(aSize, eCtrlType, rRenderContext);
+ ImplControlValue aControlValue;
+ tools::Rectangle aCtrlRegion( rPos, aSize );
+ ControlState nState = ControlState::NONE;
+
+ //states ControlState::DEFAULT, ControlState::PRESSED and ControlState::ROLLOVER are not implemented
+ if (IsStateHilighted())
+ nState |= ControlState::FOCUSED;
+ if (nStyle != DrawImageFlags::Disable)
+ nState |= ControlState::ENABLED;
+ if (IsStateChecked())
+ aControlValue.setTristateVal(ButtonValue::On);
+ else if (IsStateUnchecked())
+ aControlValue.setTristateVal(ButtonValue::Off);
+ else if (IsStateTristate())
+ aControlValue.setTristateVal( ButtonValue::Mixed );
+
+ if (isVis)
+ bNativeOK = rRenderContext.DrawNativeControl(eCtrlType, ControlPart::Entire,
+ aCtrlRegion, nState, aControlValue, OUString());
+ }
+
+ if (!bNativeOK && isVis)
+ rRenderContext.DrawImage(rPos, pData->GetImage(nIndex), nStyle);
+}
+
+std::unique_ptr<SvLBoxItem> SvLBoxButton::Clone(SvLBoxItem const * pSource) const
+{
+ std::unique_ptr<SvLBoxButton> pNew(new SvLBoxButton);
+ pNew->pData = static_cast<SvLBoxButton const *>(pSource)->pData;
+ return std::unique_ptr<SvLBoxItem>(pNew.release());
+}
+
+void SvLBoxButton::ImplAdjustBoxSize(Size& io_rSize, ControlType i_eType, vcl::RenderContext const & rRenderContext)
+{
+ if (!rRenderContext.IsNativeControlSupported( i_eType, ControlPart::Entire) )
+ return;
+
+ ImplControlValue aControlValue;
+ tools::Rectangle aCtrlRegion( Point( 0, 0 ), io_rSize );
+
+ aControlValue.setTristateVal( ButtonValue::On );
+
+ tools::Rectangle aNativeBounds, aNativeContent;
+ bool bNativeOK = rRenderContext.GetNativeControlRegion( i_eType,
+ ControlPart::Entire,
+ aCtrlRegion,
+ ControlState::ENABLED,
+ aControlValue,
+ aNativeBounds,
+ aNativeContent );
+ if( bNativeOK )
+ {
+ Size aContentSize( aNativeContent.GetSize() );
+ // leave a little space around the box image (looks better)
+ if( aContentSize.Height() + 2 > io_rSize.Height() )
+ io_rSize.setHeight( aContentSize.Height() + 2 );
+ if( aContentSize.Width() + 2 > io_rSize.Width() )
+ io_rSize.setWidth( aContentSize.Width() + 2 );
+ }
+}
+
+void SvLBoxButton::InitViewData(SvTreeListBox* pView,SvTreeListEntry* pEntry, SvViewDataItem* pViewData)
+{
+ if( !pViewData )
+ pViewData = pView->GetViewDataItem( pEntry, this );
+ Size aSize( pData->Width(), pData->Height() );
+
+ ControlType eCtrlType = (pData->IsRadio())? ControlType::Radiobutton : ControlType::Checkbox;
+ if ( pView )
+ ImplAdjustBoxSize(aSize, eCtrlType, *pView->GetOutDev());
+ pViewData->mnWidth = aSize.Width();
+ pViewData->mnHeight = aSize.Height();
+}
+
+// ***************************************************************
+// class SvLBoxContextBmp
+// ***************************************************************
+
+struct SvLBoxContextBmp_Impl
+{
+ Image m_aImage1;
+ Image m_aImage2;
+
+ bool m_bExpanded;
+};
+
+// ***************************************************************
+
+SvLBoxContextBmp::SvLBoxContextBmp(const Image& aBmp1, const Image& aBmp2,
+ bool bExpanded)
+ :m_pImpl( new SvLBoxContextBmp_Impl )
+{
+
+ m_pImpl->m_bExpanded = bExpanded;
+ SetModeImages( aBmp1, aBmp2 );
+}
+
+SvLBoxContextBmp::SvLBoxContextBmp()
+ : m_pImpl( new SvLBoxContextBmp_Impl )
+{
+ m_pImpl->m_bExpanded = false;
+}
+
+SvLBoxContextBmp::~SvLBoxContextBmp()
+{
+}
+
+SvLBoxItemType SvLBoxContextBmp::GetType() const
+{
+ return SvLBoxItemType::ContextBmp;
+}
+
+void SvLBoxContextBmp::SetModeImages( const Image& _rBitmap1, const Image& _rBitmap2 )
+{
+ m_pImpl->m_aImage1 = _rBitmap1;
+ m_pImpl->m_aImage2 = _rBitmap2;
+}
+
+Image& SvLBoxContextBmp::implGetImageStore( bool _bFirst )
+{
+
+ // OJ: #i27071# wrong mode so we just return the normal images
+ return _bFirst ? m_pImpl->m_aImage1 : m_pImpl->m_aImage2;
+}
+
+void SvLBoxContextBmp::InitViewData( SvTreeListBox* pView,SvTreeListEntry* pEntry,
+ SvViewDataItem* pViewData)
+{
+ if( !pViewData )
+ pViewData = pView->GetViewDataItem( pEntry, this );
+ Size aSize = m_pImpl->m_aImage1.GetSizePixel();
+ pViewData->mnWidth = aSize.Width();
+ pViewData->mnHeight = aSize.Height();
+}
+
+void SvLBoxContextBmp::Paint(
+ const Point& _rPos, SvTreeListBox& _rDev, vcl::RenderContext& rRenderContext,
+ const SvViewDataEntry* pView, const SvTreeListEntry& rEntry)
+{
+
+ // get the image.
+ const Image& rImage = implGetImageStore(pView->IsExpanded() != m_pImpl->m_bExpanded);
+
+ bool _bSemiTransparent = bool( SvTLEntryFlags::SEMITRANSPARENT & rEntry.GetFlags( ) );
+ // draw
+ DrawImageFlags nStyle = (_rDev.IsEnabled() && !mbDisabled) ? DrawImageFlags::NONE : DrawImageFlags::Disable;
+ if (_bSemiTransparent)
+ nStyle |= DrawImageFlags::SemiTransparent;
+ rRenderContext.DrawImage(_rPos, rImage, nStyle);
+}
+
+std::unique_ptr<SvLBoxItem> SvLBoxContextBmp::Clone(SvLBoxItem const * pSource) const
+{
+ std::unique_ptr<SvLBoxContextBmp> pNew(new SvLBoxContextBmp);
+ pNew->m_pImpl->m_aImage1 = static_cast< SvLBoxContextBmp const * >( pSource )->m_pImpl->m_aImage1;
+ pNew->m_pImpl->m_aImage2 = static_cast< SvLBoxContextBmp const * >( pSource )->m_pImpl->m_aImage2;
+ pNew->m_pImpl->m_bExpanded = static_cast<SvLBoxContextBmp const *>(pSource)->m_pImpl->m_bExpanded;
+ return std::unique_ptr<SvLBoxItem>(pNew.release());
+}
+
+tools::Long SvLBoxButtonData::Width()
+{
+ if ( !bDataOk )
+ SetWidthAndHeight();
+ return nWidth;
+}
+
+tools::Long SvLBoxButtonData::Height()
+{
+ if ( !bDataOk )
+ SetWidthAndHeight();
+ return nHeight;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */