blob: 7f097da250abaabed2697aa35adfb4f4dc1e06cb [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#include "precompiled_sfx2.hxx"
#include "TabBar.hxx"
#include "TabItem.hxx"
#include "sidebar/ControlFactory.hxx"
#include "DeckDescriptor.hxx"
#include "Paint.hxx"
#include "sfx2/sidebar/Theme.hxx"
#include "sfx2/sidebar/Tools.hxx"
#include "FocusManager.hxx"
#include <vcl/gradient.hxx>
#include <vcl/image.hxx>
#include <vcl/wrkwin.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/componentcontext.hxx>
#include <tools/svborder.hxx>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
namespace sfx2 { namespace sidebar {
TabBar::TabBar (
Window* pParentWindow,
const Reference<frame::XFrame>& rxFrame,
const ::boost::function<void(const ::rtl::OUString&)>& rDeckActivationFunctor,
const PopupMenuProvider& rPopupMenuProvider)
: Window(pParentWindow, WB_DIALOGCONTROL),
mxFrame(rxFrame),
mpMenuButton(ControlFactory::CreateMenuButton(this)),
maItems(),
maDeckActivationFunctor(rDeckActivationFunctor),
maPopupMenuProvider(rPopupMenuProvider)
{
SetBackground(Theme::GetPaint(Theme::Paint_TabBarBackground).GetWallpaper());
mpMenuButton->SetModeImage(
Theme::GetImage(Theme::Image_TabBarMenu),
Theme::IsHighContrastMode()
? BMP_COLOR_HIGHCONTRAST
: BMP_COLOR_NORMAL);
mpMenuButton->SetClickHdl(LINK(this, TabBar, OnToolboxClicked));
Layout();
#ifdef DEBUG
SetText(A2S("TabBar"));
#endif
}
TabBar::~TabBar (void)
{
}
void TabBar::Paint (const Rectangle& rUpdateArea)
{
Window::Paint(rUpdateArea);
const sal_Int32 nHorizontalPadding (Theme::GetInteger(Theme::Int_TabMenuSeparatorPadding));
SetLineColor(Theme::GetColor(Theme::Color_TabMenuSeparator));
DrawLine(
Point(nHorizontalPadding, mnMenuSeparatorY),
Point(GetSizePixel().Width()-nHorizontalPadding, mnMenuSeparatorY));
}
sal_Int32 TabBar::GetDefaultWidth (void)
{
return Theme::GetInteger(Theme::Int_TabItemWidth)
+ Theme::GetInteger(Theme::Int_TabBarLeftPadding)
+ Theme::GetInteger(Theme::Int_TabBarRightPadding);
}
void TabBar::SetDecks (
const ResourceManager::DeckContextDescriptorContainer& rDecks)
{
// Remove the current buttons.
{
for(ItemContainer::iterator
iItem(maItems.begin()), iEnd(maItems.end());
iItem!=iEnd;
++iItem)
{
iItem->mpButton.reset();
}
maItems.clear();
}
maItems.resize(rDecks.size());
sal_Int32 nIndex (0);
for (ResourceManager::DeckContextDescriptorContainer::const_iterator
iDeck(rDecks.begin()),
iEnd(rDecks.end());
iDeck!=iEnd;
++iDeck)
{
const DeckDescriptor* pDescriptor = ResourceManager::Instance().GetDeckDescriptor(iDeck->msId);
if (pDescriptor == NULL)
{
OSL_ASSERT(pDescriptor!=NULL);
continue;
}
Item& rItem (maItems[nIndex++]);
rItem.msDeckId = pDescriptor->msId;
rItem.mpButton.reset(CreateTabItem(*pDescriptor));
rItem.mpButton->SetClickHdl(LINK(&rItem, TabBar::Item, HandleClick));
rItem.maDeckActivationFunctor = maDeckActivationFunctor;
rItem.mbIsHiddenByDefault = false;
rItem.mbIsHidden = ! pDescriptor->mbIsEnabled;
rItem.mpButton->Enable(iDeck->mbIsEnabled);
}
UpdateButtonIcons();
Layout();
}
void TabBar::UpdateButtonIcons (void)
{
const BmpColorMode eColorMode (
Theme::IsHighContrastMode()
? BMP_COLOR_HIGHCONTRAST
: BMP_COLOR_NORMAL);
mpMenuButton->SetModeImage(Theme::GetImage(Theme::Image_TabBarMenu), eColorMode);
for(ItemContainer::const_iterator
iItem(maItems.begin()), iEnd(maItems.end());
iItem!=iEnd;
++iItem)
{
const DeckDescriptor* pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(iItem->msDeckId);
if (pDeckDescriptor != NULL)
iItem->mpButton->SetModeImage(
GetItemImage(*pDeckDescriptor),
eColorMode);
}
Invalidate();
}
void TabBar::Layout (void)
{
const SvBorder aPadding (
Theme::GetInteger(Theme::Int_TabBarLeftPadding),
Theme::GetInteger(Theme::Int_TabBarTopPadding),
Theme::GetInteger(Theme::Int_TabBarRightPadding),
Theme::GetInteger(Theme::Int_TabBarBottomPadding));
sal_Int32 nX (aPadding.Top());
sal_Int32 nY (aPadding.Left());
const Size aTabItemSize (
Theme::GetInteger(Theme::Int_TabItemWidth),
Theme::GetInteger(Theme::Int_TabItemHeight));
// Place the menu button and the separator.
if( bool(mpMenuButton))
{
mpMenuButton->SetPosSizePixel(
Point(nX,nY),
aTabItemSize);
mpMenuButton->Show();
nY += mpMenuButton->GetSizePixel().Height() + 1 + Theme::GetInteger(Theme::Int_TabMenuPadding);
mnMenuSeparatorY = nY - Theme::GetInteger(Theme::Int_TabMenuPadding)/2 - 1;
}
// Place the deck selection buttons.
for(ItemContainer::const_iterator
iItem(maItems.begin()), iEnd(maItems.end());
iItem!=iEnd;
++iItem)
{
Button& rButton (*iItem->mpButton);
rButton.Show( ! iItem->mbIsHidden);
if (iItem->mbIsHidden)
continue;
// Place and size the icon.
rButton.SetPosSizePixel(
Point(nX,nY),
aTabItemSize);
rButton.Show();
nY += rButton.GetSizePixel().Height() + 1 + aPadding.Bottom();
}
Invalidate();
}
void TabBar::HighlightDeck (const ::rtl::OUString& rsDeckId)
{
for (ItemContainer::iterator iItem(maItems.begin()),iEnd(maItems.end());
iItem!=iEnd;
++iItem)
{
if (iItem->msDeckId.equals(rsDeckId))
iItem->mpButton->Check(sal_True);
else
iItem->mpButton->Check(sal_False);
}
}
TabBar::Item* TabBar::GetItemForId (const ::rtl::OUString& rsDeckId)
{
for (ItemContainer::iterator iItem(maItems.begin()),iEnd(maItems.end());
iItem!=iEnd;
++iItem)
{
if (iItem->msDeckId.equals(rsDeckId))
return &*iItem;
}
return NULL;
}
void TabBar::DataChanged (const DataChangedEvent& rDataChangedEvent)
{
SetBackground(Theme::GetPaint(Theme::Paint_TabBarBackground).GetWallpaper());
UpdateButtonIcons();
Window::DataChanged(rDataChangedEvent);
}
long TabBar::Notify (NotifyEvent&)
{
return sal_False;
}
RadioButton* TabBar::CreateTabItem (const DeckDescriptor& rDeckDescriptor)
{
RadioButton* pItem = ControlFactory::CreateTabItem(this);
pItem->SetHelpText(rDeckDescriptor.msHelpText);
pItem->SetQuickHelpText(rDeckDescriptor.msHelpText);
return pItem;
}
Image TabBar::GetItemImage (const DeckDescriptor& rDeckDescriptor) const
{
return Tools::GetImage(
rDeckDescriptor.msIconURL,
rDeckDescriptor.msHighContrastIconURL,
mxFrame);
}
IMPL_LINK(TabBar::Item, HandleClick, Button*, EMPTYARG)
{
try
{
maDeckActivationFunctor(msDeckId);
}
catch( const ::com::sun::star::uno::Exception&) {} // workaround for #i123198#
return 1;
}
const ::rtl::OUString TabBar::GetDeckIdForIndex (const sal_Int32 nIndex) const
{
if (nIndex<0 || static_cast<size_t>(nIndex)>=maItems.size())
throw RuntimeException();
else
return maItems[nIndex].msDeckId;
}
void TabBar::ToggleHideFlag (const sal_Int32 nIndex)
{
if (nIndex<0 || static_cast<size_t>(nIndex)>=maItems.size())
throw RuntimeException();
else
{
maItems[nIndex].mbIsHidden = ! maItems[nIndex].mbIsHidden;
ResourceManager::Instance().SetIsDeckEnabled(
maItems[nIndex].msDeckId,
maItems[nIndex].mbIsHidden);
Layout();
}
}
void TabBar::RestoreHideFlags (void)
{
bool bNeedsLayout (false);
for(ItemContainer::iterator iItem(maItems.begin()),iEnd(maItems.end());
iItem!=iEnd;
++iItem)
{
if (iItem->mbIsHidden != iItem->mbIsHiddenByDefault)
{
iItem->mbIsHidden = iItem->mbIsHiddenByDefault;
bNeedsLayout = true;
}
}
if (bNeedsLayout)
Layout();
}
void TabBar::UpdateFocusManager (FocusManager& rFocusManager)
{
::std::vector<Button*> aButtons;
aButtons.reserve(maItems.size()+1);
aButtons.push_back(mpMenuButton.get());
for(ItemContainer::const_iterator
iItem(maItems.begin()), iEnd(maItems.end());
iItem!=iEnd;
++iItem)
{
aButtons.push_back(iItem->mpButton.get());
}
rFocusManager.SetButtons(aButtons);
}
IMPL_LINK(TabBar, OnToolboxClicked, void*, EMPTYARG)
{
if ( ! mpMenuButton)
return 0;
::std::vector<DeckMenuData> aMenuData;
for(ItemContainer::const_iterator iItem(maItems.begin()),iEnd(maItems.end());
iItem!=iEnd;
++iItem)
{
const DeckDescriptor* pDeckDescriptor = ResourceManager::Instance().GetDeckDescriptor(iItem->msDeckId);
if (pDeckDescriptor != NULL)
{
DeckMenuData aData;
aData.msDisplayName = pDeckDescriptor->msTitle;
aData.msDeckId = pDeckDescriptor->msId;
aData.mbIsCurrentDeck = iItem->mpButton->IsChecked();
aData.mbIsActive = !iItem->mbIsHidden;
aData.mbIsEnabled = iItem->mpButton->IsEnabled();
aMenuData.push_back(aData);
}
}
maPopupMenuProvider(
Rectangle(
mpMenuButton->GetPosPixel(),
mpMenuButton->GetSizePixel()),
aMenuData);
mpMenuButton->Check(sal_False);
return 0;
}
} } // end of namespace sfx2::sidebar