/************************************************************************* * * $RCSfile: SlsViewOverlay.cxx,v $ * * $Revision: 1.7 $ * * last change: $Author: obo $ $Date: 2005-04-12 16:59:35 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses * * - GNU Lesser General Public License Version 2.1 * - Sun Industry Standards Source License Version 1.1 * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library 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 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * * Sun Industry Standards Source License Version 1.1 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.1 (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.openoffice.org/license.html. * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc. * * Copyright: 2000 by Sun Microsystems, Inc. * * All Rights Reserved. * * Contributor(s): _______________________________________ * * ************************************************************************/ #include "view/SlsViewOverlay.hxx" #include "controller/SlideSorterController.hxx" #include "model/SlideSorterModel.hxx" #include "model/SlsPageDescriptor.hxx" #include "model/SlsPageEnumeration.hxx" #include "view/SlideSorterView.hxx" #include "SlideSorterViewShell.hxx" #include "view/SlsLayouter.hxx" #include "view/SlsPageObject.hxx" #include "view/SlsPageObjectViewObjectContact.hxx" #include "ViewShellBase.hxx" #include "UpdateLockManager.hxx" #include "Window.hxx" #include "sdpage.hxx" namespace { class ShowingModeGuard { public: explicit ShowingModeGuard (::sd::slidesorter::view::OverlayBase& rOverlay, bool bHideAndSave = false) : mrOverlay (rOverlay), mbIsShowing (mrOverlay.IsShowing()), mbRestorePending(false) { if (mbIsShowing) if (bHideAndSave) { mrOverlay.GetViewOverlay().HideAndSave ( ::sd::slidesorter::view::ViewOverlay::OPT_XOR); mbRestorePending = true; } mrOverlay.Hide(); } ~ShowingModeGuard (void) { if (mbIsShowing) { mrOverlay.Show(); if (mbRestorePending) mrOverlay.GetViewOverlay().Restore (); } } private: ::sd::slidesorter::view::OverlayBase& mrOverlay; bool mbIsShowing; bool mbRestorePending; }; } namespace sd { namespace slidesorter { namespace view { //===== ViewOverlay ========================================================= ViewOverlay::ViewOverlay (SlideSorterViewShell& rViewShell) : mrViewShell (rViewShell), maSelectionRectangleOverlay(*this), maMouseOverIndicatorOverlay(*this), maInsertionIndicatorOverlay(*this), maSubstitutionOverlay(*this), mbSelectionRectangleWasVisible(false), mbMouseOverIndicatorWasVisible(false), mbInsertionIndicatorWasVisible(false), mbSubstitutionDisplayWasVisible(false), mnHideAndSaveLevel(0) { } ViewOverlay::~ViewOverlay (void) { } SelectionRectangleOverlay& ViewOverlay::GetSelectionRectangleOverlay (void) { return maSelectionRectangleOverlay; } MouseOverIndicatorOverlay& ViewOverlay::GetMouseOverIndicatorOverlay (void) { return maMouseOverIndicatorOverlay; } InsertionIndicatorOverlay& ViewOverlay::GetInsertionIndicatorOverlay (void) { return maInsertionIndicatorOverlay; } SubstitutionOverlay& ViewOverlay::GetSubstitutionOverlay (void) { return maSubstitutionOverlay; } void ViewOverlay::Paint (void) { maSelectionRectangleOverlay.Paint(); maMouseOverIndicatorOverlay.Paint(); maInsertionIndicatorOverlay.Paint(); maSubstitutionOverlay.Paint(); } controller::SlideSorterController& ViewOverlay::GetController (void) { return mrViewShell.GetSlideSorterController(); } SlideSorterViewShell& ViewOverlay::GetViewShell (void) { return mrViewShell; } void ViewOverlay::HideAndSave (OverlayPaintType eType) { if (mnHideAndSaveLevel++ == 0) { // Remember the current state of the visiblities of the overlays. mbSelectionRectangleWasVisible = maSelectionRectangleOverlay.IsShowing(); mbMouseOverIndicatorWasVisible = maMouseOverIndicatorOverlay.IsShowing(); mbInsertionIndicatorWasVisible = maInsertionIndicatorOverlay.IsShowing(); mbSubstitutionDisplayWasVisible = maSubstitutionOverlay.IsShowing(); // Remember that we have saved the current state. meSavedStateType = eType; // Hide the overlays. if (eType==OPT_ALL || eType==OPT_XOR) { if (mbSelectionRectangleWasVisible) maSelectionRectangleOverlay.Hide(); } if (mbSubstitutionDisplayWasVisible) maSubstitutionOverlay.Hide(); if (eType==OPT_ALL || eType==OPT_PAINT) { if (mbMouseOverIndicatorWasVisible) maMouseOverIndicatorOverlay.Hide(); if (mbInsertionIndicatorWasVisible) maInsertionIndicatorOverlay.Hide(); } } } void ViewOverlay::Restore (void) { if (--mnHideAndSaveLevel == 0) { if (meSavedStateType==OPT_ALL || meSavedStateType==OPT_PAINT) { if (mbInsertionIndicatorWasVisible) maInsertionIndicatorOverlay.Show(); if (mbMouseOverIndicatorWasVisible) maMouseOverIndicatorOverlay.Show(); } if (mbSubstitutionDisplayWasVisible) maSubstitutionOverlay.Show(); if (meSavedStateType==OPT_ALL || meSavedStateType==OPT_XOR) { if (mbSelectionRectangleWasVisible) maSelectionRectangleOverlay.Show(); } } } //===== OverlayBase ========================================================= OverlayBase::OverlayBase (ViewOverlay& rViewOverlay) : mrViewOverlay(rViewOverlay), mbIsShowing (false) { } OverlayBase::~OverlayBase (void) { } void OverlayBase::Paint (void) { } bool OverlayBase::IsShowing (void) { return mbIsShowing; } void OverlayBase::Toggle (void) { if (IsShowing()) Hide(); else Show(); } void OverlayBase::Show (void) { if ( ! IsShowing()) { mbIsShowing = true; Paint (); } } void OverlayBase::Hide (void) { if (IsShowing()) { mbIsShowing = false; Paint (); } } ViewOverlay& OverlayBase::GetViewOverlay (void) { return mrViewOverlay; } //===== SubstitutionOverlay ================================================= SubstitutionOverlay::SubstitutionOverlay (ViewOverlay& rViewOverlay) : OverlayBase(rViewOverlay) { } SubstitutionOverlay::~SubstitutionOverlay (void) { } void SubstitutionOverlay::Paint (void) { ::osl::MutexGuard aGuard (maMutex); SubstitutionShapeList::const_iterator aShape (maShapes.begin()); SubstitutionShapeList::const_iterator aShapeEnd (maShapes.end()); while (aShape!=aShapeEnd) { mrViewOverlay.GetViewShell().DrawMarkRect (*aShape); aShape++; } OverlayBase::Paint(); } void SubstitutionOverlay::Create ( model::PageEnumeration& rSelection, const Point& rPosition) { ShowingModeGuard aGuard (*this); maPosition = rPosition; maShapes.clear(); while (rSelection.HasMoreElements()) { maShapes.push_back ( rSelection.GetNextElement().GetPageObject() ->GetCurrentBoundRect()); } } void SubstitutionOverlay::Clear (void) { ShowingModeGuard aGuard (*this); maShapes.clear(); } void SubstitutionOverlay::Move (const Point& rOffset) { SetPosition (maPosition + rOffset); } void SubstitutionOverlay::SetPosition (const Point& rPosition) { ShowingModeGuard aGuard (*this); Point rOffset = rPosition - maPosition; SubstitutionShapeList::iterator aShape (maShapes.begin()); SubstitutionShapeList::const_iterator aShapeEnd (maShapes.end()); for (;aShape!=aShapeEnd; aShape++) aShape->SetPos (aShape->TopLeft() + rOffset); maPosition = rPosition; } const Point& SubstitutionOverlay::GetPosition (void) const { return maPosition; } //===== SelectionRectangleOverlay =========================================== SelectionRectangleOverlay::SelectionRectangleOverlay ( ViewOverlay& rViewOverlay) : OverlayBase (rViewOverlay), maAnchor(0,0), maSecondCorner(0,0) { } void SelectionRectangleOverlay::Paint (void) { // mrViewOverlay.GetViewShell().DrawMarkRect (maSelectionRectangle); } void SelectionRectangleOverlay::Show (void) { if ( ! mbIsShowing) { SlideSorterView& rView (mrViewOverlay.GetViewShell().GetSlideSorterController().GetView()); rView.BegEncirclement(maAnchor); rView.MovEncirclement(maSecondCorner); OverlayBase::Show(); } } void SelectionRectangleOverlay::Hide (void) { if (mbIsShowing) { mrViewOverlay.GetViewShell().GetSlideSorterController().GetView().EndEncirclement(); OverlayBase::Hide(); } } Rectangle SelectionRectangleOverlay::GetSelectionRectangle (void) { return Rectangle(maAnchor, maSecondCorner); } void SelectionRectangleOverlay::Start (const Point& rAnchor) { maAnchor = rAnchor; maSecondCorner = rAnchor; mrViewOverlay.GetViewShell().GetSlideSorterController().GetView().BegEncirclement(maAnchor); OverlayBase::Show(); } void SelectionRectangleOverlay::Update (const Point& rSecondCorner) { maSecondCorner = rSecondCorner; mrViewOverlay.GetViewShell().GetSlideSorterController().GetView().MovEncirclement(maSecondCorner); } //===== InsertionIndicatorOverlay =========================================== InsertionIndicatorOverlay::InsertionIndicatorOverlay ( ViewOverlay& rViewOverlay) : OverlayBase (rViewOverlay) { } void InsertionIndicatorOverlay::SetPositionAndSize ( const Rectangle& aNewBoundingBox) { if (maBoundingBox != aNewBoundingBox) { ShowingModeGuard aGuard (*this, true); maBoundingBox = aNewBoundingBox; } } void InsertionIndicatorOverlay::Paint (void) { Color aColor; if (mbIsShowing) aColor = Application::GetSettings().GetStyleSettings().GetFontColor(); else aColor = Application::GetSettings().GetStyleSettings().GetWindowColor(); mrViewOverlay.GetViewShell().DrawFilledRect ( maBoundingBox, aColor, aColor); } void InsertionIndicatorOverlay::SetPosition (const Point& rPoint) { static const bool bAllowHorizontalInsertMarker = true; Layouter& rLayouter ( mrViewOverlay.GetController().GetView().GetLayouter()); USHORT nPageCount = mrViewOverlay.GetController().GetModel().GetPageCount(); sal_Int32 nInsertionIndex = rLayouter.GetInsertionIndex (rPoint, bAllowHorizontalInsertMarker); if (nInsertionIndex >= nPageCount) nInsertionIndex = nPageCount-1; sal_Int32 nDrawIndex = nInsertionIndex; bool bVertical = false; bool bLeftOrTop = false; if (nInsertionIndex >= 0) { // Now that we know where to insert, we still have to determine // where to draw the marker. There are two decisions to make: // 1. Draw a vertical or a horizontal insert marker. // The horizontal one may only be chosen when there is only one // column. // 2. The vertical (standard) insert marker may be painted left to // the insert page or right of the previous one. When both pages // are in the same row this makes no difference. Otherwise the // posiotions are at the left and right ends of two rows. Point aPageCenter (rLayouter.GetPageObjectBox ( nInsertionIndex).Center()); if (bAllowHorizontalInsertMarker && rLayouter.GetColumnCount() == 1) { bVertical = false; bLeftOrTop = (rPoint.Y() <= aPageCenter.Y()); } else { bVertical = true; bLeftOrTop = (rPoint.X() <= aPageCenter.X()); } // Add one when the mark was painted below or to the right of the // page object. if ( ! bLeftOrTop) nInsertionIndex += 1; } mnInsertionIndex = nInsertionIndex; Rectangle aBox; if (mnInsertionIndex >= 0) aBox = rLayouter.GetInsertionMarkerBox ( nDrawIndex, bVertical, bLeftOrTop); SetPositionAndSize (aBox); } sal_Int32 InsertionIndicatorOverlay::GetInsertionPageIndex (void) const { return mnInsertionIndex; } //===== MouseOverIndicatorOverlay =========================================== MouseOverIndicatorOverlay::MouseOverIndicatorOverlay ( ViewOverlay& rViewOverlay) : OverlayBase (rViewOverlay), mpPageUnderMouse(NULL) { } void MouseOverIndicatorOverlay::SetSlideUnderMouse ( const model::PageDescriptor* pDescriptor) { SlideSorterViewShell& rViewShell (mrViewOverlay.GetViewShell()); if ( ! rViewShell.GetViewShellBase().GetUpdateLockManager().IsLocked()) if (mpPageUnderMouse != pDescriptor) { ShowingModeGuard aGuard (*this, true); mpPageUnderMouse = pDescriptor; } } void MouseOverIndicatorOverlay::Paint (void) { if (mpPageUnderMouse != NULL) { SlideSorterViewShell& rViewShell (mrViewOverlay.GetViewShell()); if ( ! rViewShell.GetViewShellBase().GetUpdateLockManager().IsLocked()) { SlideSorterView& rView (rViewShell.GetSlideSorterController().GetView()); OutputDevice* pDevice = rView.GetWindow(); PageObjectViewObjectContact* pContact = mpPageUnderMouse->GetViewObjectContact(); if (pDevice != NULL && pContact != NULL) { pContact->PaintFrame(*pDevice, mbIsShowing); } } } } } } } // end of namespace ::sd::slidesorter::view