Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / include / sfx2 / LokControlHandler.hxx
bloba292f137471b547b3f98f445cf44a23dfdbf8018
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #pragma once
12 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
13 #include <sfx2/dllapi.h>
14 #include <sfx2/lokhelper.hxx>
15 #include <svx/svdouno.hxx>
16 #include <svx/svditer.hxx>
17 #include <vcl/virdev.hxx>
18 #include <vcl/DocWindow.hxx>
19 #include <com/sun/star/awt/PosSize.hpp>
20 #include <com/sun/star/awt/XControl.hpp>
21 #include <com/sun/star/awt/XWindow.hpp>
22 #include <com/sun/star/awt/XWindowPeer.hpp>
23 #include <com/sun/star/awt/XGraphics.hpp>
24 #include <com/sun/star/awt/XView.hpp>
25 #include <toolkit/helper/vclunohelper.hxx>
26 #include <tools/UnitConversion.hxx>
28 #include <sal/log.hxx>
30 #include <optional>
32 class LokControlHandler
34 public:
35 static bool postMouseEvent(const SdrPage* pPage, const SdrView* pDrawView,
36 vcl::DocWindow& rMainWindow, int nType, Point aPointHmm, int nCount,
37 int nButtons, int nModifier)
39 static std::optional<PointerStyle> eDocPointerStyle;
41 o3tl::Length eControlUnitLength = MapToO3tlLength(rMainWindow.GetMapMode().GetMapUnit());
42 SdrObjListIter aIterator(pPage, SdrIterMode::Flat);
43 while (aIterator.IsMore())
45 SdrObject* pObject = aIterator.Next();
46 SdrUnoObj* pUnoObect = dynamic_cast<SdrUnoObj*>(pObject);
47 if (pUnoObect)
49 tools::Rectangle aControlRect = pUnoObect->GetLogicRect();
50 tools::Rectangle aControlRectHMM
51 = o3tl::convert(aControlRect, eControlUnitLength, o3tl::Length::mm100);
53 if (aControlRectHMM.Contains(aPointHmm))
55 css::uno::Reference<css::awt::XControl> xControl
56 = pUnoObect->GetUnoControl(*pDrawView, *rMainWindow.GetOutDev());
57 if (!xControl.is())
58 return false;
60 css::uno::Reference<css::awt::XWindow> xControlWindow(xControl,
61 css::uno::UNO_QUERY);
62 if (!xControlWindow.is())
63 return false;
65 css::uno::Reference<css::awt::XWindowPeer> xWindowPeer(xControl->getPeer());
67 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow(xWindowPeer);
68 if (pWindow)
70 tools::Rectangle aControlRectPx
71 = o3tl::convert(aControlRectHMM, o3tl::Length::mm100, o3tl::Length::px);
72 // used by Control::LogicInvalidate
73 pWindow->SetPosPixel(aControlRectPx.TopLeft());
75 // when entering into control area save current pointer style
76 // and set pointer style to arrow
77 if (!eDocPointerStyle)
79 eDocPointerStyle = rMainWindow.GetPointer();
80 rMainWindow.SetPointer(pWindow->GetPointer());
83 Point aControlRelativePositionHMM = aPointHmm - aControlRectHMM.TopLeft();
84 Point aControlRelativePosition = o3tl::convert(
85 aControlRelativePositionHMM, o3tl::Length::mm100, o3tl::Length::px);
87 LokMouseEventData aMouseEventData(nType, aControlRelativePosition, nCount,
88 MouseEventModifiers::SIMPLECLICK,
89 nButtons, nModifier);
90 SfxLokHelper::postMouseEventAsync(pWindow, aMouseEventData);
91 return true;
97 // when exiting from control area restore document pointer style
98 if (eDocPointerStyle)
100 rMainWindow.SetPointer(*eDocPointerStyle);
101 eDocPointerStyle.reset();
103 return false;
106 static void drawUnoControl(const SdrView* pDrawView, const SdrUnoObj* pUnoObect,
107 vcl::Window const& rMainWindow, VirtualDevice& rDevice,
108 tools::Rectangle const& rTileRectHMM, double scaleX, double scaleY)
110 css::uno::Reference<css::awt::XControl> xControl
111 = pUnoObect->GetUnoControl(*pDrawView, *rMainWindow.GetOutDev());
112 if (!xControl.is())
113 return;
115 css::uno::Reference<css::awt::XWindow> xControlWindow(xControl, css::uno::UNO_QUERY);
116 if (!xControlWindow.is())
117 return;
119 css::uno::Reference<css::awt::XGraphics> xGraphics(rDevice.CreateUnoGraphics());
120 if (!xGraphics.is())
121 return;
123 css::uno::Reference<css::awt::XView> xControlView(xControl, css::uno::UNO_QUERY);
124 if (!xControlView.is())
125 return;
127 o3tl::Length eControlUnitLength = MapToO3tlLength(rMainWindow.GetMapMode().GetMapUnit());
128 tools::Rectangle aControlRect = pUnoObect->GetLogicRect();
129 tools::Rectangle aObjectRectHMM
130 = o3tl::convert(aControlRect, eControlUnitLength, o3tl::Length::mm100);
131 tools::Rectangle aControltRectPx
132 = o3tl::convert(aObjectRectHMM, o3tl::Length::mm100, o3tl::Length::px);
134 Point aOffsetFromTile(aObjectRectHMM.Left() - rTileRectHMM.Left(),
135 aObjectRectHMM.Top() - rTileRectHMM.Top());
136 tools::Rectangle aRectangleHMM(aOffsetFromTile, aObjectRectHMM.GetSize());
137 tools::Rectangle aRectanglePx
138 = o3tl::convert(aRectangleHMM, o3tl::Length::mm100, o3tl::Length::px);
140 xControlWindow->setPosSize(aControltRectPx.Left(), aControltRectPx.Top(),
141 aRectanglePx.GetWidth(), aRectanglePx.GetHeight(),
142 css::awt::PosSize::POSSIZE);
144 xControlView->setGraphics(xGraphics);
145 // required for getting text label rendered with the correct scale
146 xControlView->setZoom(1, 1);
148 xControlView->draw(aRectanglePx.Left() * scaleX, aRectanglePx.Top() * scaleY);
151 static void paintControlTile(const SdrPage* pPage, const SdrView* pDrawView,
152 vcl::Window const& rMainWindow, VirtualDevice& rDevice,
153 Size aOutputSize, tools::Rectangle const& rTileRect)
155 tools::Rectangle aTileRectHMM
156 = o3tl::convert(rTileRect, o3tl::Length::twip, o3tl::Length::mm100);
158 // Resizes the virtual device so to contain the entries context
159 rDevice.SetOutputSizePixel(aOutputSize);
161 rDevice.Push(vcl::PushFlags::MAPMODE);
162 MapMode aDeviceMapMode(rDevice.GetMapMode());
164 const Fraction scale = conversionFract(o3tl::Length::px, o3tl::Length::twip);
165 Fraction scaleX = Fraction(aOutputSize.Width(), rTileRect.GetWidth()) * scale;
166 Fraction scaleY = Fraction(aOutputSize.Height(), rTileRect.GetHeight()) * scale;
167 aDeviceMapMode.SetScaleX(scaleX);
168 aDeviceMapMode.SetScaleY(scaleY);
169 aDeviceMapMode.SetMapUnit(MapUnit::MapPixel);
170 rDevice.SetMapMode(aDeviceMapMode);
172 o3tl::Length eControlUnitLength = MapToO3tlLength(rMainWindow.GetMapMode().GetMapUnit());
173 SdrObjListIter aIterator(pPage, SdrIterMode::Flat);
175 while (aIterator.IsMore())
177 SdrObject* pObject = aIterator.Next();
178 SdrUnoObj* pUnoObect = dynamic_cast<SdrUnoObj*>(pObject);
179 if (pUnoObect)
181 tools::Rectangle aControlRect = pUnoObect->GetLogicRect();
182 tools::Rectangle aObjectRectHMM
183 = o3tl::convert(aControlRect, eControlUnitLength, o3tl::Length::mm100);
185 // Check if we intersect with the tile rectangle and we
186 // need to draw the control.
187 if (aObjectRectHMM.Overlaps(aTileRectHMM))
189 drawUnoControl(pDrawView, pUnoObect, rMainWindow, rDevice, aTileRectHMM,
190 double(scaleX), double(scaleY));
195 rDevice.Pop();
199 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */