/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include "precompiled_sd.hxx" #include "view/SlsButtonBar.hxx" #include "SlideSorter.hxx" #include "model/SlsPageDescriptor.hxx" #include "model/SlideSorterModel.hxx" #include "view/SlsTheme.hxx" #include "view/SlideSorterView.hxx" #include "view/SlsToolTip.hxx" #include "controller/SlideSorterController.hxx" #include "controller/SlsSlotManager.hxx" #include "controller/SlsCurrentSlideManager.hxx" #include "controller/SlsPageSelector.hxx" #include "controller/SlsAnimator.hxx" #include "controller/SlsAnimationFunction.hxx" #include "app.hrc" #include "drawdoc.hxx" #include #include #include #include #include #include #include #include using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; using ::com::sun::star::beans::PropertyValue; using ::com::sun::star::presentation::XPresentation2; namespace sd { namespace slidesorter { namespace view { /** Base class for the painter of the background bar onto which the buttons are painted. It also provides some size information. */ class ButtonBar::BackgroundTheme { public: BackgroundTheme( const ::boost::shared_ptr& rpTheme, const ::std::vector& rButtons); /** Set the preview bounding box, the maximal area in which to display buttons. A call to this method triggers a call to Layout(). */ void SetPreviewBoundingBox (const Rectangle& rPreviewBoundingBox); Button::IconSize GetIconSize (void) const; virtual BitmapEx CreateBackground ( const OutputDevice& rTemplateDevice, const bool bIsButtonDown) const = 0; virtual Point GetBackgroundLocation (void) = 0; virtual Rectangle GetButtonArea (void) = 0; protected: ::boost::shared_ptr mpTheme; Rectangle maPreviewBoundingBox; Size maMinimumLargeButtonAreaSize; Size maMinimumMediumButtonAreaSize; Size maMinimumSmallButtonAreaSize; Button::IconSize meIconSize; virtual void Layout (void) = 0; private: void UpdateMinimumIconSizes(const ::std::vector& rButtons); }; namespace { /** Rectangular button bar that covers the whole width of the preview. */ class RectangleBackgroundTheme : public ButtonBar::BackgroundTheme { public: RectangleBackgroundTheme( const ::boost::shared_ptr& rpTheme, const ::std::vector& rButtons); virtual BitmapEx CreateBackground ( const OutputDevice& rTemplateDevice, const bool bIsButtonDown) const; virtual Point GetBackgroundLocation (void); virtual Rectangle GetButtonArea (void); protected: virtual void Layout (void); private: sal_Int32 mnBarHeight; }; /** Button bar is composed of three images, the left and right end of the bar and the center image. Buttons are only placed over the center image. The center image is painted as is, it is not scaled. */ class BitmapBackgroundTheme : public ButtonBar::BackgroundTheme { public: BitmapBackgroundTheme( const ::boost::shared_ptr& rpTheme, const ::std::vector& rButtons); virtual BitmapEx CreateBackground ( const OutputDevice& rTemplateDevice, const bool bIsButtonDown) const; virtual Point GetBackgroundLocation (void); virtual Rectangle GetButtonArea (void); protected: virtual void Layout (void); private: Rectangle maButtonArea; Point maBackgroundLocation; }; /** The source mask is essentially multiplied with the given alpha value. The result is writen to the result mask. */ void AdaptTransparency (AlphaMask& rMask, const AlphaMask& rSourceMask, const double nAlpha) { BitmapWriteAccess* pBitmap = rMask.AcquireWriteAccess(); const BitmapReadAccess* pSourceBitmap = const_cast(rSourceMask).AcquireReadAccess(); if (pBitmap!=NULL && pSourceBitmap!=NULL) { const sal_Int32 nWidth (pBitmap->Width()); const sal_Int32 nHeight (pBitmap->Height()); for (sal_Int32 nY = 0; nYGetPixel(nY, nX).GetBlueOrIndex()); const sal_uInt8 nNewValue (static_cast(nValue * (1-nAlpha))); pBitmap->SetPixel(nY, nX, 255-nNewValue); } } } } // end of anonymous namespace //===== ButtonBar::Lock ======================================================= ButtonBar::Lock::Lock (SlideSorter& rSlideSorter) : mrButtonBar(rSlideSorter.GetView().GetButtonBar()) { mrButtonBar.AcquireLock(); } ButtonBar::Lock::~Lock (void) { mrButtonBar.ReleaseLock(); } //===== ButtonBar ============================================================= ButtonBar::ButtonBar (SlideSorter& rSlideSorter) : mrSlideSorter(rSlideSorter), maPageObjectSize(0,0), maButtonBoundingBox(), maBackgroundLocation(), mpDescriptor(), mbIsExcluded(false), mpButtonUnderMouse(), mpDownButton(), maRegularButtons(), maExcludedButtons(), maNormalBackground(), maButtonDownBackground(), mbIsMouseOverBar(false), mpBackgroundTheme(), mnLockCount(0) { HandleDataChangeEvent(); } ButtonBar::~ButtonBar (void) { } void ButtonBar::ProcessButtonDownEvent ( const model::SharedPageDescriptor& rpDescriptor, const Point aMouseModelLocation) { SetButtonUnderMouse(GetButtonAt(aMouseModelLocation)); if (mpButtonUnderMouse) mpButtonUnderMouse->SetState(Button::State_Down); mpDownButton = mpButtonUnderMouse; mrSlideSorter.GetView().RequestRepaint(rpDescriptor); } void ButtonBar::ProcessButtonUpEvent ( const model::SharedPageDescriptor& rpDescriptor, const Point aMouseModelLocation) { SetButtonUnderMouse(GetButtonAt(aMouseModelLocation)); if (mpButtonUnderMouse) { mpButtonUnderMouse->SetState(Button::State_Hover); if (mpButtonUnderMouse == mpDownButton) { // This is done only when the buttons are sufficiently visible. if (mpDescriptor->GetVisualState().GetButtonAlpha()<0.7) { mpButtonUnderMouse->ProcessClick(mpDescriptor); mbIsExcluded = mpDescriptor->HasState(model::PageDescriptor::ST_Excluded); ProcessMouseMotionEvent (rpDescriptor, aMouseModelLocation, false); } } } mpDownButton.reset(); mrSlideSorter.GetView().RequestRepaint(rpDescriptor); } void ButtonBar::ProcessMouseMotionEvent ( const model::SharedPageDescriptor& rpDescriptor, const Point aMouseModelLocation, const bool bIsMouseButtonDown) { model::SharedPageDescriptor pOldDescriptor (mpDescriptor); bool bPageHasChanged (false); bool bButtonHasChanged (false); bool bButtonStateHasChanged (false); // Update the page object for which to manage the buttons. bPageHasChanged = SetPage(rpDescriptor); mbIsMouseOverBar = IsMouseOverBar(aMouseModelLocation); // Update button under mouse. if (rpDescriptor) { bButtonHasChanged = SetButtonUnderMouse(GetButtonAt(aMouseModelLocation)); if (mpButtonUnderMouse) { // When the mouse button is down, mark the button under the // mouse only as pressed when it is the same button the mouse // button was pressed over, and where the button release would // lead to a click action. if (bIsMouseButtonDown) { if (mpButtonUnderMouse==mpDownButton) bButtonStateHasChanged = mpButtonUnderMouse->SetState(Button::State_Down); } else bButtonStateHasChanged = mpButtonUnderMouse->SetState(Button::State_Hover); } } // Show a quick help text when the mouse is over a button. if (bButtonHasChanged) { SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); if (pWindow) { if (mpButtonUnderMouse) mrSlideSorter.GetView().GetToolTip().ShowHelpText(mpButtonUnderMouse->GetHelpText()); else mrSlideSorter.GetView().GetToolTip().ShowDefaultHelpText(); } } if (bPageHasChanged || bButtonHasChanged || bButtonStateHasChanged) { if (pOldDescriptor) mrSlideSorter.GetView().RequestRepaint(pOldDescriptor); if (mpDescriptor && pOldDescriptor!=mpDescriptor) mrSlideSorter.GetView().RequestRepaint(mpDescriptor); } } void ButtonBar::ResetPage (void) { SetPage(model::SharedPageDescriptor()); } bool ButtonBar::SetPage (const model::SharedPageDescriptor& rpDescriptor) { if (mpDescriptor != rpDescriptor) { mpDescriptor = rpDescriptor; if (mpDescriptor) mbIsExcluded = mpDescriptor->HasState(model::PageDescriptor::ST_Excluded); else mbIsExcluded = false; SetButtonUnderMouse(); mpDownButton.reset(); return true; } else return false; } sal_Int32 ButtonBar::GetButtonCount (const bool bIsExcluded) const { if (bIsExcluded) return maExcludedButtons.size(); else return maRegularButtons.size(); } ::boost::shared_ptr