/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include class LokControlHandler { public: static bool postMouseEvent(const SdrPage* pPage, const SdrView* pDrawView, vcl::Window const& rMainWindow, int nType, Point aPointHmm, int nCount, int nButtons, int nModifier) { SdrObjListIter aIterator(pPage, SdrIterMode::Flat); while (aIterator.IsMore()) { SdrObject* pObject = aIterator.Next(); SdrUnoObj* pUnoObect = dynamic_cast(pObject); if (pUnoObect) { tools::Rectangle aControlRectHMM = pUnoObect->GetLogicRect(); if (aControlRectHMM.Contains(aPointHmm)) { css::uno::Reference xControl = pUnoObect->GetUnoControl(*pDrawView, *rMainWindow.GetOutDev()); if (!xControl.is()) return false; css::uno::Reference xControlWindow(xControl, css::uno::UNO_QUERY); if (!xControlWindow.is()) return false; css::uno::Reference xWindowPeer(xControl->getPeer()); VclPtr pWindow = VCLUnoHelper::GetWindow(xWindowPeer); if (pWindow) { Point aControlRelativePositionHMM = aPointHmm - aControlRectHMM.TopLeft(); Point aControlRelativePosition = o3tl::convert( aControlRelativePositionHMM, o3tl::Length::mm100, o3tl::Length::px); LokMouseEventData aMouseEventData(nType, aControlRelativePosition, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier); SfxLokHelper::postMouseEventAsync(pWindow, aMouseEventData); return true; } } } } return false; } static void drawUnoControl(const SdrView* pDrawView, const SdrUnoObj* pUnoObect, vcl::Window const& rMainWindow, VirtualDevice& rDevice, tools::Rectangle const& rTileRectHMM, double scaleX, double scaleY) { css::uno::Reference xControl = pUnoObect->GetUnoControl(*pDrawView, *rMainWindow.GetOutDev()); if (!xControl.is()) return; css::uno::Reference xControlWindow(xControl, css::uno::UNO_QUERY); if (!xControlWindow.is()) return; css::uno::Reference xGraphics(rDevice.CreateUnoGraphics()); if (!xGraphics.is()) return; css::uno::Reference xControlView(xControl, css::uno::UNO_QUERY); if (!xControlView.is()) return; tools::Rectangle aObjectRectHMM = pUnoObect->GetLogicRect(); Point aOffsetFromTile(aObjectRectHMM.Left() - rTileRectHMM.Left(), aObjectRectHMM.Top() - rTileRectHMM.Top()); tools::Rectangle aRectangleHMM(aOffsetFromTile, aObjectRectHMM.GetSize()); tools::Rectangle aRectanglePx = o3tl::convert(aRectangleHMM, o3tl::Length::mm100, o3tl::Length::px); xControlWindow->setPosSize(0, 0, aRectanglePx.GetWidth(), aRectanglePx.GetHeight(), css::awt::PosSize::POSSIZE); xControlView->setGraphics(xGraphics); xControlView->draw(aRectanglePx.Left() * scaleX, aRectanglePx.Top() * scaleY); } static void paintControlTile(const SdrPage* pPage, const SdrView* pDrawView, vcl::Window const& rMainWindow, VirtualDevice& rDevice, Size aOutputSize, tools::Rectangle const& rTileRect) { tools::Rectangle aTileRectHMM = o3tl::convert(rTileRect, o3tl::Length::twip, o3tl::Length::mm100); // Resizes the virtual device so to contain the entries context rDevice.SetOutputSizePixel(aOutputSize); rDevice.Push(vcl::PushFlags::MAPMODE); MapMode aDeviceMapMode(rDevice.GetMapMode()); const Fraction scale = conversionFract(o3tl::Length::px, o3tl::Length::mm100); Fraction scaleX = Fraction(aOutputSize.Width(), aTileRectHMM.GetWidth()) * scale; Fraction scaleY = Fraction(aOutputSize.Height(), aTileRectHMM.GetHeight()) * scale; aDeviceMapMode.SetScaleX(scaleX); aDeviceMapMode.SetScaleY(scaleY); rDevice.SetMapMode(aDeviceMapMode); SdrObjListIter aIterator(pPage, SdrIterMode::Flat); while (aIterator.IsMore()) { SdrObject* pObject = aIterator.Next(); SdrUnoObj* pUnoObect = dynamic_cast(pObject); if (pUnoObect) { tools::Rectangle aObjectRectHMM = pUnoObect->GetLogicRect(); // Check if we intersect with the tile rectangle and we // need to draw the control. if (aObjectRectHMM.Overlaps(aTileRectHMM)) { drawUnoControl(pDrawView, pUnoObect, rMainWindow, rDevice, aTileRectHMM, double(scaleX), double(scaleY)); } } } rDevice.Pop(); } }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */