/* -*- 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/. * * This file incorporates work covered by the following license notice: * * 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 .
*/
// #i15222# // Due to the resource problems in Win95/98 with bitmap resources I // will change this handle bitmap providing class. Old version was splitting // and preparing all small handle bitmaps in device bitmap format, now this will // be done on the fly. Thus, there is only one big bitmap in memory. With // three source bitmaps, this will be 3 system bitmap resources instead of hundreds. // The price for that needs to be evaluated. Maybe we will need another change here // if this is too expensive. class SdrHdlBitmapSet
{ // the bitmap holding all information
BitmapEx maMarkersBitmap;
// the cropped Bitmaps for reusage
::std::vector< BitmapEx > maRealMarkers;
// change getting of bitmap to use the big resource bitmap const BitmapEx& SdrHdlBitmapSet::GetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd)
{ // fill in size and source position in maMarkersBitmap const sal_uInt16 nYPos(nInd * 11);
case BitmapMarkerKind::Anchor: // AnchorTR for SW case BitmapMarkerKind::AnchorTR:
{ return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 3, tools::Rectangle(Point(24, 67), Size(24, 24)));
}
// add AnchorPressed to be able to animate anchor control case BitmapMarkerKind::AnchorPressed: case BitmapMarkerKind::AnchorPressedTR:
{ return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 4, tools::Rectangle(Point(48, 67), Size(24, 24)));
}
}
}
switch(eKnd)
{ case BitmapMarkerKind::Rect_7x7: eRetval = BitmapMarkerKind::Rect_9x9; break; case BitmapMarkerKind::Rect_9x9: eRetval = BitmapMarkerKind::Rect_11x11; break; case BitmapMarkerKind::Rect_11x11: eRetval = BitmapMarkerKind::Rect_13x13; break;
case BitmapMarkerKind::Circ_7x7: eRetval = BitmapMarkerKind::Circ_9x9; break; case BitmapMarkerKind::Circ_9x9: eRetval = BitmapMarkerKind::Circ_11x11; break;
case BitmapMarkerKind::Customshape_7x7: eRetval = BitmapMarkerKind::Customshape_9x9; break; case BitmapMarkerKind::Customshape_9x9: eRetval = BitmapMarkerKind::Customshape_11x11; break; //case BitmapMarkerKind::Customshape_11x11: eRetval = ; break;
case BitmapMarkerKind::Elli_7x9: eRetval = BitmapMarkerKind::Elli_9x11; break;
case BitmapMarkerKind::Elli_9x7: eRetval = BitmapMarkerKind::Elli_11x9; break;
case BitmapMarkerKind::RectPlus_7x7: eRetval = BitmapMarkerKind::RectPlus_9x9; break; case BitmapMarkerKind::RectPlus_9x9: eRetval = BitmapMarkerKind::RectPlus_11x11; break;
// let anchor blink with its pressed state case BitmapMarkerKind::Anchor: eRetval = BitmapMarkerKind::AnchorPressed; break;
// same for AnchorTR case BitmapMarkerKind::AnchorTR: eRetval = BitmapMarkerKind::AnchorPressedTR; break; default: break;
}
return eRetval;
}
namespace
{
OUString appendMarkerName(BitmapMarkerKind eKindOfMarker)
{ switch(eKindOfMarker)
{ case BitmapMarkerKind::Rect_7x7: return u"rect7"_ustr; case BitmapMarkerKind::Rect_9x9: return u"rect9"_ustr; case BitmapMarkerKind::Rect_11x11: return u"rect11"_ustr; case BitmapMarkerKind::Rect_13x13: return u"rect13"_ustr; case BitmapMarkerKind::Circ_7x7: case BitmapMarkerKind::Customshape_7x7: return u"circ7"_ustr; case BitmapMarkerKind::Circ_9x9: case BitmapMarkerKind::Customshape_9x9: return u"circ9"_ustr; case BitmapMarkerKind::Circ_11x11: case BitmapMarkerKind::Customshape_11x11: return u"circ11"_ustr; case BitmapMarkerKind::Elli_7x9: return u"elli7x9"_ustr; case BitmapMarkerKind::Elli_9x11: return u"elli9x11"_ustr; case BitmapMarkerKind::Elli_9x7: return u"elli9x7"_ustr; case BitmapMarkerKind::Elli_11x9: return u"elli11x9"_ustr; case BitmapMarkerKind::RectPlus_7x7: return u"rectplus7"_ustr; case BitmapMarkerKind::RectPlus_9x9: return u"rectplus9"_ustr; case BitmapMarkerKind::RectPlus_11x11: return u"rectplus11"_ustr; case BitmapMarkerKind::Crosshair: return u"cross"_ustr; case BitmapMarkerKind::Anchor: case BitmapMarkerKind::AnchorTR: return u"anchor"_ustr; case BitmapMarkerKind::AnchorPressed: case BitmapMarkerKind::AnchorPressedTR: return u"anchor-pressed"_ustr; case BitmapMarkerKind::Glue: return u"glue-selected"_ustr; case BitmapMarkerKind::Glue_Deselected: return u"glue-unselected"_ustr; default: break;
} return OUString();
}
OUString appendMarkerColor(BitmapColorIndex eIndex)
{ switch(eIndex)
{ case BitmapColorIndex::LightGreen: return u"1"_ustr; case BitmapColorIndex::Cyan: return u"2"_ustr; case BitmapColorIndex::LightCyan: return u"3"_ustr; case BitmapColorIndex::Red: return u"4"_ustr; case BitmapColorIndex::LightRed: return u"5"_ustr; case BitmapColorIndex::Yellow: return u"6"_ustr; default: break;
} return OUString();
}
BitmapEx ImpGetBitmapEx(BitmapMarkerKind eKindOfMarker, BitmapColorIndex eIndex)
{ // use this code path only when we use HiDPI (for now) if (Application::GetDefaultDevice()->GetDPIScalePercentage() > 100)
{
OUString sMarkerName = appendMarkerName(eKindOfMarker); if (!sMarkerName.isEmpty())
{
OUString sMarkerPrefix(u"svx/res/marker-"_ustr);
BitmapEx aBitmapEx;
// support bigger sizes bool bForceBiggerSize(false);
if (m_pHdlList && m_pHdlList->GetHdlSize() > 3)
{ switch(eKindOfMarker)
{ case BitmapMarkerKind::Anchor: case BitmapMarkerKind::AnchorPressed: case BitmapMarkerKind::AnchorTR: case BitmapMarkerKind::AnchorPressedTR:
{ // #i121463# For anchor, do not simply make bigger because of HdlSize, // do it dependent of IsSelected() which Writer can set in drag mode if(IsSelected())
{
bForceBiggerSize = true;
} break;
} default:
{
bForceBiggerSize = true; break;
}
}
}
// This handle has the focus, visualize it if(IsFocusHdl() && m_pHdlList && m_pHdlList->GetFocusHdl() == this)
{ // create animated handle
BitmapMarkerKind eNextBigger = GetNextBigger(eKindOfMarker);
if(eNextBigger == eKindOfMarker)
{ // this may happen for the not supported getting-bigger types. // Choose an alternative here switch(eKindOfMarker)
{ case BitmapMarkerKind::Rect_13x13: eNextBigger = BitmapMarkerKind::Rect_11x11; break; case BitmapMarkerKind::Circ_11x11: eNextBigger = BitmapMarkerKind::Elli_11x9; break; case BitmapMarkerKind::Elli_9x11: eNextBigger = BitmapMarkerKind::Elli_11x9; break; case BitmapMarkerKind::Elli_11x9: eNextBigger = BitmapMarkerKind::Elli_9x11; break; case BitmapMarkerKind::RectPlus_11x11: eNextBigger = BitmapMarkerKind::Rect_13x13; break; case BitmapMarkerKind::Glue:
eNextBigger = BitmapMarkerKind::Crosshair; break; case BitmapMarkerKind::Crosshair: case BitmapMarkerKind::Glue_Deselected:
eNextBigger = BitmapMarkerKind::Glue; break; default: break;
}
}
// #i53216# Use system cursor blink time. Use the unsigned value. const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); const sal_uInt64 nBlinkTime(rStyleSettings.GetCursorBlinkTime());
if(eKindOfMarker == BitmapMarkerKind::Anchor || eKindOfMarker == BitmapMarkerKind::AnchorPressed)
{ // when anchor is used take upper left as reference point inside the handle
pRetval.reset(new sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime));
} elseif(eKindOfMarker == BitmapMarkerKind::AnchorTR || eKindOfMarker == BitmapMarkerKind::AnchorPressedTR)
{ // AnchorTR for SW, take top right as (0,0)
pRetval.reset(new sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime, static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Width() - 1), 0, static_cast<sal_uInt16>(aBmpEx2.GetSizePixel().Width() - 1), 0));
} else
{ // create centered handle as default
pRetval.reset(new sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime, static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Width() - 1) >> 1, static_cast<sal_uInt16>(aBmpEx1.GetSizePixel().Height() - 1) >> 1, static_cast<sal_uInt16>(aBmpEx2.GetSizePixel().Width() - 1) >> 1, static_cast<sal_uInt16>(aBmpEx2.GetSizePixel().Height() - 1) >> 1));
}
} else
{ // create normal handle: use ImpGetBitmapEx(...) now
BitmapEx aBmpEx = ImpGetBitmapEx(eKindOfMarker, eColIndex);
// When the image with handles is not found, the bitmap returned is // empty. This is a problem when we use LibreOffice as a library // (through LOKit - for example on Android) even when we don't show // the handles, because the hit test would always return false. // // This HACK replaces the empty bitmap with a black 13x13 bitmap handle // so that the hit test works for this case. if (aBmpEx.IsEmpty())
{
aBmpEx = BitmapEx(Size(13, 13), vcl::PixelFormat::N24_BPP);
aBmpEx.Erase(COL_BLACK);
}
if(eKindOfMarker == BitmapMarkerKind::Anchor || eKindOfMarker == BitmapMarkerKind::AnchorPressed)
{ // upper left as reference point inside the handle for AnchorPressed, too
pRetval.reset(new sdr::overlay::OverlayBitmapEx(rPos, aBmpEx));
} elseif(eKindOfMarker == BitmapMarkerKind::AnchorTR || eKindOfMarker == BitmapMarkerKind::AnchorPressedTR)
{ // AnchorTR for SW, take top right as (0,0)
pRetval.reset(new sdr::overlay::OverlayBitmapEx(rPos, aBmpEx, static_cast<sal_uInt16>(aBmpEx.GetSizePixel().Width() - 1), 0));
} else
{
sal_uInt16 nCenX(static_cast<sal_uInt16>(aBmpEx.GetSizePixel().Width() - 1) >> 1);
sal_uInt16 nCenY(static_cast<sal_uInt16>(aBmpEx.GetSizePixel().Height() - 1) >> 1);
PointerStyle SdrHdl::GetPointer() const
{
PointerStyle ePtr=PointerStyle::Move; constbool bSize=m_eKind>=SdrHdlKind::UpperLeft && m_eKind<=SdrHdlKind::LowerRight; constbool bRot=m_pHdlList!=nullptr && m_pHdlList->IsRotateShear(); constbool bDis=m_pHdlList!=nullptr && m_pHdlList->IsDistortShear(); if (bSize && m_pHdlList!=nullptr && (bRot || bDis)) { switch (m_eKind) { case SdrHdlKind::UpperLeft: case SdrHdlKind::UpperRight: case SdrHdlKind::LowerLeft: case SdrHdlKind::LowerRight: ePtr=bRot ? PointerStyle::Rotate : PointerStyle::RefHand; break; case SdrHdlKind::Left : case SdrHdlKind::Right: ePtr=PointerStyle::VShear; break; case SdrHdlKind::Upper: case SdrHdlKind::Lower: ePtr=PointerStyle::HShear; break; default: break;
}
} else { // When resizing rotated rectangles, rotate the mouse cursor slightly, too if (bSize && m_nRotationAngle!=0_deg100) {
Degree100 nHdlAngle(0); switch (m_eKind) { case SdrHdlKind::LowerRight: nHdlAngle=31500_deg100; break; case SdrHdlKind::Lower: nHdlAngle=27000_deg100; break; case SdrHdlKind::LowerLeft: nHdlAngle=22500_deg100; break; case SdrHdlKind::Left : nHdlAngle=18000_deg100; break; case SdrHdlKind::UpperLeft: nHdlAngle=13500_deg100; break; case SdrHdlKind::Upper: nHdlAngle=9000_deg100; break; case SdrHdlKind::UpperRight: nHdlAngle=4500_deg100; break; case SdrHdlKind::Right: nHdlAngle=0_deg100; break; default: break;
} // a little bit more (for rounding)
nHdlAngle = NormAngle36000(nHdlAngle + m_nRotationAngle + 2249_deg100);
nHdlAngle/=4500_deg100; switch (static_cast<sal_uInt8>(nHdlAngle.get())) { case 0: ePtr=PointerStyle::ESize; break; case 1: ePtr=PointerStyle::NESize; break; case 2: ePtr=PointerStyle::NSize; break; case 3: ePtr=PointerStyle::NWSize; break; case 4: ePtr=PointerStyle::WSize; break; case 5: ePtr=PointerStyle::SWSize; break; case 6: ePtr=PointerStyle::SSize; break; case 7: ePtr=PointerStyle::SESize; break;
} // switch
} else { switch (m_eKind) { case SdrHdlKind::UpperLeft: ePtr=PointerStyle::NWSize; break; case SdrHdlKind::Upper: ePtr=PointerStyle::NSize; break; case SdrHdlKind::UpperRight: ePtr=PointerStyle::NESize; break; case SdrHdlKind::Left : ePtr=PointerStyle::WSize; break; case SdrHdlKind::Right: ePtr=PointerStyle::ESize; break; case SdrHdlKind::LowerLeft: ePtr=PointerStyle::SWSize; break; case SdrHdlKind::Lower: ePtr=PointerStyle::SSize; break; case SdrHdlKind::LowerRight: ePtr=PointerStyle::SESize; break; case SdrHdlKind::Poly : ePtr=PointerStyle::MovePoint; break; case SdrHdlKind::Circle : ePtr=PointerStyle::Hand; break; case SdrHdlKind::Ref1 : ePtr=PointerStyle::RefHand; break; case SdrHdlKind::Ref2 : ePtr=PointerStyle::RefHand; break; case SdrHdlKind::BezierWeight : ePtr=PointerStyle::MoveBezierWeight; break; case SdrHdlKind::Glue : ePtr=PointerStyle::MovePoint; break; case SdrHdlKind::CustomShape1 : ePtr=PointerStyle::RefHand; break; default: break;
}
}
} return ePtr;
}
bool SdrHdl::IsFocusHdl() const
{ switch(m_eKind)
{ case SdrHdlKind::UpperLeft: case SdrHdlKind::Upper: case SdrHdlKind::UpperRight: case SdrHdlKind::Left: case SdrHdlKind::Right: case SdrHdlKind::LowerLeft: case SdrHdlKind::Lower: case SdrHdlKind::LowerRight:
{ // if it's an activated TextEdit, it's moved to extended points return !m_pHdlList || !m_pHdlList->IsMoveOutside();
}
case SdrHdlKind::Move: // handle to move object case SdrHdlKind::Poly: // selected point of polygon or curve case SdrHdlKind::BezierWeight: // weight at a curve case SdrHdlKind::Circle: // angle of circle segments, corner radius of rectangles case SdrHdlKind::Ref1: // reference point 1, e. g. center of rotation case SdrHdlKind::Ref2: // reference point 2, e. g. endpoint of reflection axis case SdrHdlKind::Glue: // gluepoint
// for SJ and the CustomShapeHandles: case SdrHdlKind::CustomShape1:
PointerStyle ImpMeasureHdl::GetPointer() const
{ switch (m_nObjHdlNum)
{ case 0: case 1: return PointerStyle::Hand; case 2: case 3: return PointerStyle::MovePoint; case 4: case 5: return SdrHdl::GetPointer(); // will then be rotated appropriately
} // switch return PointerStyle::NotAllowed;
}
std::unique_ptr<sdr::overlay::OverlayRectangle> pNewOverlayObject(new sdr::overlay::OverlayRectangle(
aTopLeft,
aBottomRight,
aHilightColor,
fTransparence,
3.0,
3.0,
-toRadians(m_nRotationAngle), true)); // allow animation; the Handle is not shown at text edit time
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.