INTEGRATION: CWS presfixes12 (1.1.2); FILE ADDED

2007/05/14 00:55:29 thb 1.1.2.5: #i77154# Moved intrinsic animation notification from global EventMultiplexer to ShapeManager (which is local to each slide). This is a temporary workaround, the proper fix would demote the EventMultiplexer to each Slide
2007/05/10 20:32:40 thb 1.1.2.4: #i37778# Reworked LayerManager::updateShapeLayers - now much better aligned with general shape update, and avoids superfluous rendering; made unit tests work again; passing down slide background repaint status to LayerManager; relaxed preconditions for Shape::getUpdateArea() - no longer requires views to work; now catching singular view matrix and using sensible default at API border
2007/04/24 15:52:10 thb 1.1.2.3: #i76658# Registering shape and cursor listeners only when going active (besides reduced load, this also helps with identifying shapes via lookup)
2007/01/30 16:43:50 thb 1.1.2.2: #i37778# Made view update/repaint/resize work again; swapped BackgroundShape parameters for correct mtf import
2007/01/29 14:02:14 thb 1.1.2.1: Issue number: #i37778#

Larger slideshow refactoring. Wrote design and coding style manifest,
and adapted the code to actually conform to this. In detail:
 - cleaned up ownership/disposable/weak_ptr story. removed hacks and
   explicit Disposable implementations, where workaround were available
 - removed object mutices, where superfluous
 - reworked EventMultiplexer (using templatized listener class now), added
   more events. EventMultiplexer now serves as a true blackboard
 - reworked directory structure: disjunct parts are now physically separated
   into directories, instantiation happens via factories & abstract interfaces
 - added CursorManager, to make setting mouse cursor less hackish
 - reworked DrawShape, to implement SeparateListener pattern
 - reworked IntrinsicAnimationActivity, to avoid cyclic references
 - modified hyperlink & shape cursor handling to communicate via
   EventMultiplexer
 - renamed & cleaned up files (presentation.cxx now named slideshowimpl.cxx,
   etc.)
 - added first version of the z-order fix to layer/layermanager
 - cleaned up include guards and include syntax
This commit is contained in:
Oliver Bolte 2007-07-17 13:57:08 +00:00
parent d5a6abfe40
commit 2d8a3b9417

View file

@ -0,0 +1,463 @@
/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: shapemanagerimpl.cxx,v $
*
* $Revision: 1.2 $
*
* last change: $Author: obo $ $Date: 2007-07-17 14:57:08 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 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
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"
#include <canvas/debug.hxx>
#include <com/sun/star/awt/MouseButton.hpp>
#include <com/sun/star/awt/SystemPointer.hpp>
#include <com/sun/star/presentation/XShapeEventListener.hpp>
#include <com/sun/star/presentation/XSlideShowListener.hpp>
#include <com/sun/star/awt/MouseButton.hpp>
#include "shapemanagerimpl.hxx"
#include <boost/bind.hpp>
using namespace com::sun::star;
namespace slideshow {
namespace internal {
ShapeManagerImpl::ShapeManagerImpl( EventMultiplexer& rMultiplexer,
LayerManagerSharedPtr const& rLayerManager,
CursorManager& rCursorManager,
const ShapeEventListenerMap& rGlobalListenersMap,
const ShapeCursorMap& rGlobalCursorMap ):
mrMultiplexer(rMultiplexer),
mpLayerManager(rLayerManager),
mrCursorManager(rCursorManager),
mrGlobalListenersMap(rGlobalListenersMap),
mrGlobalCursorMap(rGlobalCursorMap),
maShapeListenerMap(),
maShapeCursorMap(),
maHyperlinkShapes(),
mbEnabled(false)
{
}
void ShapeManagerImpl::activate( bool bSlideBackgoundPainted )
{
if( !mbEnabled )
{
mbEnabled = true;
// register this handler on EventMultiplexer.
// Higher prio (overrides other engine handlers)
mrMultiplexer.addMouseMoveHandler( shared_from_this(), 2.0 );
mrMultiplexer.addClickHandler( shared_from_this(), 2.0 );
mrMultiplexer.addShapeListenerHandler( shared_from_this() );
// clone listener map
uno::Reference<presentation::XShapeEventListener> xDummyListener;
std::for_each( mrGlobalListenersMap.begin(),
mrGlobalListenersMap.end(),
boost::bind( &ShapeManagerImpl::listenerAdded,
this,
boost::cref(xDummyListener),
boost::bind(
std::select1st<ShapeEventListenerMap::value_type>(),
_1 )));
// clone cursor map
std::for_each( mrGlobalCursorMap.begin(),
mrGlobalCursorMap.end(),
boost::bind( &ShapeManagerImpl::cursorChanged,
this,
boost::bind(
std::select1st<ShapeCursorMap::value_type>(),
_1 ),
boost::bind(
std::select2nd<ShapeCursorMap::value_type>(),
_1 )));
if( mpLayerManager )
mpLayerManager->activate( bSlideBackgoundPainted );
}
}
void ShapeManagerImpl::deactivate()
{
if( mbEnabled )
{
mbEnabled = false;
if( mpLayerManager )
mpLayerManager->deactivate();
maShapeListenerMap.clear();
maShapeCursorMap.clear();
mrMultiplexer.removeShapeListenerHandler( shared_from_this() );
mrMultiplexer.removeMouseMoveHandler( shared_from_this() );
mrMultiplexer.removeClickHandler( shared_from_this() );
}
}
void ShapeManagerImpl::dispose()
{
// remove listeners (EventMultiplexer holds shared_ptr on us)
deactivate();
maHyperlinkShapes.clear();
maShapeCursorMap.clear();
maShapeListenerMap.clear();
mpLayerManager.reset();
}
bool ShapeManagerImpl::handleMousePressed( awt::MouseEvent const& )
{
// not used here
return false; // did not handle the event
}
bool ShapeManagerImpl::handleMouseReleased( awt::MouseEvent const& e )
{
if( !mbEnabled || e.Buttons != awt::MouseButton::LEFT)
return false;
basegfx::B2DPoint const aPosition( e.X, e.Y );
// first check for hyperlinks, because these have
// highest prio:
rtl::OUString const hyperlink( checkForHyperlink(aPosition) );
if( hyperlink.getLength() > 0 )
{
mrMultiplexer.notifyHyperlinkClicked(hyperlink);
return true; // event consumed
}
// find matching shape (scan reversely, to coarsely match
// paint order)
ShapeToListenersMap::reverse_iterator aCurrBroadcaster(
maShapeListenerMap.rbegin() );
ShapeToListenersMap::reverse_iterator const aEndBroadcasters(
maShapeListenerMap.rend() );
while( aCurrBroadcaster != aEndBroadcasters )
{
// TODO(F2): Get proper geometry polygon from the
// shape, to avoid having areas outside the shape
// react on the mouse
if( aCurrBroadcaster->first->getBounds().isInside( aPosition ) &&
aCurrBroadcaster->first->isVisible() )
{
// shape hit, and shape is visible. Raise
// event.
boost::shared_ptr<cppu::OInterfaceContainerHelper> const pCont(
aCurrBroadcaster->second );
uno::Reference<drawing::XShape> const xShape(
aCurrBroadcaster->first->getXShape() );
// DON'T do anything with /this/ after this point!
pCont->forEach<presentation::XShapeEventListener>(
boost::bind( &presentation::XShapeEventListener::click,
_1,
boost::cref(xShape),
boost::cref(e) ));
return true; // handled this event
}
++aCurrBroadcaster;
}
return false; // did not handle this event
}
bool ShapeManagerImpl::handleMouseEntered( const awt::MouseEvent& )
{
// not used here
return false; // did not handle the event
}
bool ShapeManagerImpl::handleMouseExited( const awt::MouseEvent& )
{
// not used here
return false; // did not handle the event
}
bool ShapeManagerImpl::handleMouseDragged( const awt::MouseEvent& )
{
// not used here
return false; // did not handle the event
}
bool ShapeManagerImpl::handleMouseMoved( const awt::MouseEvent& e )
{
if( !mbEnabled )
return false;
// find hit shape in map
const ::basegfx::B2DPoint aPosition( e.X, e.Y );
sal_Int16 nNewCursor(-1);
if( checkForHyperlink(aPosition).getLength() > 0 )
{
nNewCursor = awt::SystemPointer::REFHAND;
}
else
{
// find matching shape (scan reversely, to coarsely match
// paint order)
ShapeToCursorMap::reverse_iterator aCurrCursor(
maShapeCursorMap.rbegin() );
ShapeToCursorMap::reverse_iterator const aEndCursors(
maShapeCursorMap.rend() );
while( aCurrCursor != aEndCursors )
{
// TODO(F2): Get proper geometry polygon from the
// shape, to avoid having areas outside the shape
// react on the mouse
if( aCurrCursor->first->getBounds().isInside( aPosition ) &&
aCurrCursor->first->isVisible() )
{
// shape found, and it's visible. set
// requested cursor to shape's
nNewCursor = aCurrCursor->second;
break;
}
++aCurrCursor;
}
}
if( nNewCursor == -1 )
mrCursorManager.resetCursor();
else
mrCursorManager.requestCursor( nNewCursor );
return false; // we don't /eat/ this event. Lower prio
// handler should see it, too.
}
bool ShapeManagerImpl::update()
{
if( mbEnabled && mpLayerManager )
return mpLayerManager->update();
return false;
}
bool ShapeManagerImpl::update( ViewSharedPtr const& /*rView*/ )
{
// am not doing view-specific updates here.
return false;
}
bool ShapeManagerImpl::needsUpdate() const
{
if( mbEnabled && mpLayerManager )
return mpLayerManager->isUpdatePending();
return false;
}
void ShapeManagerImpl::enterAnimationMode( const AnimatableShapeSharedPtr& rShape )
{
if( mbEnabled && mpLayerManager )
mpLayerManager->enterAnimationMode(rShape);
}
void ShapeManagerImpl::leaveAnimationMode( const AnimatableShapeSharedPtr& rShape )
{
if( mbEnabled && mpLayerManager )
mpLayerManager->leaveAnimationMode(rShape);
}
void ShapeManagerImpl::notifyShapeUpdate( const ShapeSharedPtr& rShape )
{
if( mbEnabled && mpLayerManager )
mpLayerManager->notifyShapeUpdate(rShape);
}
ShapeSharedPtr ShapeManagerImpl::lookupShape( uno::Reference< drawing::XShape > const & xShape ) const
{
if( mpLayerManager )
return mpLayerManager->lookupShape(xShape);
return ShapeSharedPtr();
}
void ShapeManagerImpl::addHyperlinkArea( const HyperlinkAreaSharedPtr& rArea )
{
maHyperlinkShapes.insert(rArea);
}
void ShapeManagerImpl::removeHyperlinkArea( const HyperlinkAreaSharedPtr& rArea )
{
maHyperlinkShapes.erase(rArea);
}
AttributableShapeSharedPtr ShapeManagerImpl::getSubsetShape( const AttributableShapeSharedPtr& rOrigShape,
const DocTreeNode& rTreeNode )
{
if( mpLayerManager )
return mpLayerManager->getSubsetShape(rOrigShape,rTreeNode);
return AttributableShapeSharedPtr();
}
void ShapeManagerImpl::revokeSubset( const AttributableShapeSharedPtr& rOrigShape,
const AttributableShapeSharedPtr& rSubsetShape )
{
if( mpLayerManager )
mpLayerManager->revokeSubset(rOrigShape,rSubsetShape);
}
bool ShapeManagerImpl::listenerAdded(
const uno::Reference<presentation::XShapeEventListener>& /*xListener*/,
const uno::Reference<drawing::XShape>& xShape )
{
ShapeEventListenerMap::const_iterator aIter;
if( (aIter = mrGlobalListenersMap.find( xShape )) ==
mrGlobalListenersMap.end() )
{
ENSURE_AND_RETURN(false,
"ShapeManagerImpl::listenerAdded(): global "
"shape listener map inconsistency!");
}
// is this one of our shapes? other shapes are ignored.
ShapeSharedPtr pShape( lookupShape(xShape) );
if( pShape )
{
maShapeListenerMap.insert(
ShapeToListenersMap::value_type(
pShape,
aIter->second));
}
return true;
}
bool ShapeManagerImpl::listenerRemoved(
const uno::Reference<presentation::XShapeEventListener>& /*xListener*/,
const uno::Reference<drawing::XShape>& xShape )
{
// shape really erased from map? maybe there are other listeners
// for the same shape pending...
if( mrGlobalListenersMap.find(xShape) == mrGlobalListenersMap.end() )
{
// is this one of our shapes? other shapes are ignored.
ShapeSharedPtr pShape( lookupShape(xShape) );
if( pShape )
maShapeListenerMap.erase(pShape);
}
return true;
}
bool ShapeManagerImpl::cursorChanged( const uno::Reference<drawing::XShape>& xShape,
sal_Int16 nCursor )
{
ShapeSharedPtr pShape( lookupShape(xShape) );
if( mrGlobalCursorMap.find(xShape) == mrGlobalCursorMap.end() )
{
// erased from global map - erase locally, too
maShapeCursorMap.erase(pShape);
}
else
{
// included in global map - update local one
ShapeToCursorMap::iterator aIter;
if( (aIter = maShapeCursorMap.find(pShape))
== maShapeCursorMap.end() )
{
maShapeCursorMap.insert(
ShapeToCursorMap::value_type(
pShape,
nCursor ));
}
else
{
aIter->second = nCursor;
}
}
return true;
}
rtl::OUString ShapeManagerImpl::checkForHyperlink( basegfx::B2DPoint const& hitPos ) const
{
// find matching region (scan reversely, to coarsely match
// paint order): set is ordered by priority
AreaSet::const_reverse_iterator iPos( maHyperlinkShapes.rbegin() );
AreaSet::const_reverse_iterator const iEnd( maHyperlinkShapes.rend() );
for( ; iPos != iEnd; ++iPos )
{
HyperlinkAreaSharedPtr const& pArea = *iPos;
HyperlinkArea::HyperlinkRegions const linkRegions(
pArea->getHyperlinkRegions() );
for( std::size_t i = linkRegions.size(); i--; )
{
basegfx::B2DRange const& region = linkRegions[i].first;
if( region.isInside(hitPos) )
return linkRegions[i].second;
}
}
return rtl::OUString();
}
void ShapeManagerImpl::addIntrinsicAnimationHandler( const IntrinsicAnimationEventHandlerSharedPtr& rHandler )
{
maIntrinsicAnimationEventHandlers.add( rHandler );
}
void ShapeManagerImpl::removeIntrinsicAnimationHandler( const IntrinsicAnimationEventHandlerSharedPtr& rHandler )
{
maIntrinsicAnimationEventHandlers.remove( rHandler );
}
bool ShapeManagerImpl::notifyIntrinsicAnimationsEnabled()
{
return maIntrinsicAnimationEventHandlers.applyAll(
boost::mem_fn(&IntrinsicAnimationEventHandler::enableAnimations));
}
bool ShapeManagerImpl::notifyIntrinsicAnimationsDisabled()
{
return maIntrinsicAnimationEventHandlers.applyAll(
boost::mem_fn(&IntrinsicAnimationEventHandler::disableAnimations));
}
} // namespace internal
} // namespace presentation