blob: c3691c776d36d2628dbd9582b969f228b81df113 [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.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sdext.hxx"
#include "PresenterPaneBase.hxx"
#include "PresenterCanvasHelper.hxx"
#include "PresenterController.hxx"
#include "PresenterGeometryHelper.hxx"
#include "PresenterPaintManager.hxx"
#include "PresenterTextView.hxx"
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/XWindow2.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/drawing/CanvasFeature.hpp>
#include <com/sun/star/rendering/CompositeOperation.hpp>
#include <com/sun/star/rendering/TexturingMode.hpp>
#include <osl/mutex.hxx>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::drawing::framework;
using ::rtl::OUString;
namespace sdext { namespace presenter {
//===== PresenterPaneBase =====================================================
PresenterPaneBase::PresenterPaneBase (
const Reference<XComponentContext>& rxContext,
const ::rtl::Reference<PresenterController>& rpPresenterController)
: PresenterPaneBaseInterfaceBase(m_aMutex),
mpPresenterController(rpPresenterController),
mxParentWindow(),
mxBorderWindow(),
mxBorderCanvas(),
mxContentWindow(),
mxContentCanvas(),
mxPaneId(),
mxBorderPainter(),
mxPresenterHelper(),
msTitle(),
mxComponentContext(rxContext),
mpViewBackground(),
mbHasCallout(false),
maCalloutAnchor()
{
if (mpPresenterController.get() != NULL)
mxPresenterHelper = mpPresenterController->GetPresenterHelper();
}
PresenterPaneBase::~PresenterPaneBase (void)
{
}
void PresenterPaneBase::disposing (void)
{
if (mxBorderWindow.is())
{
mxBorderWindow->removeWindowListener(this);
mxBorderWindow->removePaintListener(this);
}
{
Reference<XComponent> xComponent (mxContentCanvas, UNO_QUERY);
mxContentCanvas = NULL;
if (xComponent.is())
xComponent->dispose();
}
{
Reference<XComponent> xComponent (mxContentWindow, UNO_QUERY);
mxContentWindow = NULL;
if (xComponent.is())
xComponent->dispose();
}
{
Reference<XComponent> xComponent (mxBorderCanvas, UNO_QUERY);
mxBorderCanvas = NULL;
if (xComponent.is())
xComponent->dispose();
}
{
Reference<XComponent> xComponent (mxBorderWindow, UNO_QUERY);
mxBorderWindow = NULL;
if (xComponent.is())
xComponent->dispose();
}
mxComponentContext = NULL;
}
void PresenterPaneBase::SetTitle (const OUString& rsTitle)
{
msTitle = rsTitle;
OSL_ASSERT(mpPresenterController.get()!=NULL);
OSL_ASSERT(mpPresenterController->GetPaintManager().get()!=NULL);
mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow);
}
::rtl::OUString PresenterPaneBase::GetTitle (void) const
{
return msTitle;
}
Reference<drawing::framework::XPaneBorderPainter>
PresenterPaneBase::GetPaneBorderPainter (void) const
{
return mxBorderPainter;
}
void PresenterPaneBase::SetCalloutAnchor (const css::awt::Point& rCalloutAnchor)
{
mbHasCallout = true;
// Anchor is given in the coorindate system of the parent window.
// Transform it into the local coordinate system.
maCalloutAnchor = rCalloutAnchor;
const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
maCalloutAnchor.X -= aBorderBox.X;
maCalloutAnchor.Y -= aBorderBox.Y;
// Move the bottom of the border window so that it goes through the
// callout anchor (special case for bottom callout).
sal_Int32 nHeight (rCalloutAnchor.Y - aBorderBox.Y);
if (mxBorderPainter.is() && mxPaneId.is())
nHeight += mxBorderPainter->getCalloutOffset(mxPaneId->getResourceURL()).Y;
if (nHeight != aBorderBox.Height)
{
mxBorderWindow->setPosSize(
aBorderBox.X,
aBorderBox.Y,
aBorderBox.Width,
nHeight,
awt::PosSize::HEIGHT);
}
mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow);
}
awt::Point PresenterPaneBase::GetCalloutAnchor (void) const
{
return maCalloutAnchor;
}
::boost::shared_ptr<PresenterTextView> PresenterPaneBase::GetTextViewForTitle (void)
{
::boost::shared_ptr<PresenterTextView> pTextView(
new PresenterTextView(
mxComponentContext,
mxBorderCanvas));
pTextView->SetText(msTitle);
return pTextView;
}
//----- XInitialization -------------------------------------------------------
void SAL_CALL PresenterPaneBase::initialize (const Sequence<Any>& rArguments)
throw (Exception, RuntimeException)
{
ThrowIfDisposed();
if ( ! mxComponentContext.is())
{
throw RuntimeException(
OUString::createFromAscii("PresenterSpritePane: missing component context"),
static_cast<XWeak*>(this));
}
if (rArguments.getLength() == 5 || rArguments.getLength() == 6)
{
try
{
// Get the resource id from the first argument.
if ( ! (rArguments[0] >>= mxPaneId))
{
throw lang::IllegalArgumentException(
OUString::createFromAscii("PresenterPane: invalid pane id"),
static_cast<XWeak*>(this),
0);
}
if ( ! (rArguments[1] >>= mxParentWindow))
{
throw lang::IllegalArgumentException(
OUString::createFromAscii("PresenterPane: invalid parent window"),
static_cast<XWeak*>(this),
1);
}
Reference<rendering::XSpriteCanvas> xParentCanvas;
if ( ! (rArguments[2] >>= xParentCanvas))
{
throw lang::IllegalArgumentException(
OUString::createFromAscii("PresenterPane: invalid parent canvas"),
static_cast<XWeak*>(this),
2);
}
if ( ! (rArguments[3] >>= msTitle))
{
throw lang::IllegalArgumentException(
OUString::createFromAscii("PresenterPane: invalid title"),
static_cast<XWeak*>(this),
3);
}
if ( ! (rArguments[4] >>= mxBorderPainter))
{
throw lang::IllegalArgumentException(
OUString::createFromAscii("PresenterPane: invalid border painter"),
static_cast<XWeak*>(this),
4);
}
bool bIsWindowVisibleOnCreation (true);
if (rArguments.getLength()>5 && ! (rArguments[5] >>= bIsWindowVisibleOnCreation))
{
throw lang::IllegalArgumentException(
OUString::createFromAscii("PresenterPane: invalid window visibility flag"),
static_cast<XWeak*>(this),
5);
}
CreateWindows(mxParentWindow, bIsWindowVisibleOnCreation);
if (mxBorderWindow.is())
{
mxBorderWindow->addWindowListener(this);
mxBorderWindow->addPaintListener(this);
}
CreateCanvases(mxParentWindow, xParentCanvas);
// Raise new windows.
ToTop();
}
catch (Exception&)
{
mxContentWindow = NULL;
mxComponentContext = NULL;
throw;
}
}
else
{
throw RuntimeException(
OUString::createFromAscii("PresenterSpritePane: invalid number of arguments"),
static_cast<XWeak*>(this));
}
}
//----- XResourceId -----------------------------------------------------------
Reference<XResourceId> SAL_CALL PresenterPaneBase::getResourceId (void)
throw (RuntimeException)
{
ThrowIfDisposed();
return mxPaneId;
}
sal_Bool SAL_CALL PresenterPaneBase::isAnchorOnly (void)
throw (RuntimeException)
{
return true;
}
//----- XWindowListener -------------------------------------------------------
void SAL_CALL PresenterPaneBase::windowResized (const awt::WindowEvent& rEvent)
throw (RuntimeException)
{
(void)rEvent;
ThrowIfDisposed();
}
void SAL_CALL PresenterPaneBase::windowMoved (const awt::WindowEvent& rEvent)
throw (RuntimeException)
{
(void)rEvent;
ThrowIfDisposed();
}
void SAL_CALL PresenterPaneBase::windowShown (const lang::EventObject& rEvent)
throw (RuntimeException)
{
(void)rEvent;
ThrowIfDisposed();
}
void SAL_CALL PresenterPaneBase::windowHidden (const lang::EventObject& rEvent)
throw (RuntimeException)
{
(void)rEvent;
ThrowIfDisposed();
}
//----- lang::XEventListener --------------------------------------------------
void SAL_CALL PresenterPaneBase::disposing (const lang::EventObject& rEvent)
throw (RuntimeException)
{
if (rEvent.Source == mxBorderWindow)
{
mxBorderWindow = NULL;
}
}
//-----------------------------------------------------------------------------
void PresenterPaneBase::CreateWindows (
const Reference<awt::XWindow>& rxParentWindow,
const bool bIsWindowVisibleOnCreation)
{
if (mxPresenterHelper.is() && rxParentWindow.is())
{
mxBorderWindow = mxPresenterHelper->createWindow(
rxParentWindow,
sal_False,
bIsWindowVisibleOnCreation,
sal_False,
sal_False);
mxContentWindow = mxPresenterHelper->createWindow(
mxBorderWindow,
sal_False,
bIsWindowVisibleOnCreation,
sal_False,
sal_False);
}
}
Reference<awt::XWindow> PresenterPaneBase::GetBorderWindow (void) const
{
return mxBorderWindow;
}
void PresenterPaneBase::ToTop (void)
{
if (mxPresenterHelper.is())
mxPresenterHelper->toTop(mxContentWindow);
}
void PresenterPaneBase::SetBackground (const SharedBitmapDescriptor& rpBackground)
{
mpViewBackground = rpBackground;
}
void PresenterPaneBase::PaintBorderBackground (
const awt::Rectangle& rBorderBox,
const awt::Rectangle& rUpdateBox)
{
(void)rBorderBox;
(void)rUpdateBox;
/*
// The outer box of the border is given. We need the center and inner
// box as well.
awt::Rectangle aCenterBox (
mxBorderPainter->removeBorder(
mxPaneId->getResourceURL(),
rBorderBox,
drawing::framework::BorderType_OUTER_BORDER));
awt::Rectangle aInnerBox (
mxBorderPainter->removeBorder(
mxPaneId->getResourceURL(),
rBorderBox,
drawing::framework::BorderType_TOTAL_BORDER));
mpPresenterController->GetCanvasHelper()->Paint(
mpViewBackground,
mxBorderCanvas,
rUpdateBox,
aCenterBox,
aInnerBox);
*/
}
void PresenterPaneBase::PaintBorder (const awt::Rectangle& rUpdateBox)
{
OSL_ASSERT(mxPaneId.is());
if (mxBorderPainter.is() && mxBorderWindow.is() && mxBorderCanvas.is())
{
awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
awt::Rectangle aLocalBorderBox (0,0, aBorderBox.Width, aBorderBox.Height);
PaintBorderBackground(aLocalBorderBox, rUpdateBox);
if (mbHasCallout)
mxBorderPainter->paintBorderWithCallout(
mxPaneId->getResourceURL(),
mxBorderCanvas,
aLocalBorderBox,
rUpdateBox,
msTitle,
maCalloutAnchor);
else
mxBorderPainter->paintBorder(
mxPaneId->getResourceURL(),
mxBorderCanvas,
aLocalBorderBox,
rUpdateBox,
msTitle);
}
}
void PresenterPaneBase::LayoutContextWindow (void)
{
OSL_ASSERT(mxPaneId.is());
OSL_ASSERT(mxBorderWindow.is());
OSL_ASSERT(mxContentWindow.is());
if (mxBorderPainter.is() && mxPaneId.is() && mxBorderWindow.is() && mxContentWindow.is())
{
const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
const awt::Rectangle aInnerBox (mxBorderPainter->removeBorder(
mxPaneId->getResourceURL(),
aBorderBox,
drawing::framework::BorderType_TOTAL_BORDER));
mxContentWindow->setPosSize(
aInnerBox.X - aBorderBox.X,
aInnerBox.Y - aBorderBox.Y,
aInnerBox.Width,
aInnerBox.Height,
awt::PosSize::POSSIZE);
}
}
bool PresenterPaneBase::IsVisible (void) const
{
Reference<awt::XWindow2> xWindow2 (mxBorderPainter, UNO_QUERY);
if (xWindow2.is())
return xWindow2->isVisible();
return false;
}
void PresenterPaneBase::ThrowIfDisposed (void)
throw (::com::sun::star::lang::DisposedException)
{
if (rBHelper.bDisposed || rBHelper.bInDispose)
{
throw lang::DisposedException (
::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"PresenterPane object has already been disposed")),
static_cast<uno::XWeak*>(this));
}
}
} } // end of namespace ::sd::presenter