1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <tools/debug.hxx>
21 #include <tools/poly.hxx>
22 #include <vcl/event.hxx>
23 #include <vcl/settings.hxx>
24 #include <vcl/vcllayout.hxx>
25 #include <vcl/virdev.hxx>
26 #include <vcl/ptrstyle.hxx>
27 #include <sal/log.hxx>
29 #include <svtools/ruler.hxx>
30 #include <svtools/svtresid.hxx>
31 #include <svtools/strings.hrc>
32 #include <svtools/colorcfg.hxx>
33 #include "accessibleruler.hxx"
39 using namespace ::com::sun::star
;
40 using namespace ::com::sun::star::uno
;
41 using namespace ::com::sun::star::lang
;
42 using namespace ::com::sun::star::accessibility
;
45 #define RULER_RESIZE_OFF 4
46 #define RULER_MIN_SIZE 3
48 #define RULER_VAR_SIZE 8
50 #define RULER_UPDATE_LINES 0x01
52 #define RULER_CLIP 150
54 #define RULER_UNIT_MM 0
55 #define RULER_UNIT_CM 1
56 #define RULER_UNIT_M 2
57 #define RULER_UNIT_KM 3
58 #define RULER_UNIT_INCH 4
59 #define RULER_UNIT_FOOT 5
60 #define RULER_UNIT_MILE 6
61 #define RULER_UNIT_POINT 7
62 #define RULER_UNIT_PICA 8
63 #define RULER_UNIT_CHAR 9
64 #define RULER_UNIT_LINE 10
65 #define RULER_UNIT_COUNT 11
70 * Pre-calculates glyph items for rText on rRenderContext. Subsequent calls
71 * avoid the calculation and just return a pointer to rTextGlyphs.
73 SalLayoutGlyphs
* lcl_GetRulerTextGlyphs(const vcl::RenderContext
& rRenderContext
, const OUString
& rText
,
74 SalLayoutGlyphs
& rTextGlyphs
)
76 if (rTextGlyphs
.IsValid())
77 // Use pre-calculated result.
80 // Calculate glyph items.
82 std::unique_ptr
<SalLayout
> pLayout
= rRenderContext
.ImplLayout(
83 rText
, 0, rText
.getLength(), Point(0, 0), 0, nullptr, SalLayoutFlags::GlyphItemsOnly
);
87 const SalLayoutGlyphs
* pGlyphs
= pLayout
->GetGlyphs();
91 // Remember the calculation result.
92 rTextGlyphs
= *pGlyphs
;
103 vector
<RulerLine
> pLines
;
104 vector
<RulerBorder
> pBorders
;
105 vector
<RulerIndent
> pIndents
;
106 vector
<RulerTab
> pTabs
;
108 tools::Long nNullVirOff
;
109 tools::Long nRulVirOff
;
110 tools::Long nRulWidth
;
111 tools::Long nPageOff
;
112 tools::Long nPageWidth
;
113 tools::Long nNullOff
;
114 tools::Long nMargin1
;
115 tools::Long nMargin2
;
116 // In this context, "frame margin" means paragraph margins (indents)
117 tools::Long nLeftFrameMargin
;
118 tools::Long nRightFrameMargin
;
119 RulerMarginStyle nMargin1Style
;
120 RulerMarginStyle nMargin2Style
;
128 ImplRulerData::ImplRulerData() :
137 nLeftFrameMargin (0),
138 nRightFrameMargin (0),
139 nMargin1Style (RulerMarginStyle::NONE
),
140 nMargin2Style (RulerMarginStyle::NONE
),
141 bAutoPageWidth (true), // Page width == EditWin width
146 const RulerUnitData aImplRulerUnitTab
[RULER_UNIT_COUNT
] =
148 { MapUnit::Map100thMM
, 100, 25.0, 25.0, 50.0, 100.0, " mm" }, // MM
149 { MapUnit::Map100thMM
, 1000, 100.0, 500.0, 1000.0, 1000.0, " cm" }, // CM
150 { MapUnit::MapMM
, 1000, 10.0, 250.0, 500.0, 1000.0, " m" }, // M
151 { MapUnit::MapCM
, 100000, 12500.0, 25000.0, 50000.0, 100000.0, " km" }, // KM
152 { MapUnit::Map1000thInch
, 1000, 62.5, 125.0, 500.0, 1000.0, "\"" }, // INCH
153 { MapUnit::Map100thInch
, 1200, 120.0, 120.0, 600.0, 1200.0, "'" }, // FOOT
154 { MapUnit::Map10thInch
, 633600, 63360.0, 63360.0, 316800.0, 633600.0, " miles" }, // MILE
155 { MapUnit::MapPoint
, 1, 12.0, 12.0, 12.0, 36.0, " pt" }, // POINT
156 { MapUnit::Map100thMM
, 423, 423.0, 423.0, 423.0, 846.0, " pc" }, // PICA
157 { MapUnit::Map100thMM
, 371, 371.0, 371.0, 371.0, 743.0, " ch" }, // CHAR
158 { MapUnit::Map100thMM
, 551, 551.0, 551.0, 551.0, 1102.0, " li" } // LINE
161 static RulerTabData ruler_tab
=
163 0, // DPIScaleFactor to be set
164 7, // ruler_tab_width
165 6, // ruler_tab_height
166 2, // ruler_tab_height2
167 2, // ruler_tab_width2
168 8, // ruler_tab_cwidth
169 4, // ruler_tab_cwidth2
170 4, // ruler_tab_cwidth3
171 2, // ruler_tab_cwidth4
172 4, // ruler_tab_dheight
173 1, // ruler_tab_dheight2
174 5, // ruler_tab_dwidth
175 3, // ruler_tab_dwidth2
176 3, // ruler_tab_dwidth3
177 1, // ruler_tab_dwidth4
178 5 // ruler_tab_textoff
181 void Ruler::ImplInit( WinBits nWinBits
)
183 // Set default WinBits
184 if ( !(nWinBits
& WB_VERT
) )
188 // RTL: no UI mirroring for horizontal rulers, because
189 // the document is also not mirrored
193 // Initialize variables
194 mnWinStyle
= nWinBits
; // Window-Style
195 mnBorderOff
= 0; // Border-Offset
196 mnWinOff
= 0; // EditWinOffset
197 mnWinWidth
= 0; // EditWinWidth
198 mnWidth
= 0; // Window width
199 mnHeight
= 0; // Window height
200 mnVirOff
= 0; // Offset of VirtualDevice from top-left corner
201 mnVirWidth
= 0; // width or height from VirtualDevice
202 mnVirHeight
= 0; // height of width from VirtualDevice
203 mnDragPos
= 0; // Drag-Position (Null point)
204 mnDragAryPos
= 0; // Drag-Array-Index
205 mnDragSize
= RulerDragSize::Move
; // Did size change at dragging
206 mnDragModifier
= 0; // Modifier key at dragging
207 mnExtraStyle
= 0; // Style of Extra field
210 mbCalc
= true; // Should recalculate page width
211 mbFormat
= true; // Should redraw
212 mbDrag
= false; // Currently at dragging
213 mbDragDelete
= false; // Has mouse left the dragging area
214 mbDragCanceled
= false; // Dragging cancelled?
215 mbAutoWinWidth
= true; // EditWinWidth == RulerWidth
216 mbActive
= true; // Is ruler active
217 mnUpdateFlags
= 0; // What needs to be updated
218 mpData
= mpSaveData
.get(); // Pointer to normal data
219 meExtraType
= RulerExtra::DontKnow
; // What is in extra field
220 meDragType
= RulerType::DontKnow
; // Which element is dragged
223 mnUnitIndex
= RULER_UNIT_CM
;
224 meUnit
= FieldUnit::CM
;
225 maZoom
= Fraction( 1, 1 );
227 // Recalculate border widths
228 if ( nWinBits
& WB_BORDER
)
234 ImplInitSettings( true, true, true );
236 // Setup the default size
237 tools::Rectangle aRect
;
238 GetTextBoundRect( aRect
, "0123456789" );
239 tools::Long nDefHeight
= aRect
.GetHeight() + RULER_OFF
* 2 + ruler_tab
.textoff
* 2 + mnBorderWidth
;
242 if ( nWinBits
& WB_HORZ
)
243 aDefSize
.setHeight( nDefHeight
);
245 aDefSize
.setWidth( nDefHeight
);
246 SetOutputSizePixel( aDefSize
);
247 SetType(WindowType::RULER
);
250 Ruler::Ruler( vcl::Window
* pParent
, WinBits nWinStyle
) :
251 Window( pParent
, nWinStyle
& WB_3DLOOK
),
252 maVirDev( VclPtr
<VirtualDevice
>::Create(*this) ),
253 maMapMode( MapUnit::Map100thMM
),
254 mpSaveData(new ImplRulerData
),
256 mpDragData(new ImplRulerData
)
258 // Check to see if the ruler constructor has
259 // already been called before otherwise
260 // we end up with over-scaled elements
261 if (ruler_tab
.DPIScaleFactor
== 0)
263 ruler_tab
.DPIScaleFactor
= GetDPIScaleFactor();
264 ruler_tab
.width
*= ruler_tab
.DPIScaleFactor
;
265 ruler_tab
.height
*= ruler_tab
.DPIScaleFactor
;
266 ruler_tab
.height2
*= ruler_tab
.DPIScaleFactor
;
267 ruler_tab
.width2
*= ruler_tab
.DPIScaleFactor
;
268 ruler_tab
.cwidth
*= ruler_tab
.DPIScaleFactor
;
269 ruler_tab
.cwidth2
*= ruler_tab
.DPIScaleFactor
;
270 ruler_tab
.cwidth3
*= ruler_tab
.DPIScaleFactor
;
271 ruler_tab
.cwidth4
*= ruler_tab
.DPIScaleFactor
;
272 ruler_tab
.dheight
*= ruler_tab
.DPIScaleFactor
;
273 ruler_tab
.dheight2
*= ruler_tab
.DPIScaleFactor
;
274 ruler_tab
.dwidth
*= ruler_tab
.DPIScaleFactor
;
275 ruler_tab
.dwidth2
*= ruler_tab
.DPIScaleFactor
;
276 ruler_tab
.dwidth3
*= ruler_tab
.DPIScaleFactor
;
277 ruler_tab
.dwidth4
*= ruler_tab
.DPIScaleFactor
;
278 ruler_tab
.textoff
*= ruler_tab
.DPIScaleFactor
;
282 ImplInit( nWinStyle
);
290 void Ruler::dispose()
294 mxAccContext
.clear();
298 void Ruler::ImplVDrawLine(vcl::RenderContext
& rRenderContext
, tools::Long nX1
, tools::Long nY1
, tools::Long nX2
, tools::Long nY2
)
300 if ( nX1
< -RULER_CLIP
)
303 if ( nX2
< -RULER_CLIP
)
306 tools::Long nClip
= mnVirWidth
+ RULER_CLIP
;
314 if ( mnWinStyle
& WB_HORZ
)
315 rRenderContext
.DrawLine( Point( nX1
, nY1
), Point( nX2
, nY2
) );
317 rRenderContext
.DrawLine( Point( nY1
, nX1
), Point( nY2
, nX2
) );
320 void Ruler::ImplVDrawRect(vcl::RenderContext
& rRenderContext
, tools::Long nX1
, tools::Long nY1
, tools::Long nX2
, tools::Long nY2
)
322 if ( nX1
< -RULER_CLIP
)
325 if ( nX2
< -RULER_CLIP
)
328 tools::Long nClip
= mnVirWidth
+ RULER_CLIP
;
336 if ( mnWinStyle
& WB_HORZ
)
337 rRenderContext
.DrawRect(tools::Rectangle(nX1
, nY1
, nX2
, nY2
));
339 rRenderContext
.DrawRect(tools::Rectangle(nY1
, nX1
, nY2
, nX2
));
342 void Ruler::ImplVDrawText(vcl::RenderContext
& rRenderContext
, tools::Long nX
, tools::Long nY
, const OUString
& rText
, tools::Long nMin
, tools::Long nMax
)
344 tools::Rectangle aRect
;
345 SalLayoutGlyphs
* pTextLayout
346 = lcl_GetRulerTextGlyphs(rRenderContext
, rText
, maTextGlyphs
[rText
]);
347 rRenderContext
.GetTextBoundRect(aRect
, rText
, 0, 0, -1, 0, nullptr, pTextLayout
);
349 tools::Long nShiftX
= ( aRect
.GetWidth() / 2 ) + aRect
.Left();
350 tools::Long nShiftY
= ( aRect
.GetHeight() / 2 ) + aRect
.Top();
352 if ( (nX
> -RULER_CLIP
) && (nX
< mnVirWidth
+ RULER_CLIP
) && ( nX
< nMax
- nShiftX
) && ( nX
> nMin
+ nShiftX
) )
354 if ( mnWinStyle
& WB_HORZ
)
355 rRenderContext
.DrawText(Point(nX
- nShiftX
, nY
- nShiftY
), rText
, 0, -1, nullptr,
356 nullptr, pTextLayout
);
358 rRenderContext
.DrawText(Point(nY
- nShiftX
, nX
- nShiftY
), rText
, 0, -1, nullptr,
359 nullptr, pTextLayout
);
363 void Ruler::ImplInvertLines(vcl::RenderContext
& rRenderContext
)
366 if (mpData
->pLines
.empty() || !mbActive
|| mbDrag
|| mbFormat
|| (mnUpdateFlags
& RULER_UPDATE_LINES
) )
369 tools::Long nNullWinOff
= mpData
->nNullVirOff
+ mnVirOff
;
370 tools::Long nRulX1
= mpData
->nRulVirOff
+ mnVirOff
;
371 tools::Long nRulX2
= nRulX1
+ mpData
->nRulWidth
;
372 tools::Long nY
= (RULER_OFF
* 2) + mnVirHeight
- 1;
374 // Calculate rectangle
375 tools::Rectangle aRect
;
376 if (mnWinStyle
& WB_HORZ
)
377 aRect
.SetBottom( nY
);
379 aRect
.SetRight( nY
);
382 for (const RulerLine
& rLine
: mpData
->pLines
)
384 const tools::Long n
= rLine
.nPos
+ nNullWinOff
;
385 if ((n
>= nRulX1
) && (n
< nRulX2
))
387 if (mnWinStyle
& WB_HORZ
)
395 aRect
.SetBottom( n
);
397 tools::Rectangle aTempRect
= aRect
;
399 if (mnWinStyle
& WB_HORZ
)
400 aTempRect
.SetBottom( RULER_OFF
- 1 );
402 aTempRect
.SetRight( RULER_OFF
- 1 );
404 rRenderContext
.Erase(aTempRect
);
406 if (mnWinStyle
& WB_HORZ
)
408 aTempRect
.SetBottom( aRect
.Bottom() );
409 aTempRect
.SetTop( aTempRect
.Bottom() - RULER_OFF
+ 1 );
413 aTempRect
.SetRight( aRect
.Right() );
414 aTempRect
.SetLeft( aTempRect
.Right() - RULER_OFF
+ 1 );
416 rRenderContext
.Erase(aTempRect
);
423 void Ruler::ImplDrawTicks(vcl::RenderContext
& rRenderContext
, tools::Long nMin
, tools::Long nMax
, tools::Long nStart
, tools::Long nTop
, tools::Long nBottom
)
425 double nCenter
= nTop
+ ((nBottom
- nTop
) / 2);
427 tools::Long nTickLength3
= (nBottom
- nTop
) * 0.5;
428 tools::Long nTickLength2
= nTickLength3
* 0.66;
429 tools::Long nTickLength1
= nTickLength2
* 0.66;
431 tools::Long nScale
= ruler_tab
.DPIScaleFactor
;
432 tools::Long DPIOffset
= nScale
- 1;
434 double nTick4
= aImplRulerUnitTab
[mnUnitIndex
].nTick4
;
436 double nTickCount
= aImplRulerUnitTab
[mnUnitIndex
].nTick1
/ nScale
;
437 double nTickUnit
= 0;
438 tools::Long nTickWidth
;
439 bool bNoTicks
= false;
441 Size aPixSize
= rRenderContext
.LogicToPixel(Size(nTick4
, nTick4
), maMapMode
);
443 if (mnUnitIndex
== RULER_UNIT_CHAR
)
445 if (mnCharWidth
== 0)
447 nTick4
= mnCharWidth
* 2;
448 nTick2
= mnCharWidth
;
449 nTickCount
= mnCharWidth
;
450 nTickUnit
= mnCharWidth
;
452 else if (mnUnitIndex
== RULER_UNIT_LINE
)
454 if (mnLineHeight
== 0)
456 nTick4
= mnLineHeight
* 2;
457 nTick2
= mnLineHeight
;
458 nTickUnit
= mnLineHeight
;
459 nTickCount
= mnLineHeight
;
462 if (mnWinStyle
& WB_HORZ
)
464 nTickWidth
= aPixSize
.Width();
468 vcl::Font aFont
= rRenderContext
.GetFont();
469 if (mnWinStyle
& WB_RIGHT_ALIGNED
)
470 aFont
.SetOrientation(Degree10(2700));
472 aFont
.SetOrientation(Degree10(900));
473 rRenderContext
.SetFont(aFont
);
474 nTickWidth
= aPixSize
.Height();
477 tools::Long nMaxWidth
= rRenderContext
.PixelToLogic(Size(mpData
->nPageWidth
, 0), maMapMode
).Width();
479 nMaxWidth
= -nMaxWidth
;
481 if ((mnUnitIndex
== RULER_UNIT_CHAR
) || (mnUnitIndex
== RULER_UNIT_LINE
))
482 nMaxWidth
/= nTickUnit
;
484 nMaxWidth
/= aImplRulerUnitTab
[mnUnitIndex
].nTickUnit
;
486 OUString aNumString
= OUString::number(nMaxWidth
);
487 tools::Long nTxtWidth
= rRenderContext
.GetTextWidth( aNumString
);
488 const tools::Long nTextOff
= 4;
490 // Determine the number divider for ruler drawn numbers - means which numbers
491 // should be shown on the ruler and which should be skipped because the ruler
492 // is not big enough to draw them
493 if (nTickWidth
< nTxtWidth
+ nTextOff
)
495 // Calculate the scale of the ruler
496 tools::Long nMulti
= 1;
497 tools::Long nOrgTick4
= nTick4
;
499 while (nTickWidth
< nTxtWidth
+ nTextOff
)
501 tools::Long nOldMulti
= nMulti
;
504 else if (nMulti
< 10)
506 else if (nMulti
< 100)
508 else if (nMulti
< 1000)
513 // Overflow - in this case don't draw ticks and exit
514 if (nMulti
< nOldMulti
)
520 nTick4
= nOrgTick4
* nMulti
;
521 aPixSize
= rRenderContext
.LogicToPixel(Size(nTick4
, nTick4
), maMapMode
);
522 if (mnWinStyle
& WB_HORZ
)
523 nTickWidth
= aPixSize
.Width();
525 nTickWidth
= aPixSize
.Height();
531 rRenderContext
.SetLineColor(rRenderContext
.GetSettings().GetStyleSettings().GetShadowColor());
541 if ((mnUnitIndex
!= RULER_UNIT_CHAR
) && (mnUnitIndex
!= RULER_UNIT_LINE
))
543 nTick2
= aImplRulerUnitTab
[mnUnitIndex
].nTick2
;
544 nTick3
= aImplRulerUnitTab
[mnUnitIndex
].nTick3
;
549 nTickGapSize
= rRenderContext
.LogicToPixel(Size(nTickCount
, nTickCount
), maMapMode
);
550 tools::Long nTickGap1
= mnWinStyle
& WB_HORZ
? nTickGapSize
.Width() : nTickGapSize
.Height();
551 nTickGapSize
= rRenderContext
.LogicToPixel(Size(nTick2
, nTick2
), maMapMode
);
552 tools::Long nTickGap2
= mnWinStyle
& WB_HORZ
? nTickGapSize
.Width() : nTickGapSize
.Height();
553 nTickGapSize
= rRenderContext
.LogicToPixel(Size(nTick3
, nTick3
), maMapMode
);
554 tools::Long nTickGap3
= mnWinStyle
& WB_HORZ
? nTickGapSize
.Width() : nTickGapSize
.Height();
556 while (((nStart
- n
) >= nMin
) || ((nStart
+ n
) <= nMax
))
563 // 0 is only painted when Margin1 is not equal to zero
564 if ((mpData
->nMargin1Style
& RulerMarginStyle::Invisible
) || (mpData
->nMargin1
!= 0))
567 ImplVDrawText(rRenderContext
, nStart
, nCenter
, aNumString
);
573 aPixSize
= rRenderContext
.LogicToPixel(Size(nTick
, nTick
), maMapMode
);
575 if (mnWinStyle
& WB_HORZ
)
576 n
= aPixSize
.Width();
578 n
= aPixSize
.Height();
580 // Tick4 - Output (Text)
581 double aStep
= nTick
/ nTick4
;
582 double aRest
= std::abs(aStep
- std::floor(aStep
));
583 double nAcceptanceDelta
= 0.0001;
585 if (aRest
< nAcceptanceDelta
)
587 if ((mnUnitIndex
== RULER_UNIT_CHAR
) || (mnUnitIndex
== RULER_UNIT_LINE
))
588 aNumString
= OUString::number(nTick
/ nTickUnit
);
590 aNumString
= OUString::number(nTick
/ aImplRulerUnitTab
[mnUnitIndex
].nTickUnit
);
592 tools::Long nHorizontalLocation
= nStart
+ n
;
593 ImplVDrawText(rRenderContext
, nHorizontalLocation
, nCenter
, aNumString
, nMin
, nMax
);
595 if (nMin
< nHorizontalLocation
&& nHorizontalLocation
< nMax
)
597 ImplVDrawRect(rRenderContext
, nHorizontalLocation
, nBottom
- 1 * nScale
, nHorizontalLocation
+ DPIOffset
, nBottom
);
598 ImplVDrawRect(rRenderContext
, nHorizontalLocation
, nTop
, nHorizontalLocation
+ DPIOffset
, nTop
+ 1 * nScale
);
601 nHorizontalLocation
= nStart
- n
;
602 ImplVDrawText(rRenderContext
, nHorizontalLocation
, nCenter
, aNumString
, nMin
, nMax
);
604 if (nMin
< nHorizontalLocation
&& nHorizontalLocation
< nMax
)
606 ImplVDrawRect(rRenderContext
, nHorizontalLocation
, nBottom
,
607 nHorizontalLocation
+ DPIOffset
, nBottom
- 1 * nScale
);
608 ImplVDrawRect(rRenderContext
, nHorizontalLocation
, nTop
,
609 nHorizontalLocation
+ DPIOffset
, nTop
+ 1 * nScale
);
612 // Tick/Tick2 - Output (Strokes)
615 tools::Long nTickLength
= nTickLength1
;
617 aStep
= (nTick
/ nTick2
);
618 aRest
= std::abs(aStep
- std::floor(aStep
));
619 if (aRest
< nAcceptanceDelta
)
620 nTickLength
= nTickLength2
;
622 aStep
= (nTick
/ nTick3
);
623 aRest
= std::abs(aStep
- std::floor(aStep
));
624 if (aRest
< nAcceptanceDelta
)
625 nTickLength
= nTickLength3
;
627 if ((nTickLength
== nTickLength1
&& nTickGap1
> 6) ||
628 (nTickLength
== nTickLength2
&& nTickGap2
> 6) ||
629 (nTickLength
== nTickLength3
&& nTickGap3
> 6))
631 tools::Long nT1
= nCenter
- (nTickLength
/ 2.0);
632 tools::Long nT2
= nT1
+ nTickLength
- 1;
638 ImplVDrawRect(rRenderContext
, nT
, nT1
, nT
+ DPIOffset
, nT2
);
641 ImplVDrawRect(rRenderContext
, nT
, nT1
, nT
+ DPIOffset
, nT2
);
649 void Ruler::ImplDrawBorders(vcl::RenderContext
& rRenderContext
, tools::Long nMin
, tools::Long nMax
, tools::Long nVirTop
, tools::Long nVirBottom
)
651 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
658 for (std::vector
<RulerBorder
>::size_type i
= 0; i
< mpData
->pBorders
.size(); i
++)
660 if (mpData
->pBorders
[i
].nStyle
& RulerBorderStyle::Invisible
)
663 n1
= mpData
->pBorders
[i
].nPos
+ mpData
->nNullVirOff
;
664 n2
= n1
+ mpData
->pBorders
[i
].nWidth
;
666 if (((n1
>= nMin
) && (n1
<= nMax
)) || ((n2
>= nMin
) && (n2
<= nMax
)))
670 rRenderContext
.SetLineColor();
671 rRenderContext
.SetFillColor(rStyleSettings
.GetFaceColor());
672 ImplVDrawRect(rRenderContext
, n1
, nVirTop
, n2
, nVirBottom
);
674 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
675 ImplVDrawLine(rRenderContext
, n1
+ 1, nVirTop
, n1
+ 1, nVirBottom
);
676 ImplVDrawLine(rRenderContext
, n1
, nVirTop
, n2
, nVirTop
);
678 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
679 ImplVDrawLine(rRenderContext
, n1
, nVirTop
, n1
, nVirBottom
);
680 ImplVDrawLine(rRenderContext
, n1
, nVirBottom
, n2
, nVirBottom
);
681 ImplVDrawLine(rRenderContext
, n2
- 1, nVirTop
, n2
- 1, nVirBottom
);
683 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
684 ImplVDrawLine(rRenderContext
, n2
, nVirTop
, n2
, nVirBottom
);
686 if (mpData
->pBorders
[i
].nStyle
& RulerBorderStyle::Variable
)
688 if (n2
- n1
> RULER_VAR_SIZE
+ 4)
690 nTemp1
= n1
+ (((n2
- n1
+ 1) - RULER_VAR_SIZE
) / 2);
691 nTemp2
= nVirTop
+ (((nVirBottom
- nVirTop
+ 1) - RULER_VAR_SIZE
) / 2);
692 tools::Long nTemp3
= nTemp1
+ RULER_VAR_SIZE
- 1;
693 tools::Long nTemp4
= nTemp2
+ RULER_VAR_SIZE
- 1;
694 tools::Long nTempY
= nTemp2
;
696 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
697 while (nTempY
<= nTemp4
)
699 ImplVDrawLine(rRenderContext
, nTemp1
, nTempY
, nTemp3
, nTempY
);
704 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
705 while (nTempY
<= nTemp4
)
707 ImplVDrawLine(rRenderContext
, nTemp1
, nTempY
, nTemp3
, nTempY
);
713 if (mpData
->pBorders
[i
].nStyle
& RulerBorderStyle::Sizeable
)
715 if (n2
- n1
> RULER_VAR_SIZE
+ 10)
717 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
718 ImplVDrawLine(rRenderContext
, n1
+ 4, nVirTop
+ 3, n1
+ 4, nVirBottom
- 3);
719 ImplVDrawLine(rRenderContext
, n2
- 5, nVirTop
+ 3, n2
- 5, nVirBottom
- 3);
720 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
721 ImplVDrawLine(rRenderContext
, n1
+ 5, nVirTop
+ 3, n1
+ 5, nVirBottom
- 3);
722 ImplVDrawLine(rRenderContext
, n2
- 4, nVirTop
+ 3, n2
- 4, nVirBottom
- 3);
728 n
= n1
+ ((n2
- n1
) / 2);
729 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
731 ImplVDrawLine(rRenderContext
, n
- 1, nVirTop
, n
- 1, nVirBottom
);
732 ImplVDrawLine(rRenderContext
, n
+ 1, nVirTop
, n
+ 1, nVirBottom
);
733 rRenderContext
.SetLineColor();
734 rRenderContext
.SetFillColor(rStyleSettings
.GetWindowColor());
735 ImplVDrawRect(rRenderContext
, n
, nVirTop
, n
, nVirBottom
);
741 void Ruler::ImplDrawIndent(vcl::RenderContext
& rRenderContext
, const tools::Polygon
& rPoly
, bool bIsHit
)
743 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
745 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
746 rRenderContext
.SetFillColor(bIsHit
? rStyleSettings
.GetDarkShadowColor() : rStyleSettings
.GetWorkspaceColor());
747 tools::Polygon
aPolygon(rPoly
);
748 aPolygon
.Optimize(PolyOptimizeFlags::CLOSE
);
749 rRenderContext
.DrawPolygon(aPolygon
);
752 void Ruler::ImplDrawIndents(vcl::RenderContext
& rRenderContext
, tools::Long nMin
, tools::Long nMax
, tools::Long nVirTop
, tools::Long nVirBottom
)
755 tools::Long nIndentHeight
= (mnVirHeight
/ 2) - 1;
756 tools::Long nIndentWidth2
= nIndentHeight
-3;
758 tools::Polygon
aPoly(5);
760 for (std::vector
<RulerIndent
>::size_type j
= 0; j
< mpData
->pIndents
.size(); j
++)
762 if (mpData
->pIndents
[j
].bInvisible
)
765 RulerIndentStyle nIndentStyle
= mpData
->pIndents
[j
].nStyle
;
767 n
= mpData
->pIndents
[j
].nPos
+mpData
->nNullVirOff
;
769 if ((n
>= nMin
) && (n
<= nMax
))
771 if (nIndentStyle
== RulerIndentStyle::Bottom
)
773 aPoly
.SetPoint(Point(n
+ 0, nVirBottom
- nIndentHeight
), 0);
774 aPoly
.SetPoint(Point(n
- nIndentWidth2
, nVirBottom
- 3), 1);
775 aPoly
.SetPoint(Point(n
- nIndentWidth2
, nVirBottom
), 2);
776 aPoly
.SetPoint(Point(n
+ nIndentWidth2
, nVirBottom
), 3);
777 aPoly
.SetPoint(Point(n
+ nIndentWidth2
, nVirBottom
- 3), 4);
781 aPoly
.SetPoint(Point(n
+ 0, nVirTop
+ nIndentHeight
), 0);
782 aPoly
.SetPoint(Point(n
- nIndentWidth2
, nVirTop
+ 3), 1);
783 aPoly
.SetPoint(Point(n
- nIndentWidth2
, nVirTop
), 2);
784 aPoly
.SetPoint(Point(n
+ nIndentWidth2
, nVirTop
), 3);
785 aPoly
.SetPoint(Point(n
+ nIndentWidth2
, nVirTop
+ 3), 4);
788 if (0 == (mnWinStyle
& WB_HORZ
))
791 for (sal_uInt16 i
= 0; i
< 5; i
++)
794 Point
aSet(nVirBottom
- aTmp
.Y(), aTmp
.X());
799 if (mxCurrentHitTest
!= nullptr && mxCurrentHitTest
->eType
== RulerType::Indent
)
801 bIsHit
= mxCurrentHitTest
->nAryPos
== j
;
803 else if(mbDrag
&& meDragType
== RulerType::Indent
)
805 bIsHit
= mnDragAryPos
== j
;
807 ImplDrawIndent(rRenderContext
, aPoly
, bIsHit
);
812 static void ImplCenterTabPos(Point
& rPos
, sal_uInt16 nTabStyle
)
814 bool bRTL
= 0 != (nTabStyle
& RULER_TAB_RTL
);
815 nTabStyle
&= RULER_TAB_STYLE
;
816 rPos
.AdjustY(ruler_tab
.height
/2 );
818 if ( (!bRTL
&& nTabStyle
== RULER_TAB_LEFT
) ||
819 ( bRTL
&& nTabStyle
== RULER_TAB_RIGHT
) )
821 rPos
.AdjustX( -(ruler_tab
.width
/ 2) );
823 else if ( (!bRTL
&& nTabStyle
== RULER_TAB_RIGHT
) ||
824 ( bRTL
&& nTabStyle
== RULER_TAB_LEFT
) )
826 rPos
.AdjustX(ruler_tab
.width
/ 2 );
830 static void lcl_RotateRect_Impl(tools::Rectangle
& rRect
, const tools::Long nReference
, bool bRightAligned
)
835 tools::Rectangle
aTmp(rRect
);
836 rRect
.SetTop( aTmp
.Left() );
837 rRect
.SetBottom( aTmp
.Right() );
838 rRect
.SetLeft( aTmp
.Top() );
839 rRect
.SetRight( aTmp
.Bottom() );
843 tools::Long nRef
= 2 * nReference
;
844 rRect
.SetLeft( nRef
- rRect
.Left() );
845 rRect
.SetRight( nRef
- rRect
.Right() );
849 static void ImplDrawRulerTab(vcl::RenderContext
& rRenderContext
, const Point
& rPos
,
850 sal_uInt16 nStyle
, WinBits nWinBits
)
852 if (nStyle
& RULER_STYLE_INVISIBLE
)
855 sal_uInt16 nTabStyle
= nStyle
& RULER_TAB_STYLE
;
856 bool bRTL
= 0 != (nStyle
& RULER_TAB_RTL
);
858 // Scale by the screen DPI scaling factor
859 // However when doing this some of the rectangles
860 // drawn become asymmetric due to the +1 offsets
861 sal_uInt16 DPIOffset
= rRenderContext
.GetDPIScaleFactor() - 1;
863 tools::Rectangle aRect1
;
864 tools::Rectangle aRect2
;
865 tools::Rectangle aRect3
;
869 if (nTabStyle
== RULER_TAB_DEFAULT
)
871 aRect1
.SetLeft( rPos
.X() - ruler_tab
.dwidth2
+ 1 );
872 aRect1
.SetTop( rPos
.Y() - ruler_tab
.dheight2
+ 1 );
873 aRect1
.SetRight( rPos
.X() - ruler_tab
.dwidth2
+ ruler_tab
.dwidth
+ DPIOffset
);
874 aRect1
.SetBottom( rPos
.Y() );
876 aRect2
.SetLeft( rPos
.X() - ruler_tab
.dwidth2
+ ruler_tab
.dwidth3
);
877 aRect2
.SetTop( rPos
.Y() - ruler_tab
.dheight
+ 1 );
878 aRect2
.SetRight( rPos
.X() - ruler_tab
.dwidth2
+ ruler_tab
.dwidth3
+ ruler_tab
.dwidth4
- 1 );
879 aRect2
.SetBottom( rPos
.Y() );
882 else if ((!bRTL
&& nTabStyle
== RULER_TAB_LEFT
) || (bRTL
&& nTabStyle
== RULER_TAB_RIGHT
))
884 aRect1
.SetLeft( rPos
.X() );
885 aRect1
.SetTop( rPos
.Y() - ruler_tab
.height2
+ 1 );
886 aRect1
.SetRight( rPos
.X() + ruler_tab
.width
- 1 );
887 aRect1
.SetBottom( rPos
.Y() );
889 aRect2
.SetLeft( rPos
.X() );
890 aRect2
.SetTop( rPos
.Y() - ruler_tab
.height
+ 1 );
891 aRect2
.SetRight( rPos
.X() + ruler_tab
.width2
- 1 );
892 aRect2
.SetBottom( rPos
.Y() );
894 else if ((!bRTL
&& nTabStyle
== RULER_TAB_RIGHT
) || (bRTL
&& nTabStyle
== RULER_TAB_LEFT
))
896 aRect1
.SetLeft( rPos
.X() - ruler_tab
.width
+ 1 );
897 aRect1
.SetTop( rPos
.Y() - ruler_tab
.height2
+ 1 );
898 aRect1
.SetRight( rPos
.X() );
899 aRect1
.SetBottom( rPos
.Y() );
901 aRect2
.SetLeft( rPos
.X() - ruler_tab
.width2
+ 1 );
902 aRect2
.SetTop( rPos
.Y() - ruler_tab
.height
+ 1 );
903 aRect2
.SetRight( rPos
.X() );
904 aRect2
.SetBottom( rPos
.Y() );
908 aRect1
.SetLeft( rPos
.X() - ruler_tab
.cwidth2
+ 1 );
909 aRect1
.SetTop( rPos
.Y() - ruler_tab
.height2
+ 1 );
910 aRect1
.SetRight( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth
+ DPIOffset
);
911 aRect1
.SetBottom( rPos
.Y() );
913 aRect2
.SetLeft( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth3
);
914 aRect2
.SetTop( rPos
.Y() - ruler_tab
.height
+ 1 );
915 aRect2
.SetRight( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth3
+ ruler_tab
.cwidth4
- 1 );
916 aRect2
.SetBottom( rPos
.Y() );
918 if (nTabStyle
== RULER_TAB_DECIMAL
)
920 aRect3
.SetLeft( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth
- 1 );
921 aRect3
.SetTop( rPos
.Y() - ruler_tab
.height
+ 1 + 1 - DPIOffset
);
922 aRect3
.SetRight( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth
+ DPIOffset
);
923 aRect3
.SetBottom( rPos
.Y() - ruler_tab
.height
+ 1 + 2 );
926 if (0 == (nWinBits
& WB_HORZ
))
928 bool bRightAligned
= 0 != (nWinBits
& WB_RIGHT_ALIGNED
);
929 lcl_RotateRect_Impl(aRect1
, rPos
.Y(), bRightAligned
);
930 lcl_RotateRect_Impl(aRect2
, rPos
.Y(), bRightAligned
);
931 lcl_RotateRect_Impl(aRect3
, rPos
.Y(), bRightAligned
);
933 rRenderContext
.DrawRect(aRect1
);
934 rRenderContext
.DrawRect(aRect2
);
936 if (!aRect3
.IsEmpty())
937 rRenderContext
.DrawRect(aRect3
);
940 void Ruler::ImplDrawTab(vcl::RenderContext
& rRenderContext
, const Point
& rPos
, sal_uInt16 nStyle
)
942 if (nStyle
& RULER_STYLE_INVISIBLE
)
945 rRenderContext
.SetLineColor();
947 if (nStyle
& RULER_STYLE_DONTKNOW
)
948 rRenderContext
.SetFillColor(rRenderContext
.GetSettings().GetStyleSettings().GetFaceColor());
950 rRenderContext
.SetFillColor(rRenderContext
.GetSettings().GetStyleSettings().GetDarkShadowColor());
952 if (mpData
->bTextRTL
)
953 nStyle
|= RULER_TAB_RTL
;
955 ImplDrawRulerTab(rRenderContext
, rPos
, nStyle
, GetStyle());
958 void Ruler::ImplDrawTabs(vcl::RenderContext
& rRenderContext
, tools::Long nMin
, tools::Long nMax
, tools::Long nVirTop
, tools::Long nVirBottom
)
960 for (const RulerTab
& rTab
: mpData
->pTabs
)
962 if (rTab
.nStyle
& RULER_STYLE_INVISIBLE
)
965 tools::Long aPosition
;
966 aPosition
= rTab
.nPos
;
967 aPosition
+= +mpData
->nNullVirOff
;
968 tools::Long nTopBottom
= (GetStyle() & WB_RIGHT_ALIGNED
) ? nVirTop
: nVirBottom
;
969 if (nMin
<= aPosition
&& aPosition
<= nMax
)
970 ImplDrawTab(rRenderContext
, Point( aPosition
, nTopBottom
), rTab
.nStyle
);
974 static int adjustSize(int nOrig
)
979 // make sure we return an odd number, that looks better in the ruler
980 return ( (3*nOrig
) / 8) * 2 + 1;
983 void Ruler::ApplySettings(vcl::RenderContext
& rRenderContext
)
985 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
987 vcl::Font aFont
= rStyleSettings
.GetToolFont();
988 // make the font a bit smaller than default
989 Size
aSize(adjustSize(aFont
.GetFontSize().Width()), adjustSize(aFont
.GetFontSize().Height()));
990 aFont
.SetFontSize(aSize
);
992 ApplyControlFont(rRenderContext
, aFont
);
994 ApplyControlForeground(*this, rStyleSettings
.GetDarkShadowColor());
998 svtools::ColorConfig aColorConfig
;
999 aColor
= aColorConfig
.GetColorValue(svtools::APPBACKGROUND
).nColor
;
1000 ApplyControlBackground(rRenderContext
, aColor
);
1003 void Ruler::ImplInitSettings(bool bFont
, bool bForeground
, bool bBackground
)
1005 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1009 vcl::Font aFont
= rStyleSettings
.GetToolFont();
1010 // make the font a bit smaller than default
1011 Size
aSize(adjustSize(aFont
.GetFontSize().Width()), adjustSize(aFont
.GetFontSize().Height()));
1012 aFont
.SetFontSize(aSize
);
1014 ApplyControlFont(*this, aFont
);
1017 if (bForeground
|| bFont
)
1019 ApplyControlForeground(*this, rStyleSettings
.GetDarkShadowColor());
1026 svtools::ColorConfig aColorConfig
;
1027 aColor
= aColorConfig
.GetColorValue(svtools::APPBACKGROUND
).nColor
;
1028 ApplyControlBackground(*this, aColor
);
1031 maVirDev
->SetSettings( GetSettings() );
1032 maVirDev
->SetBackground( GetBackground() );
1033 vcl::Font aFont
= GetFont();
1035 if (mnWinStyle
& WB_VERT
)
1036 aFont
.SetOrientation(Degree10(900));
1038 maVirDev
->SetFont(aFont
);
1039 maVirDev
->SetTextColor(GetTextColor());
1040 maVirDev
->SetTextFillColor(GetTextFillColor());
1043 void Ruler::ImplCalc()
1046 mpData
->nRulVirOff
= mnWinOff
+ mpData
->nPageOff
;
1047 if ( mpData
->nRulVirOff
> mnVirOff
)
1048 mpData
->nRulVirOff
-= mnVirOff
;
1050 mpData
->nRulVirOff
= 0;
1051 tools::Long nRulWinOff
= mpData
->nRulVirOff
+mnVirOff
;
1053 // calculate non-visual part of the page
1054 tools::Long nNotVisPageWidth
;
1055 if ( mpData
->nPageOff
< 0 )
1057 nNotVisPageWidth
= -(mpData
->nPageOff
);
1058 if ( nRulWinOff
< mnWinOff
)
1059 nNotVisPageWidth
-= mnWinOff
-nRulWinOff
;
1062 nNotVisPageWidth
= 0;
1065 if ( mnWinStyle
& WB_HORZ
)
1067 if ( mbAutoWinWidth
)
1068 mnWinWidth
= mnWidth
- mnVirOff
;
1069 if ( mpData
->bAutoPageWidth
)
1070 mpData
->nPageWidth
= mnWinWidth
;
1071 mpData
->nRulWidth
= std::min( mnWinWidth
, mpData
->nPageWidth
-nNotVisPageWidth
);
1072 if ( nRulWinOff
+mpData
->nRulWidth
> mnWidth
)
1073 mpData
->nRulWidth
= mnWidth
-nRulWinOff
;
1077 if ( mbAutoWinWidth
)
1078 mnWinWidth
= mnHeight
- mnVirOff
;
1079 if ( mpData
->bAutoPageWidth
)
1080 mpData
->nPageWidth
= mnWinWidth
;
1081 mpData
->nRulWidth
= std::min( mnWinWidth
, mpData
->nPageWidth
-nNotVisPageWidth
);
1082 if ( nRulWinOff
+mpData
->nRulWidth
> mnHeight
)
1083 mpData
->nRulWidth
= mnHeight
-nRulWinOff
;
1089 void Ruler::ImplFormat(vcl::RenderContext
const & rRenderContext
)
1091 // if already formatted, don't do it again
1095 // don't do anything if the window still has no size
1099 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
1100 tools::Long nP1
; // pixel position of Page1
1101 tools::Long nP2
; // pixel position of Page2
1102 tools::Long nM1
; // pixel position of Margin1
1103 tools::Long nM2
; // pixel position of Margin2
1104 tools::Long nVirTop
; // top/left corner
1105 tools::Long nVirBottom
; // bottom/right corner
1106 tools::Long nVirLeft
; // left/top corner
1107 tools::Long nVirRight
; // right/bottom corner
1108 tools::Long nNullVirOff
; // for faster calculation
1114 mpData
->nNullVirOff
= mnWinOff
+ mpData
->nPageOff
+ mpData
->nNullOff
- mnVirOff
;
1116 nNullVirOff
= mpData
->nNullVirOff
;
1117 nVirLeft
= mpData
->nRulVirOff
;
1118 nVirRight
= nVirLeft
+ mpData
->nRulWidth
- 1;
1120 nVirBottom
= mnVirHeight
- 1;
1122 if (!IsReallyVisible())
1127 // initialize VirtualDevice
1128 if (mnWinStyle
& WB_HORZ
)
1130 aVirDevSize
.setWidth( mnVirWidth
);
1131 aVirDevSize
.setHeight( mnVirHeight
);
1135 aVirDevSize
.setHeight( mnVirWidth
);
1136 aVirDevSize
.setWidth( mnVirHeight
);
1138 if (aVirDevSize
!= maVirDev
->GetOutputSizePixel())
1139 maVirDev
->SetOutputSizePixel(aVirDevSize
);
1143 // calculate margins
1144 if (!(mpData
->nMargin1Style
& RulerMarginStyle::Invisible
))
1146 nM1
= mpData
->nMargin1
+ nNullVirOff
;
1147 if (mpData
->bAutoPageWidth
)
1154 nP1
= nNullVirOff
- mpData
->nNullOff
;
1161 if (!(mpData
->nMargin2Style
& RulerMarginStyle::Invisible
))
1163 nM2
= mpData
->nMargin2
+ nNullVirOff
;
1164 if (mpData
->bAutoPageWidth
)
1167 if (nM2
> nVirRight
)
1171 nP2
= nNullVirOff
- mpData
->nNullOff
+ mpData
->nPageWidth
;
1181 // top/bottom border
1182 maVirDev
->SetLineColor(rStyleSettings
.GetShadowColor());
1183 ImplVDrawLine(*maVirDev
, nVirLeft
, nVirTop
+ 1, nM1
, nVirTop
+ 1); //top left line
1184 ImplVDrawLine(*maVirDev
, nM2
, nVirTop
+ 1, nP2
- 1, nVirTop
+ 1); //top right line
1189 // draw margin1, margin2 and in-between
1190 maVirDev
->SetLineColor();
1191 maVirDev
->SetFillColor(rStyleSettings
.GetDialogColor());
1193 ImplVDrawRect(*maVirDev
, nP1
, nVirTop
+ 1, nM1
, nVirBottom
); //left gray rectangle
1195 ImplVDrawRect(*maVirDev
, nM2
, nVirTop
+ 1, nP2
, nVirBottom
); //right gray rectangle
1198 maVirDev
->SetFillColor(rStyleSettings
.GetWindowColor());
1199 ImplVDrawRect(*maVirDev
, nM1
+ 1, nVirTop
, nM2
- 1, nVirBottom
); //center rectangle
1201 maVirDev
->SetLineColor(rStyleSettings
.GetShadowColor());
1204 ImplVDrawLine(*maVirDev
, nM1
, nVirTop
+ 1, nM1
, nVirBottom
); //right line of the left rectangle
1205 ImplVDrawLine(*maVirDev
, nP1
, nVirBottom
, nM1
, nVirBottom
); //bottom line of the left rectangle
1206 if (nP1
>= nVirLeft
)
1208 ImplVDrawLine(*maVirDev
, nP1
, nVirTop
+ 1, nP1
, nVirBottom
); //left line of the left rectangle
1209 ImplVDrawLine(*maVirDev
, nP1
, nVirBottom
, nP1
+ 1, nVirBottom
); //?
1214 ImplVDrawLine(*maVirDev
, nM2
, nVirBottom
, nP2
- 1, nVirBottom
); //bottom line of the right rectangle
1215 ImplVDrawLine(*maVirDev
, nM2
, nVirTop
+ 1, nM2
, nVirBottom
); //left line of the right rectangle
1216 if (nP2
<= nVirRight
+ 1)
1217 ImplVDrawLine(*maVirDev
, nP2
- 1, nVirTop
+ 1, nP2
- 1, nVirBottom
); //right line of the right rectangle
1220 tools::Long nMin
= nVirLeft
;
1221 tools::Long nMax
= nP2
;
1222 tools::Long nStart
= 0;
1224 if (mpData
->bTextRTL
)
1225 nStart
= mpData
->nRightFrameMargin
+ nNullVirOff
;
1227 nStart
= mpData
->nLeftFrameMargin
+ nNullVirOff
;
1232 if (nP2
< nVirRight
)
1236 ImplDrawTicks(*maVirDev
, nMin
, nMax
, nStart
, nVirTop
, nVirBottom
);
1239 if (!mpData
->pBorders
.empty())
1240 ImplDrawBorders(*maVirDev
, nVirLeft
, nP2
, nVirTop
, nVirBottom
);
1243 if (!mpData
->pIndents
.empty())
1244 ImplDrawIndents(*maVirDev
, nVirLeft
, nP2
, nVirTop
- 1, nVirBottom
+ 1);
1247 if (!mpData
->pTabs
.empty())
1248 ImplDrawTabs(*maVirDev
, nVirLeft
, nP2
, nVirTop
-1, nVirBottom
+ 1);
1253 void Ruler::ImplInitExtraField( bool bUpdate
)
1255 Size aWinSize
= GetOutputSizePixel();
1257 // extra field evaluate
1258 if ( mnWinStyle
& WB_EXTRAFIELD
)
1260 maExtraRect
.SetLeft( RULER_OFF
);
1261 maExtraRect
.SetTop( RULER_OFF
);
1262 maExtraRect
.SetRight( RULER_OFF
+ mnVirHeight
- 1 );
1263 maExtraRect
.SetBottom( RULER_OFF
+ mnVirHeight
- 1 );
1264 if(mpData
->bTextRTL
)
1266 if(mnWinStyle
& WB_HORZ
)
1267 maExtraRect
.Move(aWinSize
.Width() - maExtraRect
.GetWidth() - maExtraRect
.Left(), 0);
1269 maExtraRect
.Move(0, aWinSize
.Height() - maExtraRect
.GetHeight() - maExtraRect
.Top());
1273 mnVirOff
= maExtraRect
.Right()+1;
1278 maExtraRect
.SetEmpty();
1282 // mnVirWidth depends on mnVirOff
1283 if ( (mnVirWidth
> RULER_MIN_SIZE
) ||
1284 ((aWinSize
.Width() > RULER_MIN_SIZE
) && (aWinSize
.Height() > RULER_MIN_SIZE
)) )
1286 if ( mnWinStyle
& WB_HORZ
)
1287 mnVirWidth
= aWinSize
.Width()-mnVirOff
;
1289 mnVirWidth
= aWinSize
.Height()-mnVirOff
;
1291 if ( mnVirWidth
< RULER_MIN_SIZE
)
1303 void Ruler::ImplDraw(vcl::RenderContext
& rRenderContext
)
1307 ImplFormat(rRenderContext
);
1310 if (!IsReallyVisible())
1313 // output the ruler to the virtual device
1315 Size aVirDevSize
= maVirDev
->GetOutputSizePixel();
1317 if (mnWinStyle
& WB_HORZ
)
1319 aOffPos
.setX( mnVirOff
);
1320 if (mpData
->bTextRTL
)
1321 aVirDevSize
.AdjustWidth( -(maExtraRect
.GetWidth()) );
1323 aOffPos
.setY( RULER_OFF
);
1327 aOffPos
.setX( RULER_OFF
);
1328 aOffPos
.setY( mnVirOff
);
1330 rRenderContext
.DrawOutDev(aOffPos
, aVirDevSize
, Point(), aVirDevSize
, *maVirDev
);
1332 // redraw positionlines
1333 ImplInvertLines(rRenderContext
);
1336 void Ruler::ImplDrawExtra(vcl::RenderContext
& rRenderContext
)
1338 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
1339 tools::Rectangle aRect
= maExtraRect
;
1340 bool bEraseRect
= false;
1342 aRect
.AdjustLeft(2 );
1343 aRect
.AdjustTop(2 );
1344 aRect
.AdjustRight( -2 );
1345 aRect
.AdjustBottom( -2 );
1347 if (mnExtraStyle
& RULER_STYLE_HIGHLIGHT
)
1349 rRenderContext
.SetFillColor(rStyleSettings
.GetCheckedColor());
1355 rRenderContext
.SetLineColor();
1356 rRenderContext
.DrawRect(aRect
);
1360 if (meExtraType
== RulerExtra::NullOffset
)
1362 rRenderContext
.SetLineColor(rStyleSettings
.GetButtonTextColor());
1363 rRenderContext
.DrawLine(Point(aRect
.Left() + 1, aRect
.Top() + 4),
1364 Point(aRect
.Right() - 1, aRect
.Top() + 4));
1365 rRenderContext
.DrawLine(Point(aRect
.Left() + 4, aRect
.Top() + 1),
1366 Point(aRect
.Left() + 4, aRect
.Bottom() - 1));
1368 else if (meExtraType
== RulerExtra::Tab
)
1370 sal_uInt16 nTabStyle
= mnExtraStyle
& RULER_TAB_STYLE
;
1371 if (mpData
->bTextRTL
)
1372 nTabStyle
|= RULER_TAB_RTL
;
1373 Point aCenter
= aRect
.Center();
1374 Point
aDraw(aCenter
);
1375 ImplCenterTabPos(aDraw
, nTabStyle
);
1376 WinBits nWinBits
= GetStyle();
1377 if (0 == (nWinBits
& WB_HORZ
))
1379 if ((nWinBits
& WB_RIGHT_ALIGNED
) != 0)
1380 aDraw
.setY( 2 * aCenter
.Y() - aDraw
.Y() );
1382 if (mpData
->bTextRTL
)
1384 tools::Long nTemp
= aDraw
.X();
1385 aDraw
.setX( aDraw
.Y() );
1386 aDraw
.setY( nTemp
);
1389 ImplDrawTab(rRenderContext
, aDraw
, nTabStyle
);
1393 void Ruler::ImplUpdate( bool bMustCalc
)
1395 // clear lines in this place so they aren't considered at recalculation
1397 Invalidate(InvalidateFlags::NoErase
);
1404 // abort if we are dragging as drag-handler will update the ruler after drag is finished
1408 // otherwise trigger update
1409 if (IsReallyVisible() && IsUpdateMode())
1411 Invalidate(InvalidateFlags::NoErase
);
1415 bool Ruler::ImplHitTest( const Point
& rPos
, RulerSelection
* pHitTest
,
1416 bool bRequireStyle
, RulerIndentStyle nRequiredStyle
) const
1420 tools::Long nHitBottom
;
1428 // determine positions
1429 bool bIsHori
= 0 != (mnWinStyle
& WB_HORZ
);
1440 nHitBottom
= mnVirHeight
+ (RULER_OFF
* 2);
1443 pHitTest
->nAryPos
= 0;
1444 pHitTest
->mnDragSize
= RulerDragSize::Move
;
1445 pHitTest
->bSize
= false;
1446 pHitTest
->bSizeBar
= false;
1448 // so that leftover tabs and indents are taken into account
1449 tools::Long nXExtraOff
;
1450 if ( !mpData
->pTabs
.empty() || !mpData
->pIndents
.empty() )
1451 nXExtraOff
= (mnVirHeight
/ 2) - 4;
1457 if ( (nX
< mpData
->nRulVirOff
- nXExtraOff
) ||
1458 (nX
> mpData
->nRulVirOff
+ mpData
->nRulWidth
+ nXExtraOff
) ||
1463 pHitTest
->eType
= RulerType::Outside
;
1467 nX
-= mpData
->nNullVirOff
;
1468 pHitTest
->nPos
= nX
;
1469 pHitTest
->eType
= RulerType::DontKnow
;
1471 // first test the tabs
1472 tools::Rectangle aRect
;
1473 if ( !mpData
->pTabs
.empty() )
1475 aRect
.SetBottom( nHitBottom
);
1476 aRect
.SetTop( aRect
.Bottom() - ruler_tab
.height
- RULER_OFF
);
1478 for ( i
= mpData
->pTabs
.size() - 1; i
>= 0; i
-- )
1480 nStyle
= mpData
->pTabs
[i
].nStyle
;
1481 if ( !(nStyle
& RULER_STYLE_INVISIBLE
) )
1483 nStyle
&= RULER_TAB_STYLE
;
1485 // default tabs are only shown (no action)
1486 if ( nStyle
!= RULER_TAB_DEFAULT
)
1488 n1
= mpData
->pTabs
[i
].nPos
;
1490 if ( nStyle
== RULER_TAB_LEFT
)
1492 aRect
.SetLeft( n1
);
1493 aRect
.SetRight( n1
+ ruler_tab
.width
- 1 );
1495 else if ( nStyle
== RULER_TAB_RIGHT
)
1497 aRect
.SetRight( n1
);
1498 aRect
.SetLeft( n1
- ruler_tab
.width
- 1 );
1502 aRect
.SetLeft( n1
- ruler_tab
.cwidth2
+ 1 );
1503 aRect
.SetRight( n1
- ruler_tab
.cwidth2
+ ruler_tab
.cwidth
);
1506 if ( aRect
.IsInside( Point( nX
, nY
) ) )
1508 pHitTest
->eType
= RulerType::Tab
;
1509 pHitTest
->nAryPos
= i
;
1518 if ( !mpData
->pIndents
.empty() )
1520 tools::Long nIndentHeight
= (mnVirHeight
/ 2) - 1;
1521 tools::Long nIndentWidth2
= nIndentHeight
- 3;
1523 for ( i
= mpData
->pIndents
.size(); i
; i
-- )
1525 RulerIndentStyle nIndentStyle
= mpData
->pIndents
[i
-1].nStyle
;
1526 if ( (! bRequireStyle
|| nIndentStyle
== nRequiredStyle
) &&
1527 !mpData
->pIndents
[i
-1].bInvisible
)
1529 n1
= mpData
->pIndents
[i
-1].nPos
;
1531 if ( (nIndentStyle
== RulerIndentStyle::Bottom
) != !bIsHori
)
1533 aRect
.SetLeft( n1
-nIndentWidth2
);
1534 aRect
.SetRight( n1
+nIndentWidth2
);
1535 aRect
.SetTop( nHitBottom
-nIndentHeight
-RULER_OFF
+1 );
1536 aRect
.SetBottom( nHitBottom
);
1540 aRect
.SetLeft( n1
-nIndentWidth2
);
1541 aRect
.SetRight( n1
+nIndentWidth2
);
1543 aRect
.SetBottom( nIndentHeight
+RULER_OFF
-1 );
1546 if ( aRect
.IsInside( Point( nX
, nY
) ) )
1548 pHitTest
->eType
= RulerType::Indent
;
1549 pHitTest
->nAryPos
= i
-1;
1557 int nBorderTolerance
= 1;
1558 if(pHitTest
->bExpandTest
)
1563 for ( i
= mpData
->pBorders
.size(); i
; i
-- )
1565 n1
= mpData
->pBorders
[i
-1].nPos
;
1566 tools::Long n2
= n1
+ mpData
->pBorders
[i
-1].nWidth
;
1568 // borders have at least 3 pixel padding
1569 if ( !mpData
->pBorders
[i
-1].nWidth
)
1571 n1
-= nBorderTolerance
;
1572 n2
+= nBorderTolerance
;
1576 if ( (nX
>= n1
) && (nX
<= n2
) )
1578 RulerBorderStyle nBorderStyle
= mpData
->pBorders
[i
-1].nStyle
;
1579 if ( !(nBorderStyle
& RulerBorderStyle::Invisible
) )
1581 pHitTest
->eType
= RulerType::Border
;
1582 pHitTest
->nAryPos
= i
-1;
1584 if ( !(nBorderStyle
& RulerBorderStyle::Sizeable
) )
1586 if ( nBorderStyle
& RulerBorderStyle::Moveable
)
1588 pHitTest
->bSizeBar
= true;
1589 pHitTest
->mnDragSize
= RulerDragSize::Move
;
1594 tools::Long nMOff
= RULER_MOUSE_BORDERWIDTH
;
1595 while ( nMOff
*2 >= (n2
-n1
-RULER_MOUSE_BORDERMOVE
) )
1606 if ( nX
<= n1
+nMOff
)
1608 pHitTest
->bSize
= true;
1609 pHitTest
->mnDragSize
= RulerDragSize::N1
;
1611 else if ( nX
>= n2
-nMOff
)
1613 pHitTest
->bSize
= true;
1614 pHitTest
->mnDragSize
= RulerDragSize::N2
;
1618 if ( nBorderStyle
& RulerBorderStyle::Moveable
)
1620 pHitTest
->bSizeBar
= true;
1621 pHitTest
->mnDragSize
= RulerDragSize::Move
;
1632 int nMarginTolerance
= pHitTest
->bExpandTest
? nBorderTolerance
: RULER_MOUSE_MARGINWIDTH
;
1634 if ( (mpData
->nMargin1Style
& (RulerMarginStyle::Sizeable
| RulerMarginStyle::Invisible
)) == RulerMarginStyle::Sizeable
)
1636 n1
= mpData
->nMargin1
;
1637 if ( (nX
>= n1
- nMarginTolerance
) && (nX
<= n1
+ nMarginTolerance
) )
1639 pHitTest
->eType
= RulerType::Margin1
;
1640 pHitTest
->bSize
= true;
1644 if ( (mpData
->nMargin2Style
& (RulerMarginStyle::Sizeable
| RulerMarginStyle::Invisible
)) == RulerMarginStyle::Sizeable
)
1646 n1
= mpData
->nMargin2
;
1647 if ( (nX
>= n1
- nMarginTolerance
) && (nX
<= n1
+ nMarginTolerance
) )
1649 pHitTest
->eType
= RulerType::Margin2
;
1650 pHitTest
->bSize
= true;
1656 if ( !mpData
->pTabs
.empty() )
1658 aRect
.SetTop( RULER_OFF
);
1659 aRect
.SetBottom( nHitBottom
);
1661 for ( i
= mpData
->pTabs
.size() - 1; i
>= 0; i
-- )
1663 nStyle
= mpData
->pTabs
[i
].nStyle
;
1664 if ( !(nStyle
& RULER_STYLE_INVISIBLE
) )
1666 nStyle
&= RULER_TAB_STYLE
;
1668 // default tabs are only shown (no action)
1669 if ( nStyle
!= RULER_TAB_DEFAULT
)
1671 n1
= mpData
->pTabs
[i
].nPos
;
1673 if ( nStyle
== RULER_TAB_LEFT
)
1675 aRect
.SetLeft( n1
);
1676 aRect
.SetRight( n1
+ ruler_tab
.width
- 1 );
1678 else if ( nStyle
== RULER_TAB_RIGHT
)
1680 aRect
.SetRight( n1
);
1681 aRect
.SetLeft( n1
- ruler_tab
.width
- 1 );
1685 aRect
.SetLeft( n1
- ruler_tab
.cwidth2
+ 1 );
1686 aRect
.SetRight( n1
- ruler_tab
.cwidth2
+ ruler_tab
.cwidth
);
1689 aRect
.AdjustLeft( -1 );
1690 aRect
.AdjustRight( 1 );
1692 if ( aRect
.IsInside( Point( nX
, nY
) ) )
1694 pHitTest
->eType
= RulerType::Tab
;
1695 pHitTest
->nAryPos
= i
;
1706 bool Ruler::ImplDocHitTest( const Point
& rPos
, RulerType eDragType
,
1707 RulerSelection
* pHitTest
) const
1710 bool bRequiredStyle
= false;
1711 RulerIndentStyle nRequiredStyle
= RulerIndentStyle::Top
;
1713 if (eDragType
== RulerType::Indent
)
1715 bRequiredStyle
= true;
1716 nRequiredStyle
= RulerIndentStyle::Bottom
;
1719 if ( mnWinStyle
& WB_HORZ
)
1720 aPos
.AdjustX(mnWinOff
);
1722 aPos
.AdjustY(mnWinOff
);
1724 if ( (eDragType
== RulerType::Indent
) || (eDragType
== RulerType::DontKnow
) )
1726 if ( mnWinStyle
& WB_HORZ
)
1727 aPos
.setY( RULER_OFF
+ 1 );
1729 aPos
.setX( RULER_OFF
+ 1 );
1731 if ( ImplHitTest( aPos
, pHitTest
, bRequiredStyle
, nRequiredStyle
) )
1733 if ( (pHitTest
->eType
== eDragType
) || (eDragType
== RulerType::DontKnow
) )
1738 if ( (eDragType
== RulerType::Indent
) ||
1739 (eDragType
== RulerType::Tab
) ||
1740 (eDragType
== RulerType::DontKnow
) )
1742 if ( mnWinStyle
& WB_HORZ
)
1743 aPos
.setY( mnHeight
- RULER_OFF
- 1 );
1745 aPos
.setX( mnWidth
- RULER_OFF
- 1 );
1747 if ( ImplHitTest( aPos
, pHitTest
, bRequiredStyle
, nRequiredStyle
) )
1749 if ( (pHitTest
->eType
== eDragType
) || (eDragType
== RulerType::DontKnow
) )
1754 if ( (eDragType
== RulerType::Margin1
) || (eDragType
== RulerType::Margin2
) ||
1755 (eDragType
== RulerType::Border
) || (eDragType
== RulerType::DontKnow
) )
1757 if ( mnWinStyle
& WB_HORZ
)
1758 aPos
.setY( RULER_OFF
+ (mnVirHeight
/ 2) );
1760 aPos
.setX( RULER_OFF
+ (mnVirHeight
/ 2) );
1762 if ( ImplHitTest( aPos
, pHitTest
) )
1764 if ( (pHitTest
->eType
== eDragType
) || (eDragType
== RulerType::DontKnow
) )
1769 pHitTest
->eType
= RulerType::DontKnow
;
1774 bool Ruler::ImplStartDrag( RulerSelection
const * pHitTest
, sal_uInt16 nModifier
)
1776 // don't trigger drag if a border that was clicked can not be changed
1777 if ( (pHitTest
->eType
== RulerType::Border
) &&
1778 !pHitTest
->bSize
&& !pHitTest
->bSizeBar
)
1782 meDragType
= pHitTest
->eType
;
1783 mnDragPos
= pHitTest
->nPos
;
1784 mnDragAryPos
= pHitTest
->nAryPos
;
1785 mnDragSize
= pHitTest
->mnDragSize
;
1786 mnDragModifier
= nModifier
;
1787 *mpDragData
= *mpSaveData
;
1788 mpData
= mpDragData
.get();
1793 // if the handler allows dragging, initialize dragging
1795 mnStartDragPos
= mnDragPos
;
1797 Invalidate(InvalidateFlags::NoErase
);
1802 // otherwise reset the data
1803 meDragType
= RulerType::DontKnow
;
1806 mnDragSize
= RulerDragSize::Move
;
1808 mpData
= mpSaveData
.get();
1814 void Ruler::ImplDrag( const Point
& rPos
)
1818 tools::Long nOutHeight
;
1820 if ( mnWinStyle
& WB_HORZ
)
1824 nOutHeight
= mnHeight
;
1830 nOutHeight
= mnWidth
;
1833 // calculate and fit X
1835 if ( nX
< mpData
->nRulVirOff
)
1837 nX
= mpData
->nRulVirOff
;
1839 else if ( nX
> mpData
->nRulVirOff
+mpData
->nRulWidth
)
1841 nX
= mpData
->nRulVirOff
+mpData
->nRulWidth
;
1843 nX
-= mpData
->nNullVirOff
;
1845 // if upper or left from ruler, then consider old values
1846 mbDragDelete
= false;
1849 if ( !mbDragCanceled
)
1852 mbDragCanceled
= true;
1853 ImplRulerData aTempData
= *mpDragData
;
1854 *mpDragData
= *mpSaveData
;
1859 mnDragPos
= mnStartDragPos
;
1863 Invalidate(InvalidateFlags::NoErase
);
1865 // reset the data as before cancel
1866 *mpDragData
= aTempData
;
1871 mbDragCanceled
= false;
1873 // +2, so the tabs are not cleared too quickly
1874 if ( nY
> nOutHeight
+ 2 )
1875 mbDragDelete
= true;
1884 Invalidate(InvalidateFlags::NoErase
);
1888 void Ruler::ImplEndDrag()
1891 if ( mbDragCanceled
)
1892 *mpDragData
= *mpSaveData
;
1894 *mpSaveData
= *mpDragData
;
1896 mpData
= mpSaveData
.get();
1902 // reset drag values
1903 meDragType
= RulerType::DontKnow
;
1906 mnDragSize
= RulerDragSize::Move
;
1907 mbDragCanceled
= false;
1908 mbDragDelete
= false;
1913 Invalidate(InvalidateFlags::NoErase
);
1916 void Ruler::MouseButtonDown( const MouseEvent
& rMEvt
)
1918 if ( !rMEvt
.IsLeft() || IsTracking() )
1921 Point aMousePos
= rMEvt
.GetPosPixel();
1922 sal_uInt16 nMouseClicks
= rMEvt
.GetClicks();
1923 sal_uInt16 nMouseModifier
= rMEvt
.GetModifier();
1928 Invalidate(InvalidateFlags::NoErase
);
1931 if ( maExtraRect
.IsInside( aMousePos
) )
1937 std::unique_ptr
<RulerSelection
> pHitTest(new RulerSelection
);
1938 bool bHitTestResult
= ImplHitTest(aMousePos
, pHitTest
.get());
1940 if ( nMouseClicks
== 1 )
1942 if ( bHitTestResult
)
1944 ImplStartDrag( pHitTest
.get(), nMouseModifier
);
1948 // calculate position inside of ruler area
1949 if ( pHitTest
->eType
== RulerType::DontKnow
)
1951 mnDragPos
= pHitTest
->nPos
;
1955 // call HitTest again as a click, for example, could set a new tab
1956 if ( ImplHitTest(aMousePos
, pHitTest
.get()) )
1957 ImplStartDrag(pHitTest
.get(), nMouseModifier
);
1965 mnDragPos
= pHitTest
->nPos
;
1966 mnDragAryPos
= pHitTest
->nAryPos
;
1968 meDragType
= pHitTest
->eType
;
1972 meDragType
= RulerType::DontKnow
;
1979 void Ruler::MouseMove( const MouseEvent
& rMEvt
)
1981 PointerStyle ePtrStyle
= PointerStyle::Arrow
;
1983 mxPreviousHitTest
.swap(mxCurrentHitTest
);
1985 mxCurrentHitTest
.reset(new RulerSelection
);
1987 maHoverSelection
.eType
= RulerType::DontKnow
;
1989 if (ImplHitTest( rMEvt
.GetPosPixel(), mxCurrentHitTest
.get() ))
1991 maHoverSelection
= *mxCurrentHitTest
;
1993 if (mxCurrentHitTest
->bSize
)
1995 if (mnWinStyle
& WB_HORZ
)
1997 if (mxCurrentHitTest
->mnDragSize
== RulerDragSize::N1
)
1998 ePtrStyle
= PointerStyle::TabSelectW
;
1999 else if (mxCurrentHitTest
->mnDragSize
== RulerDragSize::N2
)
2000 ePtrStyle
= PointerStyle::TabSelectE
;
2002 ePtrStyle
= PointerStyle::ESize
;
2006 if (mxCurrentHitTest
->mnDragSize
== RulerDragSize::N1
)
2007 ePtrStyle
= PointerStyle::WindowNSize
;
2008 else if (mxCurrentHitTest
->mnDragSize
== RulerDragSize::N2
)
2009 ePtrStyle
= PointerStyle::WindowSSize
;
2011 ePtrStyle
= PointerStyle::SSize
;
2014 else if (mxCurrentHitTest
->bSizeBar
)
2016 if (mnWinStyle
& WB_HORZ
)
2017 ePtrStyle
= PointerStyle::HSizeBar
;
2019 ePtrStyle
= PointerStyle::VSizeBar
;
2023 if (mxPreviousHitTest
!= nullptr && mxPreviousHitTest
->eType
!= mxCurrentHitTest
->eType
)
2028 SetPointer( ePtrStyle
);
2032 Invalidate(InvalidateFlags::NoErase
);
2036 void Ruler::Tracking( const TrackingEvent
& rTEvt
)
2038 if ( rTEvt
.IsTrackingEnded() )
2040 // reset the old state at cancel
2041 if ( rTEvt
.IsTrackingCanceled() )
2043 mbDragCanceled
= true;
2050 ImplDrag( rTEvt
.GetMouseEvent().GetPosPixel() );
2053 void Ruler::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
2055 ImplDraw(rRenderContext
);
2057 // consider extra field
2058 if (mnWinStyle
& WB_EXTRAFIELD
)
2059 ImplDrawExtra(rRenderContext
);
2062 void Ruler::Resize()
2064 Size aWinSize
= GetOutputSizePixel();
2066 tools::Long nNewHeight
;
2067 if ( mnWinStyle
& WB_HORZ
)
2069 if ( aWinSize
.Height() != mnHeight
)
2070 nNewHeight
= aWinSize
.Height();
2076 if ( aWinSize
.Width() != mnWidth
)
2077 nNewHeight
= aWinSize
.Width();
2085 bool bVisible
= IsReallyVisible();
2086 if ( bVisible
&& !mpData
->pLines
.empty() )
2088 mnUpdateFlags
|= RULER_UPDATE_LINES
;
2089 Invalidate(InvalidateFlags::NoErase
);
2092 // recalculate some values if the height/width changes
2093 // extra field should always be updated
2094 ImplInitExtraField( mpData
->bTextRTL
);
2098 mnVirHeight
= nNewHeight
- mnBorderWidth
- ( RULER_OFF
* 2 );
2102 if ( mpData
->bAutoPageWidth
)
2104 else if ( mbAutoWinWidth
)
2108 // clear part of the border
2112 Invalidate(InvalidateFlags::NoErase
);
2113 else if ( mpData
->bAutoPageWidth
)
2115 // only at AutoPageWidth do we need to redraw
2116 tools::Rectangle aRect
;
2118 if ( mnWinStyle
& WB_HORZ
)
2120 if ( mnWidth
< aWinSize
.Width() )
2121 aRect
.SetLeft( mnWidth
- RULER_RESIZE_OFF
);
2123 aRect
.SetLeft( aWinSize
.Width() - RULER_RESIZE_OFF
);
2124 aRect
.SetRight( aRect
.Left() + RULER_RESIZE_OFF
);
2125 aRect
.SetTop( RULER_OFF
);
2126 aRect
.SetBottom( RULER_OFF
+ mnVirHeight
);
2130 if ( mnHeight
< aWinSize
.Height() )
2131 aRect
.SetTop( mnHeight
-RULER_RESIZE_OFF
);
2133 aRect
.SetTop( aWinSize
.Height()-RULER_RESIZE_OFF
);
2134 aRect
.SetBottom( aRect
.Top() + RULER_RESIZE_OFF
);
2135 aRect
.SetLeft( RULER_OFF
);
2136 aRect
.SetRight( RULER_OFF
+ mnVirHeight
);
2139 Invalidate(aRect
, InvalidateFlags::NoErase
);
2143 mnWidth
= aWinSize
.Width();
2144 mnHeight
= aWinSize
.Height();
2147 void Ruler::StateChanged( StateChangedType nType
)
2149 Window::StateChanged( nType
);
2151 if ( nType
== StateChangedType::InitShow
)
2153 else if ( nType
== StateChangedType::UpdateMode
)
2155 if ( IsReallyVisible() && IsUpdateMode() )
2158 else if ( (nType
== StateChangedType::Zoom
) ||
2159 (nType
== StateChangedType::ControlFont
) )
2161 ImplInitSettings( true, false, false );
2164 else if ( nType
== StateChangedType::ControlForeground
)
2166 ImplInitSettings( false, true, false );
2169 else if ( nType
== StateChangedType::ControlBackground
)
2171 ImplInitSettings( false, false, true );
2176 void Ruler::DataChanged( const DataChangedEvent
& rDCEvt
)
2178 Window::DataChanged( rDCEvt
);
2180 if ( (rDCEvt
.GetType() == DataChangedEventType::FONTS
) ||
2181 (rDCEvt
.GetType() == DataChangedEventType::DISPLAY
) ||
2182 (rDCEvt
.GetType() == DataChangedEventType::FONTSUBSTITUTION
) ||
2183 ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
2184 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
)) )
2187 ImplInitSettings( true, true, true );
2192 bool Ruler::StartDrag()
2201 void Ruler::EndDrag()
2209 void Ruler::DoubleClick()
2211 maDoubleClickHdl
.Call( this );
2214 void Ruler::ExtraDown()
2218 void Ruler::Activate()
2222 // update positionlines - draw is delayed
2223 mnUpdateFlags
|= RULER_UPDATE_LINES
;
2224 Invalidate(InvalidateFlags::NoErase
);
2227 void Ruler::Deactivate()
2229 // clear positionlines
2230 Invalidate(InvalidateFlags::NoErase
);
2235 bool Ruler::StartDocDrag( const MouseEvent
& rMEvt
, RulerType eDragType
)
2239 Point aMousePos
= rMEvt
.GetPosPixel();
2240 sal_uInt16 nMouseClicks
= rMEvt
.GetClicks();
2241 sal_uInt16 nMouseModifier
= rMEvt
.GetModifier();
2242 RulerSelection aHitTest
;
2244 if(eDragType
!= RulerType::DontKnow
)
2245 aHitTest
.bExpandTest
= true;
2250 if (!IsReallyVisible())
2252 // set mpData for ImplDocHitTest()
2256 Invalidate(InvalidateFlags::NoErase
);
2259 if ( nMouseClicks
== 1 )
2261 if ( ImplDocHitTest( aMousePos
, eDragType
, &aHitTest
) )
2263 PointerStyle aPtr
= PointerStyle::Arrow
;
2265 if ( aHitTest
.bSize
)
2267 if ( mnWinStyle
& WB_HORZ
)
2268 aPtr
= PointerStyle::ESize
;
2270 aPtr
= PointerStyle::SSize
;
2272 else if ( aHitTest
.bSizeBar
)
2274 if ( mnWinStyle
& WB_HORZ
)
2275 aPtr
= PointerStyle::HSizeBar
;
2277 aPtr
= PointerStyle::VSizeBar
;
2280 return ImplStartDrag( &aHitTest
, nMouseModifier
);
2283 else if ( nMouseClicks
== 2 )
2285 if ( ImplDocHitTest( aMousePos
, eDragType
, &aHitTest
) )
2287 mnDragPos
= aHitTest
.nPos
;
2288 mnDragAryPos
= aHitTest
.nAryPos
;
2303 void Ruler::CancelDrag()
2307 ImplDrag( Point( -1, -1 ) );
2312 RulerType
Ruler::GetType( const Point
& rPos
, sal_uInt16
* pAryPos
)
2314 RulerSelection aHitTest
;
2317 if ( IsReallyVisible() && mbFormat
)
2319 Invalidate(InvalidateFlags::NoErase
);
2322 (void)ImplHitTest(rPos
, &aHitTest
);
2326 *pAryPos
= aHitTest
.nAryPos
;
2327 return aHitTest
.eType
;
2330 void Ruler::SetWinPos( tools::Long nNewOff
, tools::Long nNewWidth
)
2332 // should widths be automatically calculated
2334 mbAutoWinWidth
= true;
2336 mbAutoWinWidth
= false;
2339 mnWinWidth
= nNewWidth
;
2343 void Ruler::SetPagePos( tools::Long nNewOff
, tools::Long nNewWidth
)
2345 // should we do anything?
2346 if ( (mpData
->nPageOff
== nNewOff
) && (mpData
->nPageWidth
== nNewWidth
) )
2349 // should widths be automatically calculated
2351 mpData
->bAutoPageWidth
= true;
2353 mpData
->bAutoPageWidth
= false;
2355 mpData
->nPageOff
= nNewOff
;
2356 mpData
->nPageWidth
= nNewWidth
;
2360 void Ruler::SetBorderPos( tools::Long nOff
)
2362 if ( mnWinStyle
& WB_BORDER
)
2364 if ( mnBorderOff
!= nOff
)
2368 if ( IsReallyVisible() && IsUpdateMode() )
2369 Invalidate(InvalidateFlags::NoErase
);
2374 void Ruler::SetUnit( FieldUnit eNewUnit
)
2376 if ( meUnit
== eNewUnit
)
2383 mnUnitIndex
= RULER_UNIT_MM
;
2386 mnUnitIndex
= RULER_UNIT_CM
;
2389 mnUnitIndex
= RULER_UNIT_M
;
2392 mnUnitIndex
= RULER_UNIT_KM
;
2394 case FieldUnit::INCH
:
2395 mnUnitIndex
= RULER_UNIT_INCH
;
2397 case FieldUnit::FOOT
:
2398 mnUnitIndex
= RULER_UNIT_FOOT
;
2400 case FieldUnit::MILE
:
2401 mnUnitIndex
= RULER_UNIT_MILE
;
2403 case FieldUnit::POINT
:
2404 mnUnitIndex
= RULER_UNIT_POINT
;
2406 case FieldUnit::PICA
:
2407 mnUnitIndex
= RULER_UNIT_PICA
;
2409 case FieldUnit::CHAR
:
2410 mnUnitIndex
= RULER_UNIT_CHAR
;
2412 case FieldUnit::LINE
:
2413 mnUnitIndex
= RULER_UNIT_LINE
;
2416 SAL_WARN( "svtools.control", "Ruler::SetUnit() - Wrong Unit" );
2420 maMapMode
.SetMapUnit( aImplRulerUnitTab
[mnUnitIndex
].eMapUnit
);
2424 void Ruler::SetZoom( const Fraction
& rNewZoom
)
2426 DBG_ASSERT( rNewZoom
.GetNumerator(), "Ruler::SetZoom() with scale 0 is not allowed" );
2428 if ( maZoom
!= rNewZoom
)
2431 maMapMode
.SetScaleX( maZoom
);
2432 maMapMode
.SetScaleY( maZoom
);
2437 void Ruler::SetExtraType( RulerExtra eNewExtraType
, sal_uInt16 nStyle
)
2439 if ( mnWinStyle
& WB_EXTRAFIELD
)
2441 meExtraType
= eNewExtraType
;
2442 mnExtraStyle
= nStyle
;
2443 if (IsReallyVisible() && IsUpdateMode())
2448 void Ruler::SetNullOffset( tools::Long nPos
)
2450 if ( mpData
->nNullOff
!= nPos
)
2452 mpData
->nNullVirOff
+= nPos
- mpData
->nNullOff
;
2453 mpData
->nNullOff
= nPos
;
2458 void Ruler::SetLeftFrameMargin( tools::Long nPos
)
2460 if ( mpData
->nLeftFrameMargin
!= nPos
)
2462 mpData
->nLeftFrameMargin
= nPos
;
2467 void Ruler::SetRightFrameMargin( tools::Long nPos
)
2469 if ( mpData
->nRightFrameMargin
!= nPos
)
2471 mpData
->nRightFrameMargin
= nPos
;
2476 void Ruler::SetMargin1( tools::Long nPos
, RulerMarginStyle nMarginStyle
)
2478 if ( (mpData
->nMargin1
!= nPos
) || (mpData
->nMargin1Style
!= nMarginStyle
) )
2480 mpData
->nMargin1
= nPos
;
2481 mpData
->nMargin1Style
= nMarginStyle
;
2486 void Ruler::SetMargin2( tools::Long nPos
, RulerMarginStyle nMarginStyle
)
2488 DBG_ASSERT( (nPos
>= mpData
->nMargin1
) ||
2489 (mpData
->nMargin1Style
& RulerMarginStyle::Invisible
) ||
2490 (mpData
->nMargin2Style
& RulerMarginStyle::Invisible
),
2491 "Ruler::SetMargin2() - Margin2 < Margin1" );
2493 if ( (mpData
->nMargin2
!= nPos
) || (mpData
->nMargin2Style
!= nMarginStyle
) )
2495 mpData
->nMargin2
= nPos
;
2496 mpData
->nMargin2Style
= nMarginStyle
;
2501 void Ruler::SetLines( sal_uInt32 aLineArraySize
, const RulerLine
* pLineArray
)
2503 // To determine if what has changed
2504 if ( mpData
->pLines
.size() == aLineArraySize
)
2506 sal_uInt32 i
= aLineArraySize
;
2507 vector
<RulerLine
>::const_iterator aItr1
= mpData
->pLines
.begin();
2508 const RulerLine
* pAry2
= pLineArray
;
2511 if ( aItr1
->nPos
!= pAry2
->nPos
)
2521 // New values and new share issue
2523 bMustUpdate
= IsReallyVisible() && IsUpdateMode();
2527 Invalidate(InvalidateFlags::NoErase
);
2530 if ( !aLineArraySize
|| !pLineArray
)
2532 if ( mpData
->pLines
.empty() )
2534 mpData
->pLines
.clear();
2538 if ( mpData
->pLines
.size() != aLineArraySize
)
2540 mpData
->pLines
.resize(aLineArraySize
);
2543 std::copy( pLineArray
,
2544 pLineArray
+ aLineArraySize
,
2545 mpData
->pLines
.begin() );
2548 Invalidate(InvalidateFlags::NoErase
);
2552 void Ruler::SetBorders( sal_uInt32 aBorderArraySize
, const RulerBorder
* pBorderArray
)
2554 if ( !aBorderArraySize
|| !pBorderArray
)
2556 if ( mpData
->pBorders
.empty() )
2558 mpData
->pBorders
.clear();
2562 if ( mpData
->pBorders
.size() != aBorderArraySize
)
2564 mpData
->pBorders
.resize(aBorderArraySize
);
2568 sal_uInt32 i
= aBorderArraySize
;
2569 const RulerBorder
* pAry1
= mpData
->pBorders
.data();
2570 const RulerBorder
* pAry2
= pBorderArray
;
2573 if ( (pAry1
->nPos
!= pAry2
->nPos
) ||
2574 (pAry1
->nWidth
!= pAry2
->nWidth
) ||
2575 (pAry1
->nStyle
!= pAry2
->nStyle
) )
2584 std::copy( pBorderArray
,
2585 pBorderArray
+ aBorderArraySize
,
2586 mpData
->pBorders
.begin() );
2592 void Ruler::SetIndents( sal_uInt32 aIndentArraySize
, const RulerIndent
* pIndentArray
)
2595 if ( !aIndentArraySize
|| !pIndentArray
)
2597 if ( mpData
->pIndents
.empty() )
2599 mpData
->pIndents
.clear();
2603 if ( mpData
->pIndents
.size() != aIndentArraySize
)
2605 mpData
->pIndents
.resize(aIndentArraySize
);
2609 sal_uInt32 i
= aIndentArraySize
;
2610 const RulerIndent
* pAry1
= mpData
->pIndents
.data();
2611 const RulerIndent
* pAry2
= pIndentArray
;
2614 if ( (pAry1
->nPos
!= pAry2
->nPos
) ||
2615 (pAry1
->nStyle
!= pAry2
->nStyle
) )
2625 std::copy( pIndentArray
,
2626 pIndentArray
+ aIndentArraySize
,
2627 mpData
->pIndents
.begin() );
2633 void Ruler::SetTabs( sal_uInt32 aTabArraySize
, const RulerTab
* pTabArray
)
2635 if ( aTabArraySize
== 0 || pTabArray
== nullptr )
2637 if ( mpData
->pTabs
.empty() )
2639 mpData
->pTabs
.clear();
2643 if ( mpData
->pTabs
.size() != aTabArraySize
)
2645 mpData
->pTabs
.resize(aTabArraySize
);
2649 sal_uInt32 i
= aTabArraySize
;
2650 vector
<RulerTab
>::iterator aTabIterator
= mpData
->pTabs
.begin();
2651 const RulerTab
* pInputArray
= pTabArray
;
2654 RulerTab
& aCurrent
= *aTabIterator
;
2655 if ( aCurrent
.nPos
!= pInputArray
->nPos
||
2656 aCurrent
.nStyle
!= pInputArray
->nStyle
)
2667 std::copy(pTabArray
, pTabArray
+ aTabArraySize
, mpData
->pTabs
.begin());
2673 const std::vector
<RulerTab
>& Ruler::GetTabs() const
2675 return mpData
->pTabs
;
2678 void Ruler::SetStyle( WinBits nStyle
)
2680 if ( mnWinStyle
!= nStyle
)
2682 mnWinStyle
= nStyle
;
2683 ImplInitExtraField( true );
2687 void Ruler::DrawTab(vcl::RenderContext
& rRenderContext
, const Color
&rFillColor
, const Point
& rPos
, sal_uInt16 nStyle
)
2690 sal_uInt16 nTabStyle
= nStyle
& (RULER_TAB_STYLE
| RULER_TAB_RTL
);
2692 rRenderContext
.Push(PushFlags::LINECOLOR
| PushFlags::FILLCOLOR
);
2693 rRenderContext
.SetLineColor();
2694 rRenderContext
.SetFillColor(rFillColor
);
2695 ImplCenterTabPos(aPos
, nTabStyle
);
2696 ImplDrawRulerTab(rRenderContext
, aPos
, nTabStyle
, nStyle
);
2697 rRenderContext
.Pop();
2700 void Ruler::SetTextRTL(bool bRTL
)
2702 if(mpData
->bTextRTL
!= bRTL
)
2704 mpData
->bTextRTL
= bRTL
;
2705 if ( IsReallyVisible() && IsUpdateMode() )
2706 ImplInitExtraField( true );
2711 tools::Long
Ruler::GetPageOffset() const
2713 return mpData
->nPageOff
;
2716 tools::Long
Ruler::GetNullOffset() const
2718 return mpData
->nNullOff
;
2721 tools::Long
Ruler::GetMargin1() const
2723 return mpData
->nMargin1
;
2726 tools::Long
Ruler::GetMargin2() const
2728 return mpData
->nMargin2
;
2732 bool Ruler::GetTextRTL() const
2734 return mpData
->bTextRTL
;
2737 const RulerUnitData
& Ruler::GetCurrentRulerUnit() const
2739 return aImplRulerUnitTab
[mnUnitIndex
];
2742 void Ruler::DrawTicks()
2745 Invalidate(InvalidateFlags::NoErase
);
2748 uno::Reference
< XAccessible
> Ruler::CreateAccessible()
2750 vcl::Window
* pParent
= GetAccessibleParentWindow();
2751 OSL_ENSURE( pParent
, "-SvxRuler::CreateAccessible(): No Parent!" );
2752 uno::Reference
< XAccessible
> xAccParent
= pParent
->GetAccessible();
2753 if( xAccParent
.is() )
2755 // MT: Fixed compiler issue because the address from a temporary object was used.
2756 // BUT: Should it really be a Pointer, instead of const&???
2758 if ( mnWinStyle
& WB_HORZ
)
2760 aStr
= SvtResId(STR_SVT_ACC_RULER_HORZ_NAME
);
2764 aStr
= SvtResId(STR_SVT_ACC_RULER_VERT_NAME
);
2766 mxAccContext
= new SvtRulerAccessible( xAccParent
, *this, aStr
);
2767 SetAccessible(mxAccContext
.get());
2768 return mxAccContext
.get();
2771 return uno::Reference
< XAccessible
>();
2774 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */