fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / svx / source / sdr / contact / viewobjectcontact.cxx
blob479d09d50f6311585c170d1cd87493c8f6daf9f1
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/sdr/contact/viewobjectcontact.hxx>
21 #include <svx/sdr/contact/viewcontact.hxx>
22 #include <svx/sdr/contact/objectcontact.hxx>
23 #include <svx/sdr/contact/displayinfo.hxx>
24 #include <vcl/region.hxx>
25 #include <svx/sdr/animation/objectanimator.hxx>
26 #include <svx/sdr/animation/animationstate.hxx>
27 #include <svx/sdr/contact/viewobjectcontactredirector.hxx>
28 #include <basegfx/numeric/ftools.hxx>
29 #include <basegfx/color/bcolor.hxx>
30 #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
31 #include <basegfx/tools/canvastools.hxx>
32 #include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
33 #include <drawinglayer/processor2d/baseprocessor2d.hxx>
34 #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx>
36 //////////////////////////////////////////////////////////////////////////////
38 using namespace com::sun::star;
40 //////////////////////////////////////////////////////////////////////////////
42 namespace
44 // animated extractor
46 // Necessary to filter a sequence of animated primitives from
47 // a sequence of primitives to find out if animated or not. The decision for
48 // what to decompose is hard-coded and only done for knowingly animated primitives
49 // to not decompose too deeply and unnecessarily. This implies that the list
50 // which is view-specific needs to be expanded by hand when new animated objects
51 // are added. This may eventually be changed to a dynamically configurable approach
52 // if necessary.
53 class AnimatedExtractingProcessor2D : public drawinglayer::processor2d::BaseProcessor2D
55 protected:
56 // the found animated primitives
57 drawinglayer::primitive2d::Primitive2DSequence maPrimitive2DSequence;
59 // bitfield
60 // text animation allowed?
61 unsigned mbTextAnimationAllowed : 1;
63 // graphic animation allowed?
64 unsigned mbGraphicAnimationAllowed : 1;
66 // as tooling, the process() implementation takes over API handling and calls this
67 // virtual render method when the primitive implementation is BasePrimitive2D-based.
68 virtual void processBasePrimitive2D(const drawinglayer::primitive2d::BasePrimitive2D& rCandidate);
70 public:
71 AnimatedExtractingProcessor2D(
72 const drawinglayer::geometry::ViewInformation2D& rViewInformation,
73 bool bTextAnimationAllowed,
74 bool bGraphicAnimationAllowed);
75 virtual ~AnimatedExtractingProcessor2D();
77 // data access
78 const drawinglayer::primitive2d::Primitive2DSequence& getPrimitive2DSequence() const { return maPrimitive2DSequence; }
79 bool isTextAnimationAllowed() const { return mbTextAnimationAllowed; }
80 bool isGraphicAnimationAllowed() const { return mbGraphicAnimationAllowed; }
83 AnimatedExtractingProcessor2D::AnimatedExtractingProcessor2D(
84 const drawinglayer::geometry::ViewInformation2D& rViewInformation,
85 bool bTextAnimationAllowed,
86 bool bGraphicAnimationAllowed)
87 : drawinglayer::processor2d::BaseProcessor2D(rViewInformation),
88 maPrimitive2DSequence(),
89 mbTextAnimationAllowed(bTextAnimationAllowed),
90 mbGraphicAnimationAllowed(bGraphicAnimationAllowed)
94 AnimatedExtractingProcessor2D::~AnimatedExtractingProcessor2D()
98 void AnimatedExtractingProcessor2D::processBasePrimitive2D(const drawinglayer::primitive2d::BasePrimitive2D& rCandidate)
100 // known implementation, access directly
101 switch(rCandidate.getPrimitive2DID())
103 // add and accept animated primitives directly, no need to decompose
104 case PRIMITIVE2D_ID_ANIMATEDSWITCHPRIMITIVE2D :
105 case PRIMITIVE2D_ID_ANIMATEDBLINKPRIMITIVE2D :
106 case PRIMITIVE2D_ID_ANIMATEDINTERPOLATEPRIMITIVE2D :
108 const drawinglayer::primitive2d::AnimatedSwitchPrimitive2D& rSwitchPrimitive = static_cast< const drawinglayer::primitive2d::AnimatedSwitchPrimitive2D& >(rCandidate);
110 if((rSwitchPrimitive.isTextAnimation() && isTextAnimationAllowed())
111 || (rSwitchPrimitive.isGraphicAnimation() && isGraphicAnimationAllowed()))
113 const drawinglayer::primitive2d::Primitive2DReference xReference(const_cast< drawinglayer::primitive2d::BasePrimitive2D* >(&rCandidate));
114 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(maPrimitive2DSequence, xReference);
116 break;
119 // decompose animated gifs where SdrGrafPrimitive2D produces a GraphicPrimitive2D
120 // which then produces the animation infos (all when used/needed)
121 case PRIMITIVE2D_ID_SDRGRAFPRIMITIVE2D :
122 case PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D :
124 // decompose SdrObjects with evtl. animated text
125 case PRIMITIVE2D_ID_SDRCAPTIONPRIMITIVE2D :
126 case PRIMITIVE2D_ID_SDRCONNECTORPRIMITIVE2D :
127 case PRIMITIVE2D_ID_SDRCUSTOMSHAPEPRIMITIVE2D :
128 case PRIMITIVE2D_ID_SDRELLIPSEPRIMITIVE2D :
129 case PRIMITIVE2D_ID_SDRELLIPSESEGMENTPRIMITIVE2D :
130 case PRIMITIVE2D_ID_SDRMEASUREPRIMITIVE2D :
131 case PRIMITIVE2D_ID_SDRPATHPRIMITIVE2D :
132 case PRIMITIVE2D_ID_SDRRECTANGLEPRIMITIVE2D :
134 // decompose evtl. animated text contained in MaskPrimitive2D
135 // or group rimitives
136 case PRIMITIVE2D_ID_MASKPRIMITIVE2D :
137 case PRIMITIVE2D_ID_GROUPPRIMITIVE2D :
139 process(rCandidate.get2DDecomposition(getViewInformation2D()));
140 break;
143 default :
145 // nothing to do for the rest
146 break;
150 } // end of anonymous namespace
152 //////////////////////////////////////////////////////////////////////////////
154 namespace sdr
156 namespace contact
158 ViewObjectContact::ViewObjectContact(ObjectContact& rObjectContact, ViewContact& rViewContact)
159 : mrObjectContact(rObjectContact),
160 mrViewContact(rViewContact),
161 maObjectRange(),
162 mxPrimitive2DSequence(),
163 mpPrimitiveAnimation(0),
164 mbLazyInvalidate(false)
166 // make the ViewContact remember me
167 mrViewContact.AddViewObjectContact(*this);
169 // make the ObjectContact remember me
170 mrObjectContact.AddViewObjectContact(*this);
173 ViewObjectContact::~ViewObjectContact()
175 // invalidate in view
176 if(!maObjectRange.isEmpty())
178 GetObjectContact().InvalidatePartOfView(maObjectRange);
181 // delete PrimitiveAnimation
182 if(mpPrimitiveAnimation)
184 delete mpPrimitiveAnimation;
185 mpPrimitiveAnimation = 0;
188 // take care of remebered ObjectContact. Remove from
189 // OC first. The VC removal (below) CAN trigger a StopGettingViewed()
190 // which (depending of it's implementation) may destroy other OCs. This
191 // can trigger the deletion of the helper OC of a page visualising object
192 // which IS the OC of this object. Eventually StopGettingViewed() needs
193 // to get asynchron later
194 GetObjectContact().RemoveViewObjectContact(*this);
196 // take care of remebered ViewContact
197 GetViewContact().RemoveViewObjectContact(*this);
200 const basegfx::B2DRange& ViewObjectContact::getObjectRange() const
202 if(maObjectRange.isEmpty())
204 // if range is not computed (new or LazyInvalidate objects), force it
205 const DisplayInfo aDisplayInfo;
206 const drawinglayer::primitive2d::Primitive2DSequence xSequence(getPrimitive2DSequence(aDisplayInfo));
208 if(xSequence.hasElements())
210 const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D());
211 const_cast< ViewObjectContact* >(this)->maObjectRange =
212 drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xSequence, rViewInformation2D);
216 return maObjectRange;
219 void ViewObjectContact::ActionChanged()
221 if(!mbLazyInvalidate)
223 // set local flag
224 mbLazyInvalidate = true;
226 // force ObjectRange
227 getObjectRange();
229 if(!maObjectRange.isEmpty())
231 // invalidate current valid range
232 GetObjectContact().InvalidatePartOfView(maObjectRange);
234 // reset ObjectRange, it needs to be recalculated
235 maObjectRange.reset();
238 // register at OC for lazy invalidate
239 GetObjectContact().setLazyInvalidate(*this);
243 void ViewObjectContact::triggerLazyInvalidate()
245 if(mbLazyInvalidate)
247 // reset flag
248 mbLazyInvalidate = false;
250 // force ObjectRange
251 getObjectRange();
253 if(!maObjectRange.isEmpty())
255 // invalidate current valid range
256 GetObjectContact().InvalidatePartOfView(maObjectRange);
261 // Take some action when new objects are inserted
262 void ViewObjectContact::ActionChildInserted(ViewContact& rChild)
264 // force creation of the new VOC and trigger it's refresh, so it
265 // will take part in LazyInvalidate immediately
266 rChild.GetViewObjectContact(GetObjectContact()).ActionChanged();
268 // forward action to ObjectContact
269 // const ViewObjectContact& rChildVOC = rChild.GetViewObjectContact(GetObjectContact());
270 // GetObjectContact().InvalidatePartOfView(rChildVOC.getObjectRange());
273 void ViewObjectContact::checkForPrimitive2DAnimations()
275 // remove old one
276 if(mpPrimitiveAnimation)
278 delete mpPrimitiveAnimation;
279 mpPrimitiveAnimation = 0;
282 // check for animated primitives
283 if(mxPrimitive2DSequence.hasElements())
285 const bool bTextAnimationAllowed(GetObjectContact().IsTextAnimationAllowed());
286 const bool bGraphicAnimationAllowed(GetObjectContact().IsGraphicAnimationAllowed());
288 if(bTextAnimationAllowed || bGraphicAnimationAllowed)
290 AnimatedExtractingProcessor2D aAnimatedExtractor(GetObjectContact().getViewInformation2D(),
291 bTextAnimationAllowed, bGraphicAnimationAllowed);
292 aAnimatedExtractor.process(mxPrimitive2DSequence);
294 if(aAnimatedExtractor.getPrimitive2DSequence().hasElements())
296 // dervied primitiveList is animated, setup new PrimitiveAnimation
297 mpPrimitiveAnimation = new sdr::animation::PrimitiveAnimation(*this, aAnimatedExtractor.getPrimitive2DSequence());
303 drawinglayer::primitive2d::Primitive2DSequence ViewObjectContact::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
305 // get the view-independent Primitive from the viewContact
306 drawinglayer::primitive2d::Primitive2DSequence xRetval(GetViewContact().getViewIndependentPrimitive2DSequence());
308 if(xRetval.hasElements())
310 // handle GluePoint
311 if(!GetObjectContact().isOutputToPrinter() && GetObjectContact().AreGluePointsVisible())
313 const drawinglayer::primitive2d::Primitive2DSequence xGlue(GetViewContact().createGluePointPrimitive2DSequence());
315 if(xGlue.hasElements())
317 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, xGlue);
321 // handle ghosted
322 if(isPrimitiveGhosted(rDisplayInfo))
324 const basegfx::BColor aRGBWhite(1.0, 1.0, 1.0);
325 const basegfx::BColorModifier aBColorModifier(aRGBWhite, 0.5, basegfx::BCOLORMODIFYMODE_INTERPOLATE);
326 const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::ModifiedColorPrimitive2D(xRetval, aBColorModifier));
327 xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
331 return xRetval;
334 drawinglayer::primitive2d::Primitive2DSequence ViewObjectContact::getPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
336 drawinglayer::primitive2d::Primitive2DSequence xNewPrimitiveSequence;
338 // take care of redirectors and create new list
339 ViewObjectContactRedirector* pRedirector = GetObjectContact().GetViewObjectContactRedirector();
341 if(pRedirector)
343 xNewPrimitiveSequence = pRedirector->createRedirectedPrimitive2DSequence(*this, rDisplayInfo);
345 else
347 xNewPrimitiveSequence = createPrimitive2DSequence(rDisplayInfo);
350 // local up-to-date checks. New list different from local one?
351 if(!drawinglayer::primitive2d::arePrimitive2DSequencesEqual(mxPrimitive2DSequence, xNewPrimitiveSequence))
353 // has changed, copy content
354 const_cast< ViewObjectContact* >(this)->mxPrimitive2DSequence = xNewPrimitiveSequence;
356 // check for animated stuff
357 const_cast< ViewObjectContact* >(this)->checkForPrimitive2DAnimations();
359 // always update object range when PrimitiveSequence changes
360 const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D());
361 const_cast< ViewObjectContact* >(this)->maObjectRange =
362 drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(mxPrimitive2DSequence, rViewInformation2D);
365 // return current Primitive2DSequence
366 return mxPrimitive2DSequence;
369 bool ViewObjectContact::isPrimitiveVisible(const DisplayInfo& /*rDisplayInfo*/) const
371 // default: always visible
372 return true;
375 bool ViewObjectContact::isPrimitiveGhosted(const DisplayInfo& rDisplayInfo) const
377 // default: standard check
378 return (GetObjectContact().DoVisualizeEnteredGroup() && !GetObjectContact().isOutputToPrinter() && rDisplayInfo.IsGhostedDrawModeActive());
381 drawinglayer::primitive2d::Primitive2DSequence ViewObjectContact::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const
383 drawinglayer::primitive2d::Primitive2DSequence xRetval;
385 // check model-view visibility
386 if(isPrimitiveVisible(rDisplayInfo))
388 xRetval = getPrimitive2DSequence(rDisplayInfo);
390 if(xRetval.hasElements())
392 // get ranges
393 const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D());
394 const basegfx::B2DRange aObjectRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xRetval, rViewInformation2D));
395 const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport());
397 // check geometrical visibility
398 if(!aViewRange.isEmpty() && !aViewRange.overlaps(aObjectRange))
400 // not visible, release
401 xRetval.realloc(0);
406 return xRetval;
409 drawinglayer::primitive2d::Primitive2DSequence ViewObjectContact::getPrimitive2DSequenceSubHierarchy(DisplayInfo& rDisplayInfo) const
411 const sal_uInt32 nSubHierarchyCount(GetViewContact().GetObjectCount());
412 drawinglayer::primitive2d::Primitive2DSequence xSeqRetval;
414 for(sal_uInt32 a(0); a < nSubHierarchyCount; a++)
416 const ViewObjectContact& rCandidate(GetViewContact().GetViewContact(a).GetViewObjectContact(GetObjectContact()));
418 drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xSeqRetval, rCandidate.getPrimitive2DSequenceHierarchy(rDisplayInfo));
421 return xSeqRetval;
423 } // end of namespace contact
424 } // end of namespace sdr
426 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */