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"
38 using namespace ::com::sun::star
;
39 using namespace ::com::sun::star::uno
;
40 using namespace ::com::sun::star::accessibility
;
43 #define RULER_RESIZE_OFF 4
44 #define RULER_MIN_SIZE 3
46 #define RULER_VAR_SIZE 8
48 #define RULER_UPDATE_LINES 0x01
50 #define RULER_CLIP 150
52 #define RULER_UNIT_MM 0
53 #define RULER_UNIT_CM 1
54 #define RULER_UNIT_M 2
55 #define RULER_UNIT_KM 3
56 #define RULER_UNIT_INCH 4
57 #define RULER_UNIT_FOOT 5
58 #define RULER_UNIT_MILE 6
59 #define RULER_UNIT_POINT 7
60 #define RULER_UNIT_PICA 8
61 #define RULER_UNIT_CHAR 9
62 #define RULER_UNIT_LINE 10
63 #define RULER_UNIT_COUNT 11
68 * Pre-calculates glyph items for rText on rRenderContext. Subsequent calls
69 * avoid the calculation and just return a pointer to rTextGlyphs.
71 SalLayoutGlyphs
* lcl_GetRulerTextGlyphs(const vcl::RenderContext
& rRenderContext
, const OUString
& rText
,
72 SalLayoutGlyphs
& rTextGlyphs
)
74 if (rTextGlyphs
.IsValid())
75 // Use pre-calculated result.
78 // Calculate glyph items.
80 std::unique_ptr
<SalLayout
> pLayout
= rRenderContext
.ImplLayout(
81 rText
, 0, rText
.getLength(), Point(0, 0), 0, {}, {}, SalLayoutFlags::GlyphItemsOnly
);
85 // Remember the calculation result.
86 rTextGlyphs
= pLayout
->GetGlyphs();
97 std::vector
<RulerLine
> pLines
;
98 std::vector
<RulerBorder
> pBorders
;
99 std::vector
<RulerIndent
> pIndents
;
100 std::vector
<RulerTab
> pTabs
;
102 tools::Long nNullVirOff
;
103 tools::Long nRulVirOff
;
104 tools::Long nRulWidth
;
105 tools::Long nPageOff
;
106 tools::Long nPageWidth
;
107 tools::Long nNullOff
;
108 tools::Long nMargin1
;
109 tools::Long nMargin2
;
110 // In this context, "frame margin" means paragraph margins (indents)
111 tools::Long nLeftFrameMargin
;
112 tools::Long nRightFrameMargin
;
113 RulerMarginStyle nMargin1Style
;
114 RulerMarginStyle nMargin2Style
;
122 ImplRulerData::ImplRulerData() :
131 nLeftFrameMargin (0),
132 nRightFrameMargin (0),
133 nMargin1Style (RulerMarginStyle::NONE
),
134 nMargin2Style (RulerMarginStyle::NONE
),
135 bAutoPageWidth (true), // Page width == EditWin width
140 const RulerUnitData aImplRulerUnitTab
[RULER_UNIT_COUNT
] =
142 { MapUnit::Map100thMM
, 100, 25.0, 25.0, 50.0, 100.0, " mm" }, // MM
143 { MapUnit::Map100thMM
, 1000, 100.0, 500.0, 1000.0, 1000.0, " cm" }, // CM
144 { MapUnit::MapMM
, 1000, 10.0, 250.0, 500.0, 1000.0, " m" }, // M
145 { MapUnit::MapCM
, 100000, 12500.0, 25000.0, 50000.0, 100000.0, " km" }, // KM
146 { MapUnit::Map1000thInch
, 1000, 62.5, 125.0, 500.0, 1000.0, "\"" }, // INCH
147 { MapUnit::Map100thInch
, 1200, 120.0, 120.0, 600.0, 1200.0, "'" }, // FOOT
148 { MapUnit::Map10thInch
, 633600, 63360.0, 63360.0, 316800.0, 633600.0, " miles" }, // MILE
149 { MapUnit::MapPoint
, 1, 12.0, 12.0, 12.0, 36.0, " pt" }, // POINT
150 { MapUnit::Map100thMM
, 423, 423.0, 423.0, 423.0, 846.0, " pc" }, // PICA
151 { MapUnit::Map100thMM
, 371, 371.0, 371.0, 371.0, 743.0, " ch" }, // CHAR
152 { MapUnit::Map100thMM
, 551, 551.0, 551.0, 551.0, 1102.0, " li" } // LINE
155 static RulerTabData ruler_tab
=
157 0, // DPIScaleFactor to be set
158 7, // ruler_tab_width
159 6, // ruler_tab_height
160 2, // ruler_tab_height2
161 2, // ruler_tab_width2
162 8, // ruler_tab_cwidth
163 4, // ruler_tab_cwidth2
164 4, // ruler_tab_cwidth3
165 2, // ruler_tab_cwidth4
166 4, // ruler_tab_dheight
167 1, // ruler_tab_dheight2
168 5, // ruler_tab_dwidth
169 3, // ruler_tab_dwidth2
170 3, // ruler_tab_dwidth3
171 1, // ruler_tab_dwidth4
172 5 // ruler_tab_textoff
175 void Ruler::ImplInit( WinBits nWinBits
)
177 // Set default WinBits
178 if ( !(nWinBits
& WB_VERT
) )
182 // RTL: no UI mirroring for horizontal rulers, because
183 // the document is also not mirrored
187 // Initialize variables
188 mnWinStyle
= nWinBits
; // Window-Style
189 mnBorderOff
= 0; // Border-Offset
190 mnWinOff
= 0; // EditWinOffset
191 mnWinWidth
= 0; // EditWinWidth
192 mnWidth
= 0; // Window width
193 mnHeight
= 0; // Window height
194 mnVirOff
= 0; // Offset of VirtualDevice from top-left corner
195 mnVirWidth
= 0; // width or height from VirtualDevice
196 mnVirHeight
= 0; // height of width from VirtualDevice
197 mnDragPos
= 0; // Drag-Position (Null point)
198 mnDragAryPos
= 0; // Drag-Array-Index
199 mnDragSize
= RulerDragSize::Move
; // Did size change at dragging
200 mnDragModifier
= 0; // Modifier key at dragging
201 mnExtraStyle
= 0; // Style of Extra field
204 mbCalc
= true; // Should recalculate page width
205 mbFormat
= true; // Should redraw
206 mbDrag
= false; // Currently at dragging
207 mbDragDelete
= false; // Has mouse left the dragging area
208 mbDragCanceled
= false; // Dragging cancelled?
209 mbAutoWinWidth
= true; // EditWinWidth == RulerWidth
210 mbActive
= true; // Is ruler active
211 mnUpdateFlags
= 0; // What needs to be updated
212 mpData
= mpSaveData
.get(); // Pointer to normal data
213 meExtraType
= RulerExtra::DontKnow
; // What is in extra field
214 meDragType
= RulerType::DontKnow
; // Which element is dragged
217 mnUnitIndex
= RULER_UNIT_CM
;
218 meUnit
= FieldUnit::CM
;
219 maZoom
= Fraction( 1, 1 );
221 // Recalculate border widths
222 if ( nWinBits
& WB_BORDER
)
228 ImplInitSettings( true, true, true );
230 // Setup the default size
231 tools::Rectangle aRect
;
232 GetOutDev()->GetTextBoundRect( aRect
, u
"0123456789"_ustr
);
233 tools::Long nDefHeight
= aRect
.GetHeight() + RULER_OFF
* 2 + ruler_tab
.textoff
* 2 + mnBorderWidth
;
236 if ( nWinBits
& WB_HORZ
)
237 aDefSize
.setHeight( nDefHeight
);
239 aDefSize
.setWidth( nDefHeight
);
240 SetOutputSizePixel( aDefSize
);
241 SetType(WindowType::RULER
);
244 Ruler::Ruler( vcl::Window
* pParent
, WinBits nWinStyle
) :
245 Window( pParent
, nWinStyle
& WB_3DLOOK
),
246 maVirDev( VclPtr
<VirtualDevice
>::Create(*GetOutDev()) ),
247 maMapMode( MapUnit::Map100thMM
),
248 mpSaveData(new ImplRulerData
),
250 mpDragData(new ImplRulerData
)
252 // Check to see if the ruler constructor has
253 // already been called before otherwise
254 // we end up with over-scaled elements
255 if (ruler_tab
.DPIScaleFactor
== 0)
257 ruler_tab
.DPIScaleFactor
= GetDPIScaleFactor();
258 ruler_tab
.width
*= ruler_tab
.DPIScaleFactor
;
259 ruler_tab
.height
*= ruler_tab
.DPIScaleFactor
;
260 ruler_tab
.height2
*= ruler_tab
.DPIScaleFactor
;
261 ruler_tab
.width2
*= ruler_tab
.DPIScaleFactor
;
262 ruler_tab
.cwidth
*= ruler_tab
.DPIScaleFactor
;
263 ruler_tab
.cwidth2
*= ruler_tab
.DPIScaleFactor
;
264 ruler_tab
.cwidth3
*= ruler_tab
.DPIScaleFactor
;
265 ruler_tab
.cwidth4
*= ruler_tab
.DPIScaleFactor
;
266 ruler_tab
.dheight
*= ruler_tab
.DPIScaleFactor
;
267 ruler_tab
.dheight2
*= ruler_tab
.DPIScaleFactor
;
268 ruler_tab
.dwidth
*= ruler_tab
.DPIScaleFactor
;
269 ruler_tab
.dwidth2
*= ruler_tab
.DPIScaleFactor
;
270 ruler_tab
.dwidth3
*= ruler_tab
.DPIScaleFactor
;
271 ruler_tab
.dwidth4
*= ruler_tab
.DPIScaleFactor
;
272 ruler_tab
.textoff
*= ruler_tab
.DPIScaleFactor
;
276 ImplInit( nWinStyle
);
284 void Ruler::dispose()
288 mxAccContext
.clear();
292 void Ruler::ImplVDrawLine(vcl::RenderContext
& rRenderContext
, tools::Long nX1
, tools::Long nY1
, tools::Long nX2
, tools::Long nY2
)
294 if ( nX1
< -RULER_CLIP
)
297 if ( nX2
< -RULER_CLIP
)
300 tools::Long nClip
= mnVirWidth
+ RULER_CLIP
;
308 if ( mnWinStyle
& WB_HORZ
)
309 rRenderContext
.DrawLine( Point( nX1
, nY1
), Point( nX2
, nY2
) );
311 rRenderContext
.DrawLine( Point( nY1
, nX1
), Point( nY2
, nX2
) );
314 void Ruler::ImplVDrawRect(vcl::RenderContext
& rRenderContext
, tools::Long nX1
, tools::Long nY1
, tools::Long nX2
, tools::Long nY2
)
316 if ( nX1
< -RULER_CLIP
)
319 if ( nX2
< -RULER_CLIP
)
322 tools::Long nClip
= mnVirWidth
+ RULER_CLIP
;
330 if ( mnWinStyle
& WB_HORZ
)
331 rRenderContext
.DrawRect(tools::Rectangle(nX1
, nY1
, nX2
, nY2
));
333 rRenderContext
.DrawRect(tools::Rectangle(nY1
, nX1
, nY2
, nX2
));
336 void Ruler::ImplVDrawText(vcl::RenderContext
& rRenderContext
, tools::Long nX
, tools::Long nY
, const OUString
& rText
, tools::Long nMin
, tools::Long nMax
)
338 tools::Rectangle aRect
;
339 SalLayoutGlyphs
* pTextLayout
340 = lcl_GetRulerTextGlyphs(rRenderContext
, rText
, maTextGlyphs
[rText
]);
341 rRenderContext
.GetTextBoundRect(aRect
, rText
, 0, 0, -1, 0, {}, {}, pTextLayout
);
343 tools::Long nShiftX
= ( aRect
.GetWidth() / 2 ) + aRect
.Left();
344 tools::Long nShiftY
= ( aRect
.GetHeight() / 2 ) + aRect
.Top();
346 if ( (nX
> -RULER_CLIP
) && (nX
< mnVirWidth
+ RULER_CLIP
) && ( nX
< nMax
- nShiftX
) && ( nX
> nMin
+ nShiftX
) )
348 if ( mnWinStyle
& WB_HORZ
)
349 rRenderContext
.DrawText(Point(nX
- nShiftX
, nY
- nShiftY
), rText
, 0, -1, nullptr,
350 nullptr, pTextLayout
);
352 rRenderContext
.DrawText(Point(nY
- nShiftX
, nX
- nShiftY
), rText
, 0, -1, nullptr,
353 nullptr, pTextLayout
);
357 void Ruler::ImplInvertLines(vcl::RenderContext
& rRenderContext
)
360 if (mpData
->pLines
.empty() || !mbActive
|| mbDrag
|| mbFormat
|| (mnUpdateFlags
& RULER_UPDATE_LINES
) )
363 tools::Long nNullWinOff
= mpData
->nNullVirOff
+ mnVirOff
;
364 tools::Long nRulX1
= mpData
->nRulVirOff
+ mnVirOff
;
365 tools::Long nRulX2
= nRulX1
+ mpData
->nRulWidth
;
366 tools::Long nY
= (RULER_OFF
* 2) + mnVirHeight
- 1;
368 // Calculate rectangle
369 tools::Rectangle aRect
;
370 if (mnWinStyle
& WB_HORZ
)
371 aRect
.SetBottom( nY
);
373 aRect
.SetRight( nY
);
376 for (const RulerLine
& rLine
: mpData
->pLines
)
378 const tools::Long n
= rLine
.nPos
+ nNullWinOff
;
379 if ((n
>= nRulX1
) && (n
< nRulX2
))
381 if (mnWinStyle
& WB_HORZ
)
389 aRect
.SetBottom( n
);
391 tools::Rectangle aTempRect
= aRect
;
393 if (mnWinStyle
& WB_HORZ
)
394 aTempRect
.SetBottom( RULER_OFF
- 1 );
396 aTempRect
.SetRight( RULER_OFF
- 1 );
398 rRenderContext
.Erase(aTempRect
);
400 if (mnWinStyle
& WB_HORZ
)
402 aTempRect
.SetBottom( aRect
.Bottom() );
403 aTempRect
.SetTop( aTempRect
.Bottom() - RULER_OFF
+ 1 );
407 aTempRect
.SetRight( aRect
.Right() );
408 aTempRect
.SetLeft( aTempRect
.Right() - RULER_OFF
+ 1 );
410 rRenderContext
.Erase(aTempRect
);
411 GetOutDev()->Invert(aRect
);
417 void Ruler::ImplDrawTicks(vcl::RenderContext
& rRenderContext
, tools::Long nMin
, tools::Long nMax
, tools::Long nStart
, tools::Long nTop
, tools::Long nBottom
)
419 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
420 double nCenter
= nTop
+ ((nBottom
- nTop
) / 2);
422 tools::Long nTickLength3
= (nBottom
- nTop
) * 0.5;
423 tools::Long nTickLength2
= nTickLength3
* 0.66;
424 tools::Long nTickLength1
= nTickLength2
* 0.66;
426 tools::Long nScale
= ruler_tab
.DPIScaleFactor
;
427 tools::Long DPIOffset
= nScale
- 1;
429 double nTick4
= aImplRulerUnitTab
[mnUnitIndex
].nTick4
;
431 double nTickCount
= aImplRulerUnitTab
[mnUnitIndex
].nTick1
/ nScale
;
432 double nTickUnit
= 0;
433 tools::Long nTickWidth
;
434 bool bNoTicks
= false;
436 Size aPixSize
= rRenderContext
.LogicToPixel(Size(nTick4
, nTick4
), maMapMode
);
438 if (mnUnitIndex
== RULER_UNIT_CHAR
)
440 if (mnCharWidth
== 0)
442 nTick4
= mnCharWidth
* 2;
443 nTick2
= mnCharWidth
;
444 nTickCount
= mnCharWidth
;
445 nTickUnit
= mnCharWidth
;
447 else if (mnUnitIndex
== RULER_UNIT_LINE
)
449 if (mnLineHeight
== 0)
451 nTick4
= mnLineHeight
* 2;
452 nTick2
= mnLineHeight
;
453 nTickUnit
= mnLineHeight
;
454 nTickCount
= mnLineHeight
;
457 if (mnWinStyle
& WB_HORZ
)
459 nTickWidth
= aPixSize
.Width();
463 vcl::Font aFont
= rRenderContext
.GetFont();
464 if (mnWinStyle
& WB_RIGHT_ALIGNED
)
465 aFont
.SetOrientation(2700_deg10
);
467 aFont
.SetOrientation(900_deg10
);
468 rRenderContext
.SetFont(aFont
);
469 nTickWidth
= aPixSize
.Height();
472 tools::Long nMaxWidth
= rRenderContext
.PixelToLogic(Size(mpData
->nPageWidth
, 0), maMapMode
).Width();
474 nMaxWidth
= -nMaxWidth
;
476 if ((mnUnitIndex
== RULER_UNIT_CHAR
) || (mnUnitIndex
== RULER_UNIT_LINE
))
477 nMaxWidth
/= nTickUnit
;
479 nMaxWidth
/= aImplRulerUnitTab
[mnUnitIndex
].nTickUnit
;
481 OUString aNumString
= OUString::number(nMaxWidth
);
482 tools::Long nTxtWidth
= rRenderContext
.GetTextWidth( aNumString
);
483 const tools::Long nTextOff
= 4;
485 // Determine the number divider for ruler drawn numbers - means which numbers
486 // should be shown on the ruler and which should be skipped because the ruler
487 // is not big enough to draw them
488 if (nTickWidth
< nTxtWidth
+ nTextOff
)
490 // Calculate the scale of the ruler
491 tools::Long nMulti
= 1;
492 tools::Long nOrgTick4
= nTick4
;
494 while (nTickWidth
< nTxtWidth
+ nTextOff
)
496 tools::Long nOldMulti
= nMulti
;
499 else if (nMulti
< 10)
501 else if (nMulti
< 100)
503 else if (nMulti
< 1000)
508 // Overflow - in this case don't draw ticks and exit
509 if (nMulti
< nOldMulti
)
515 nTick4
= nOrgTick4
* nMulti
;
516 aPixSize
= rRenderContext
.LogicToPixel(Size(nTick4
, nTick4
), maMapMode
);
517 if (mnWinStyle
& WB_HORZ
)
518 nTickWidth
= aPixSize
.Width();
520 nTickWidth
= aPixSize
.Height();
526 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
536 if ((mnUnitIndex
!= RULER_UNIT_CHAR
) && (mnUnitIndex
!= RULER_UNIT_LINE
))
538 nTick2
= aImplRulerUnitTab
[mnUnitIndex
].nTick2
;
539 nTick3
= aImplRulerUnitTab
[mnUnitIndex
].nTick3
;
544 nTickGapSize
= rRenderContext
.LogicToPixel(Size(nTickCount
, nTickCount
), maMapMode
);
545 tools::Long nTickGap1
= mnWinStyle
& WB_HORZ
? nTickGapSize
.Width() : nTickGapSize
.Height();
546 nTickGapSize
= rRenderContext
.LogicToPixel(Size(nTick2
, nTick2
), maMapMode
);
547 tools::Long nTickGap2
= mnWinStyle
& WB_HORZ
? nTickGapSize
.Width() : nTickGapSize
.Height();
548 nTickGapSize
= rRenderContext
.LogicToPixel(Size(nTick3
, nTick3
), maMapMode
);
549 tools::Long nTickGap3
= mnWinStyle
& WB_HORZ
? nTickGapSize
.Width() : nTickGapSize
.Height();
551 while (((nStart
- n
) >= nMin
) || ((nStart
+ n
) <= nMax
))
558 // 0 is only painted when Margin1 is not equal to zero
559 if ((mpData
->nMargin1Style
& RulerMarginStyle::Invisible
) || (mpData
->nMargin1
!= 0))
562 ImplVDrawText(rRenderContext
, nStart
, nCenter
, aNumString
);
568 aPixSize
= rRenderContext
.LogicToPixel(Size(nTick
, nTick
), maMapMode
);
570 if (mnWinStyle
& WB_HORZ
)
571 n
= aPixSize
.Width();
573 n
= aPixSize
.Height();
575 // Tick4 - Output (Text)
576 double aStep
= nTick
/ nTick4
;
577 double aRest
= std::abs(aStep
- std::floor(aStep
));
578 double nAcceptanceDelta
= 0.0001;
579 rRenderContext
.SetFillColor(rStyleSettings
.GetShadowColor());
581 if (aRest
< nAcceptanceDelta
)
583 if ((mnUnitIndex
== RULER_UNIT_CHAR
) || (mnUnitIndex
== RULER_UNIT_LINE
))
584 aNumString
= OUString::number(nTick
/ nTickUnit
);
586 aNumString
= OUString::number(nTick
/ aImplRulerUnitTab
[mnUnitIndex
].nTickUnit
);
588 tools::Long nHorizontalLocation
= nStart
+ n
;
589 ImplVDrawText(rRenderContext
, nHorizontalLocation
, nCenter
, aNumString
, nMin
, nMax
);
591 if (nMin
< nHorizontalLocation
&& nHorizontalLocation
< nMax
)
593 ImplVDrawRect(rRenderContext
, nHorizontalLocation
, nBottom
- 1 * nScale
, nHorizontalLocation
+ DPIOffset
, nBottom
);
594 ImplVDrawRect(rRenderContext
, nHorizontalLocation
, nTop
, nHorizontalLocation
+ DPIOffset
, nTop
+ 1 * nScale
);
597 nHorizontalLocation
= nStart
- n
;
598 ImplVDrawText(rRenderContext
, nHorizontalLocation
, nCenter
, aNumString
, nMin
, nMax
);
600 if (nMin
< nHorizontalLocation
&& nHorizontalLocation
< nMax
)
602 ImplVDrawRect(rRenderContext
, nHorizontalLocation
, nBottom
,
603 nHorizontalLocation
+ DPIOffset
, nBottom
- 1 * nScale
);
604 ImplVDrawRect(rRenderContext
, nHorizontalLocation
, nTop
,
605 nHorizontalLocation
+ DPIOffset
, nTop
+ 1 * nScale
);
608 // Tick/Tick2 - Output (Strokes)
611 tools::Long nTickLength
= nTickLength1
;
613 aStep
= (nTick
/ nTick2
);
614 aRest
= std::abs(aStep
- std::floor(aStep
));
615 if (aRest
< nAcceptanceDelta
)
616 nTickLength
= nTickLength2
;
618 aStep
= (nTick
/ nTick3
);
619 aRest
= std::abs(aStep
- std::floor(aStep
));
620 if (aRest
< nAcceptanceDelta
)
621 nTickLength
= nTickLength3
;
623 if ((nTickLength
== nTickLength1
&& nTickGap1
> 6) ||
624 (nTickLength
== nTickLength2
&& nTickGap2
> 6) ||
625 (nTickLength
== nTickLength3
&& nTickGap3
> 6))
627 tools::Long nT1
= nCenter
- (nTickLength
/ 2.0);
628 tools::Long nT2
= nT1
+ nTickLength
- 1;
634 ImplVDrawRect(rRenderContext
, nT
, nT1
, nT
+ DPIOffset
, nT2
);
637 ImplVDrawRect(rRenderContext
, nT
, nT1
, nT
+ DPIOffset
, nT2
);
645 void Ruler::ImplDrawBorders(vcl::RenderContext
& rRenderContext
, tools::Long nMin
, tools::Long nMax
, tools::Long nVirTop
, tools::Long nVirBottom
)
647 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
654 for (std::vector
<RulerBorder
>::size_type i
= 0; i
< mpData
->pBorders
.size(); i
++)
656 if (mpData
->pBorders
[i
].nStyle
& RulerBorderStyle::Invisible
)
659 n1
= mpData
->pBorders
[i
].nPos
+ mpData
->nNullVirOff
;
660 n2
= n1
+ mpData
->pBorders
[i
].nWidth
;
662 if (((n1
>= nMin
) && (n1
<= nMax
)) || ((n2
>= nMin
) && (n2
<= nMax
)))
666 rRenderContext
.SetLineColor();
667 rRenderContext
.SetFillColor(rStyleSettings
.GetFaceColor());
668 ImplVDrawRect(rRenderContext
, n1
, nVirTop
, n2
, nVirBottom
);
670 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
671 ImplVDrawLine(rRenderContext
, n1
+ 1, nVirTop
, n1
+ 1, nVirBottom
);
672 ImplVDrawLine(rRenderContext
, n1
, nVirTop
, n2
, nVirTop
);
674 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
675 ImplVDrawLine(rRenderContext
, n1
, nVirTop
, n1
, nVirBottom
);
676 ImplVDrawLine(rRenderContext
, n1
, nVirBottom
, n2
, nVirBottom
);
677 ImplVDrawLine(rRenderContext
, n2
- 1, nVirTop
, n2
- 1, nVirBottom
);
679 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
680 ImplVDrawLine(rRenderContext
, n2
, nVirTop
, n2
, nVirBottom
);
682 if (mpData
->pBorders
[i
].nStyle
& RulerBorderStyle::Variable
)
684 if (n2
- n1
> RULER_VAR_SIZE
+ 4)
686 nTemp1
= n1
+ (((n2
- n1
+ 1) - RULER_VAR_SIZE
) / 2);
687 nTemp2
= nVirTop
+ (((nVirBottom
- nVirTop
+ 1) - RULER_VAR_SIZE
) / 2);
688 tools::Long nTemp3
= nTemp1
+ RULER_VAR_SIZE
- 1;
689 tools::Long nTemp4
= nTemp2
+ RULER_VAR_SIZE
- 1;
690 tools::Long nTempY
= nTemp2
;
692 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
693 while (nTempY
<= nTemp4
)
695 ImplVDrawLine(rRenderContext
, nTemp1
, nTempY
, nTemp3
, nTempY
);
700 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
701 while (nTempY
<= nTemp4
)
703 ImplVDrawLine(rRenderContext
, nTemp1
, nTempY
, nTemp3
, nTempY
);
709 if (mpData
->pBorders
[i
].nStyle
& RulerBorderStyle::Sizeable
)
711 if (n2
- n1
> RULER_VAR_SIZE
+ 10)
713 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
714 ImplVDrawLine(rRenderContext
, n1
+ 4, nVirTop
+ 3, n1
+ 4, nVirBottom
- 3);
715 ImplVDrawLine(rRenderContext
, n2
- 5, nVirTop
+ 3, n2
- 5, nVirBottom
- 3);
716 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
717 ImplVDrawLine(rRenderContext
, n1
+ 5, nVirTop
+ 3, n1
+ 5, nVirBottom
- 3);
718 ImplVDrawLine(rRenderContext
, n2
- 4, nVirTop
+ 3, n2
- 4, nVirBottom
- 3);
724 n
= n1
+ ((n2
- n1
) / 2);
725 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
727 ImplVDrawLine(rRenderContext
, n
- 1, nVirTop
, n
- 1, nVirBottom
);
728 ImplVDrawLine(rRenderContext
, n
+ 1, nVirTop
, n
+ 1, nVirBottom
);
729 rRenderContext
.SetLineColor();
730 rRenderContext
.SetFillColor(rStyleSettings
.GetWindowColor());
731 ImplVDrawRect(rRenderContext
, n
, nVirTop
, n
, nVirBottom
);
737 void Ruler::ImplDrawIndent(vcl::RenderContext
& rRenderContext
, const tools::Polygon
& rPoly
, bool bIsHit
)
739 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
741 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
742 rRenderContext
.SetFillColor(bIsHit
? rStyleSettings
.GetDarkShadowColor() : rStyleSettings
.GetWorkspaceColor());
743 tools::Polygon
aPolygon(rPoly
);
744 aPolygon
.Optimize(PolyOptimizeFlags::CLOSE
);
745 rRenderContext
.DrawPolygon(aPolygon
);
748 void Ruler::ImplDrawIndents(vcl::RenderContext
& rRenderContext
, tools::Long nMin
, tools::Long nMax
, tools::Long nVirTop
, tools::Long nVirBottom
)
751 tools::Long nIndentHeight
= (mnVirHeight
/ 2) - 1;
752 tools::Long nIndentWidth2
= nIndentHeight
-3;
754 tools::Polygon
aPoly(5);
756 for (std::vector
<RulerIndent
>::size_type j
= 0; j
< mpData
->pIndents
.size(); j
++)
758 if (mpData
->pIndents
[j
].bInvisible
)
761 RulerIndentStyle nIndentStyle
= mpData
->pIndents
[j
].nStyle
;
763 n
= mpData
->pIndents
[j
].nPos
+mpData
->nNullVirOff
;
765 if ((n
>= nMin
) && (n
<= nMax
))
767 if (nIndentStyle
== RulerIndentStyle::Bottom
)
769 aPoly
.SetPoint(Point(n
+ 0, nVirBottom
- nIndentHeight
), 0);
770 aPoly
.SetPoint(Point(n
- nIndentWidth2
, nVirBottom
- 3), 1);
771 aPoly
.SetPoint(Point(n
- nIndentWidth2
, nVirBottom
), 2);
772 aPoly
.SetPoint(Point(n
+ nIndentWidth2
, nVirBottom
), 3);
773 aPoly
.SetPoint(Point(n
+ nIndentWidth2
, nVirBottom
- 3), 4);
777 aPoly
.SetPoint(Point(n
+ 0, nVirTop
+ nIndentHeight
), 0);
778 aPoly
.SetPoint(Point(n
- nIndentWidth2
, nVirTop
+ 3), 1);
779 aPoly
.SetPoint(Point(n
- nIndentWidth2
, nVirTop
), 2);
780 aPoly
.SetPoint(Point(n
+ nIndentWidth2
, nVirTop
), 3);
781 aPoly
.SetPoint(Point(n
+ nIndentWidth2
, nVirTop
+ 3), 4);
784 if (0 == (mnWinStyle
& WB_HORZ
))
787 for (sal_uInt16 i
= 0; i
< 5; i
++)
790 Point
aSet(nVirBottom
- aTmp
.Y(), aTmp
.X());
795 if (mxCurrentHitTest
!= nullptr && mxCurrentHitTest
->eType
== RulerType::Indent
)
797 bIsHit
= mxCurrentHitTest
->nAryPos
== j
;
799 else if(mbDrag
&& meDragType
== RulerType::Indent
)
801 bIsHit
= mnDragAryPos
== j
;
803 ImplDrawIndent(rRenderContext
, aPoly
, bIsHit
);
808 static void ImplCenterTabPos(Point
& rPos
, sal_uInt16 nTabStyle
)
810 bool bRTL
= 0 != (nTabStyle
& RULER_TAB_RTL
);
811 nTabStyle
&= RULER_TAB_STYLE
;
812 rPos
.AdjustY(ruler_tab
.height
/2 );
814 if ( (!bRTL
&& nTabStyle
== RULER_TAB_LEFT
) ||
815 ( bRTL
&& nTabStyle
== RULER_TAB_RIGHT
) )
817 rPos
.AdjustX( -(ruler_tab
.width
/ 2) );
819 else if ( (!bRTL
&& nTabStyle
== RULER_TAB_RIGHT
) ||
820 ( bRTL
&& nTabStyle
== RULER_TAB_LEFT
) )
822 rPos
.AdjustX(ruler_tab
.width
/ 2 );
826 static void lcl_RotateRect_Impl(tools::Rectangle
& rRect
, const tools::Long nReference
, bool bRightAligned
)
831 tools::Rectangle
aTmp(rRect
);
832 rRect
.SetTop( aTmp
.Left() );
833 rRect
.SetBottom( aTmp
.Right() );
834 rRect
.SetLeft( aTmp
.Top() );
835 rRect
.SetRight( aTmp
.Bottom() );
839 tools::Long nRef
= 2 * nReference
;
840 rRect
.SetLeft( nRef
- rRect
.Left() );
841 rRect
.SetRight( nRef
- rRect
.Right() );
845 static void ImplDrawRulerTab(vcl::RenderContext
& rRenderContext
, const Point
& rPos
,
846 sal_uInt16 nStyle
, WinBits nWinBits
)
848 if (nStyle
& RULER_STYLE_INVISIBLE
)
851 sal_uInt16 nTabStyle
= nStyle
& RULER_TAB_STYLE
;
852 bool bRTL
= 0 != (nStyle
& RULER_TAB_RTL
);
854 // Scale by the screen DPI scaling factor
855 // However when doing this some of the rectangles
856 // drawn become asymmetric due to the +1 offsets
857 sal_uInt16 DPIOffset
= rRenderContext
.GetDPIScaleFactor() - 1;
859 // A tabstop is drawn using three rectangles
860 tools::Rectangle aRect1
; // A horizontal short line
861 tools::Rectangle aRect2
; // A vertical short line
862 tools::Rectangle aRect3
; // A small square
866 if (nTabStyle
== RULER_TAB_DEFAULT
)
868 aRect1
.SetLeft( rPos
.X() - ruler_tab
.dwidth2
+ 1 );
869 aRect1
.SetTop( rPos
.Y() - ruler_tab
.dheight2
+ 1 );
870 aRect1
.SetRight( rPos
.X() - ruler_tab
.dwidth2
+ ruler_tab
.dwidth
+ DPIOffset
);
871 aRect1
.SetBottom( rPos
.Y() );
873 aRect2
.SetLeft( rPos
.X() - ruler_tab
.dwidth2
+ ruler_tab
.dwidth3
);
874 aRect2
.SetTop( rPos
.Y() - ruler_tab
.dheight
+ 1 );
875 aRect2
.SetRight( rPos
.X() - ruler_tab
.dwidth2
+ ruler_tab
.dwidth3
+ ruler_tab
.dwidth4
- 1 );
876 aRect2
.SetBottom( rPos
.Y() );
879 else if ((!bRTL
&& nTabStyle
== RULER_TAB_LEFT
) || (bRTL
&& nTabStyle
== RULER_TAB_RIGHT
))
881 aRect1
.SetLeft( rPos
.X() );
882 aRect1
.SetTop( rPos
.Y() - ruler_tab
.height2
+ 1 );
883 aRect1
.SetRight( rPos
.X() + ruler_tab
.width
- 1 );
884 aRect1
.SetBottom( rPos
.Y() );
886 aRect2
.SetLeft( rPos
.X() );
887 aRect2
.SetTop( rPos
.Y() - ruler_tab
.height
+ 1 );
888 aRect2
.SetRight( rPos
.X() + ruler_tab
.width2
- 1 );
889 aRect2
.SetBottom( rPos
.Y() );
891 else if ((!bRTL
&& nTabStyle
== RULER_TAB_RIGHT
) || (bRTL
&& nTabStyle
== RULER_TAB_LEFT
))
893 aRect1
.SetLeft( rPos
.X() - ruler_tab
.width
+ 1 );
894 aRect1
.SetTop( rPos
.Y() - ruler_tab
.height2
+ 1 );
895 aRect1
.SetRight( rPos
.X() );
896 aRect1
.SetBottom( rPos
.Y() );
898 aRect2
.SetLeft( rPos
.X() - ruler_tab
.width2
+ 1 );
899 aRect2
.SetTop( rPos
.Y() - ruler_tab
.height
+ 1 );
900 aRect2
.SetRight( rPos
.X() );
901 aRect2
.SetBottom( rPos
.Y() );
905 aRect1
.SetLeft( rPos
.X() - ruler_tab
.cwidth2
+ 1 );
906 aRect1
.SetTop( rPos
.Y() - ruler_tab
.height2
+ 1 );
907 aRect1
.SetRight( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth
+ DPIOffset
);
908 aRect1
.SetBottom( rPos
.Y() );
910 aRect2
.SetLeft( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth3
);
911 aRect2
.SetTop( rPos
.Y() - ruler_tab
.height
+ 1 );
912 aRect2
.SetRight( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth3
+ ruler_tab
.cwidth4
- 1 );
913 aRect2
.SetBottom( rPos
.Y() );
915 if (nTabStyle
== RULER_TAB_DECIMAL
)
917 aRect3
.SetLeft( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth
- 1 );
918 aRect3
.SetTop( rPos
.Y() - ruler_tab
.height
+ 1 + 1 - DPIOffset
);
919 aRect3
.SetRight( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth
+ DPIOffset
);
920 aRect3
.SetBottom( rPos
.Y() - ruler_tab
.height
+ 1 + 2 );
923 if (0 == (nWinBits
& WB_HORZ
))
925 bool bRightAligned
= 0 != (nWinBits
& WB_RIGHT_ALIGNED
);
926 lcl_RotateRect_Impl(aRect1
, rPos
.Y(), bRightAligned
);
927 lcl_RotateRect_Impl(aRect2
, rPos
.Y(), bRightAligned
);
928 lcl_RotateRect_Impl(aRect3
, rPos
.Y(), bRightAligned
);
930 rRenderContext
.DrawRect(aRect1
);
931 rRenderContext
.DrawRect(aRect2
);
933 if (!aRect3
.IsEmpty())
934 rRenderContext
.DrawRect(aRect3
);
937 void Ruler::ImplDrawTab(vcl::RenderContext
& rRenderContext
, const Point
& rPos
, sal_uInt16 nStyle
)
939 if (nStyle
& RULER_STYLE_INVISIBLE
)
942 rRenderContext
.SetLineColor();
944 if (nStyle
& RULER_STYLE_DONTKNOW
)
945 rRenderContext
.SetFillColor(rRenderContext
.GetSettings().GetStyleSettings().GetFaceColor());
947 rRenderContext
.SetFillColor(rRenderContext
.GetSettings().GetStyleSettings().GetDarkShadowColor());
949 if (mpData
->bTextRTL
)
950 nStyle
|= RULER_TAB_RTL
;
952 ImplDrawRulerTab(rRenderContext
, rPos
, nStyle
, GetStyle());
955 void Ruler::ImplDrawTabs(vcl::RenderContext
& rRenderContext
, tools::Long nMin
, tools::Long nMax
, tools::Long nVirTop
, tools::Long nVirBottom
)
957 for (const RulerTab
& rTab
: mpData
->pTabs
)
959 if (rTab
.nStyle
& RULER_STYLE_INVISIBLE
)
962 tools::Long aPosition
;
963 aPosition
= rTab
.nPos
;
964 aPosition
+= +mpData
->nNullVirOff
;
965 tools::Long nTopBottom
= (GetStyle() & WB_RIGHT_ALIGNED
) ? nVirTop
: nVirBottom
;
966 if (nMin
<= aPosition
&& aPosition
<= nMax
)
967 ImplDrawTab(rRenderContext
, Point( aPosition
, nTopBottom
), rTab
.nStyle
);
971 static int adjustSize(int nOrig
)
976 // make sure we return an odd number, that looks better in the ruler
977 return ( (3*nOrig
) / 8) * 2 + 1;
980 void Ruler::ApplySettings(vcl::RenderContext
& rRenderContext
)
982 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
984 vcl::Font aFont
= rStyleSettings
.GetToolFont();
985 // make the font a bit smaller than default
986 Size
aSize(adjustSize(aFont
.GetFontSize().Width()), adjustSize(aFont
.GetFontSize().Height()));
987 aFont
.SetFontSize(aSize
);
989 ApplyControlFont(rRenderContext
, aFont
);
991 ApplyControlForeground(*GetOutDev(), rStyleSettings
.GetDarkShadowColor());
995 svtools::ColorConfig aColorConfig
;
996 aColor
= aColorConfig
.GetColorValue(svtools::APPBACKGROUND
).nColor
;
997 ApplyControlBackground(rRenderContext
, aColor
);
998 // A hack to get it to change the non-ruler application background to change immediately
999 if (aColor
!= maVirDev
->GetBackground().GetColor())
1001 maVirDev
->SetBackground(aColor
);
1006 void Ruler::ImplInitSettings(bool bFont
, bool bForeground
, bool bBackground
)
1008 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1012 vcl::Font aFont
= rStyleSettings
.GetToolFont();
1013 // make the font a bit smaller than default
1014 Size
aSize(adjustSize(aFont
.GetFontSize().Width()), adjustSize(aFont
.GetFontSize().Height()));
1015 aFont
.SetFontSize(aSize
);
1017 ApplyControlFont(*GetOutDev(), aFont
);
1020 if (bForeground
|| bFont
)
1022 ApplyControlForeground(*GetOutDev(), rStyleSettings
.GetDarkShadowColor());
1029 svtools::ColorConfig aColorConfig
;
1030 aColor
= aColorConfig
.GetColorValue(svtools::APPBACKGROUND
).nColor
;
1031 ApplyControlBackground(*GetOutDev(), aColor
);
1034 maVirDev
->SetSettings( GetSettings() );
1035 maVirDev
->SetBackground( GetBackground() );
1036 vcl::Font aFont
= GetFont();
1038 if (mnWinStyle
& WB_VERT
)
1039 aFont
.SetOrientation(900_deg10
);
1041 maVirDev
->SetFont(aFont
);
1042 maVirDev
->SetTextColor(GetTextColor());
1043 maVirDev
->SetTextFillColor(GetTextFillColor());
1046 void Ruler::ImplCalc()
1049 mpData
->nRulVirOff
= mnWinOff
+ mpData
->nPageOff
;
1050 if ( mpData
->nRulVirOff
> mnVirOff
)
1051 mpData
->nRulVirOff
-= mnVirOff
;
1053 mpData
->nRulVirOff
= 0;
1054 tools::Long nRulWinOff
= mpData
->nRulVirOff
+mnVirOff
;
1056 // calculate non-visual part of the page
1057 tools::Long nNotVisPageWidth
;
1058 if ( mpData
->nPageOff
< 0 )
1060 nNotVisPageWidth
= -(mpData
->nPageOff
);
1061 if ( nRulWinOff
< mnWinOff
)
1062 nNotVisPageWidth
-= mnWinOff
-nRulWinOff
;
1065 nNotVisPageWidth
= 0;
1068 if ( mnWinStyle
& WB_HORZ
)
1070 if ( mbAutoWinWidth
)
1071 mnWinWidth
= mnWidth
- mnVirOff
;
1072 if ( mpData
->bAutoPageWidth
)
1073 mpData
->nPageWidth
= mnWinWidth
;
1074 mpData
->nRulWidth
= std::min( mnWinWidth
, mpData
->nPageWidth
-nNotVisPageWidth
);
1075 if ( nRulWinOff
+mpData
->nRulWidth
> mnWidth
)
1076 mpData
->nRulWidth
= mnWidth
-nRulWinOff
;
1080 if ( mbAutoWinWidth
)
1081 mnWinWidth
= mnHeight
- mnVirOff
;
1082 if ( mpData
->bAutoPageWidth
)
1083 mpData
->nPageWidth
= mnWinWidth
;
1084 mpData
->nRulWidth
= std::min( mnWinWidth
, mpData
->nPageWidth
-nNotVisPageWidth
);
1085 if ( nRulWinOff
+mpData
->nRulWidth
> mnHeight
)
1086 mpData
->nRulWidth
= mnHeight
-nRulWinOff
;
1092 void Ruler::ImplFormat(vcl::RenderContext
const & rRenderContext
)
1094 // if already formatted, don't do it again
1098 // don't do anything if the window still has no size
1102 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
1103 tools::Long nP1
; // pixel position of Page1
1104 tools::Long nP2
; // pixel position of Page2
1105 tools::Long nM1
; // pixel position of Margin1
1106 tools::Long nM2
; // pixel position of Margin2
1107 tools::Long nVirTop
; // top/left corner
1108 tools::Long nVirBottom
; // bottom/right corner
1109 tools::Long nVirLeft
; // left/top corner
1110 tools::Long nVirRight
; // right/bottom corner
1111 tools::Long nNullVirOff
; // for faster calculation
1117 mpData
->nNullVirOff
= mnWinOff
+ mpData
->nPageOff
+ mpData
->nNullOff
- mnVirOff
;
1119 nNullVirOff
= mpData
->nNullVirOff
;
1120 nVirLeft
= mpData
->nRulVirOff
;
1121 nVirRight
= nVirLeft
+ mpData
->nRulWidth
- 1;
1123 nVirBottom
= mnVirHeight
- 1;
1125 if (!IsReallyVisible())
1130 // initialize VirtualDevice
1131 if (mnWinStyle
& WB_HORZ
)
1133 aVirDevSize
.setWidth( mnVirWidth
);
1134 aVirDevSize
.setHeight( mnVirHeight
);
1138 aVirDevSize
.setHeight( mnVirWidth
);
1139 aVirDevSize
.setWidth( mnVirHeight
);
1141 if (aVirDevSize
!= maVirDev
->GetOutputSizePixel())
1142 maVirDev
->SetOutputSizePixel(aVirDevSize
);
1146 // calculate margins
1147 if (!(mpData
->nMargin1Style
& RulerMarginStyle::Invisible
))
1149 nM1
= mpData
->nMargin1
+ nNullVirOff
;
1150 if (mpData
->bAutoPageWidth
)
1157 nP1
= nNullVirOff
- mpData
->nNullOff
;
1164 if (!(mpData
->nMargin2Style
& RulerMarginStyle::Invisible
))
1166 nM2
= mpData
->nMargin2
+ nNullVirOff
;
1167 if (mpData
->bAutoPageWidth
)
1170 if (nM2
> nVirRight
)
1174 nP2
= nNullVirOff
- mpData
->nNullOff
+ mpData
->nPageWidth
;
1184 // top/bottom border
1185 maVirDev
->SetLineColor(rStyleSettings
.GetShadowColor());
1186 ImplVDrawLine(*maVirDev
, nVirLeft
, nVirTop
+ 1, nM1
, nVirTop
+ 1); //top left line
1187 ImplVDrawLine(*maVirDev
, nM2
, nVirTop
+ 1, nP2
- 1, nVirTop
+ 1); //top right line
1192 // draw margin1, margin2 and in-between
1193 maVirDev
->SetLineColor();
1194 maVirDev
->SetFillColor(rStyleSettings
.GetDialogColor());
1196 ImplVDrawRect(*maVirDev
, nP1
, nVirTop
+ 1, nM1
, nVirBottom
); //left gray rectangle
1198 ImplVDrawRect(*maVirDev
, nM2
, nVirTop
+ 1, nP2
, nVirBottom
); //right gray rectangle
1201 maVirDev
->SetFillColor(rStyleSettings
.GetWindowColor());
1202 ImplVDrawRect(*maVirDev
, nM1
+ 1, nVirTop
, nM2
- 1, nVirBottom
); //center rectangle
1204 maVirDev
->SetLineColor(rStyleSettings
.GetShadowColor());
1207 ImplVDrawLine(*maVirDev
, nM1
, nVirTop
+ 1, nM1
, nVirBottom
); //right line of the left rectangle
1208 ImplVDrawLine(*maVirDev
, nP1
, nVirBottom
, nM1
, nVirBottom
); //bottom line of the left rectangle
1209 if (nP1
>= nVirLeft
)
1211 ImplVDrawLine(*maVirDev
, nP1
, nVirTop
+ 1, nP1
, nVirBottom
); //left line of the left rectangle
1212 ImplVDrawLine(*maVirDev
, nP1
, nVirBottom
, nP1
+ 1, nVirBottom
); //?
1217 ImplVDrawLine(*maVirDev
, nM2
, nVirBottom
, nP2
- 1, nVirBottom
); //bottom line of the right rectangle
1218 ImplVDrawLine(*maVirDev
, nM2
, nVirTop
+ 1, nM2
, nVirBottom
); //left line of the right rectangle
1219 if (nP2
<= nVirRight
+ 1)
1220 ImplVDrawLine(*maVirDev
, nP2
- 1, nVirTop
+ 1, nP2
- 1, nVirBottom
); //right line of the right rectangle
1223 tools::Long nMin
= nVirLeft
;
1224 tools::Long nMax
= nP2
;
1225 tools::Long nStart
= 0;
1227 if (mpData
->bTextRTL
)
1228 nStart
= mpData
->nRightFrameMargin
+ nNullVirOff
;
1230 nStart
= mpData
->nLeftFrameMargin
+ nNullVirOff
;
1235 if (nP2
< nVirRight
)
1239 ImplDrawTicks(*maVirDev
, nMin
, nMax
, nStart
, nVirTop
, nVirBottom
);
1242 if (!mpData
->pBorders
.empty())
1243 ImplDrawBorders(*maVirDev
, nVirLeft
, nP2
, nVirTop
, nVirBottom
);
1246 if (!mpData
->pIndents
.empty())
1247 ImplDrawIndents(*maVirDev
, nVirLeft
, nP2
, nVirTop
- 1, nVirBottom
+ 1);
1250 if (!mpData
->pTabs
.empty())
1251 ImplDrawTabs(*maVirDev
, nVirLeft
, nP2
, nVirTop
-1, nVirBottom
+ 1);
1256 void Ruler::ImplInitExtraField( bool bUpdate
)
1258 Size aWinSize
= GetOutputSizePixel();
1260 // extra field evaluate
1261 if ( mnWinStyle
& WB_EXTRAFIELD
)
1263 maExtraRect
.SetLeft( RULER_OFF
);
1264 maExtraRect
.SetTop( RULER_OFF
);
1265 maExtraRect
.SetRight( RULER_OFF
+ mnVirHeight
- 1 );
1266 maExtraRect
.SetBottom( RULER_OFF
+ mnVirHeight
- 1 );
1267 if(mpData
->bTextRTL
)
1269 if(mnWinStyle
& WB_HORZ
)
1270 maExtraRect
.Move(aWinSize
.Width() - maExtraRect
.GetWidth() - maExtraRect
.Left(), 0);
1272 maExtraRect
.Move(0, aWinSize
.Height() - maExtraRect
.GetHeight() - maExtraRect
.Top());
1276 mnVirOff
= maExtraRect
.Right()+1;
1281 maExtraRect
.SetEmpty();
1285 // mnVirWidth depends on mnVirOff
1286 if ( (mnVirWidth
> RULER_MIN_SIZE
) ||
1287 ((aWinSize
.Width() > RULER_MIN_SIZE
) && (aWinSize
.Height() > RULER_MIN_SIZE
)) )
1289 if ( mnWinStyle
& WB_HORZ
)
1290 mnVirWidth
= aWinSize
.Width()-mnVirOff
;
1292 mnVirWidth
= aWinSize
.Height()-mnVirOff
;
1294 if ( mnVirWidth
< RULER_MIN_SIZE
)
1306 void Ruler::ImplDraw(vcl::RenderContext
& rRenderContext
)
1310 ImplFormat(rRenderContext
);
1313 if (!IsReallyVisible())
1316 // output the ruler to the virtual device
1318 Size aVirDevSize
= maVirDev
->GetOutputSizePixel();
1320 if (mnWinStyle
& WB_HORZ
)
1322 aOffPos
.setX( mnVirOff
);
1323 if (mpData
->bTextRTL
)
1324 aVirDevSize
.AdjustWidth( -(maExtraRect
.GetWidth()) );
1326 aOffPos
.setY( RULER_OFF
);
1330 aOffPos
.setX( RULER_OFF
);
1331 aOffPos
.setY( mnVirOff
);
1333 rRenderContext
.DrawOutDev(aOffPos
, aVirDevSize
, Point(), aVirDevSize
, *maVirDev
);
1335 // redraw positionlines
1336 ImplInvertLines(rRenderContext
);
1339 void Ruler::ImplDrawExtra(vcl::RenderContext
& rRenderContext
)
1341 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
1342 tools::Rectangle aRect
= maExtraRect
;
1343 bool bEraseRect
= false;
1345 aRect
.AdjustLeft(2 );
1346 aRect
.AdjustTop(2 );
1347 aRect
.AdjustRight( -2 );
1348 aRect
.AdjustBottom( -2 );
1350 if (mnExtraStyle
& RULER_STYLE_HIGHLIGHT
)
1352 rRenderContext
.SetFillColor(rStyleSettings
.GetCheckedColor());
1358 rRenderContext
.SetLineColor();
1359 rRenderContext
.DrawRect(aRect
);
1363 if (meExtraType
== RulerExtra::NullOffset
)
1365 rRenderContext
.SetLineColor(rStyleSettings
.GetButtonTextColor());
1366 rRenderContext
.DrawLine(Point(aRect
.Left() + 1, aRect
.Top() + 4),
1367 Point(aRect
.Right() - 1, aRect
.Top() + 4));
1368 rRenderContext
.DrawLine(Point(aRect
.Left() + 4, aRect
.Top() + 1),
1369 Point(aRect
.Left() + 4, aRect
.Bottom() - 1));
1371 else if (meExtraType
== RulerExtra::Tab
)
1373 sal_uInt16 nTabStyle
= mnExtraStyle
& RULER_TAB_STYLE
;
1374 if (mpData
->bTextRTL
)
1375 nTabStyle
|= RULER_TAB_RTL
;
1376 Point aCenter
= aRect
.Center();
1377 Point
aDraw(aCenter
);
1378 ImplCenterTabPos(aDraw
, nTabStyle
);
1379 WinBits nWinBits
= GetStyle();
1380 if (0 == (nWinBits
& WB_HORZ
))
1382 if ((nWinBits
& WB_RIGHT_ALIGNED
) != 0)
1383 aDraw
.setY( 2 * aCenter
.Y() - aDraw
.Y() );
1385 if (mpData
->bTextRTL
)
1387 tools::Long nTemp
= aDraw
.X();
1388 aDraw
.setX( aDraw
.Y() );
1389 aDraw
.setY( nTemp
);
1392 ImplDrawTab(rRenderContext
, aDraw
, nTabStyle
);
1396 void Ruler::ImplUpdate( bool bMustCalc
)
1398 // clear lines in this place so they aren't considered at recalculation
1400 Invalidate(InvalidateFlags::NoErase
);
1407 // abort if we are dragging as drag-handler will update the ruler after drag is finished
1411 // otherwise trigger update
1412 if (IsReallyVisible() && IsUpdateMode())
1414 Invalidate(InvalidateFlags::NoErase
);
1418 bool Ruler::ImplDoHitTest( const Point
& rPos
, RulerSelection
* pHitTest
,
1419 bool bRequireStyle
, RulerIndentStyle nRequiredStyle
,
1420 tools::Long nTolerance
) const
1424 tools::Long nHitBottom
;
1432 // determine positions
1433 bool bIsHori
= 0 != (mnWinStyle
& WB_HORZ
);
1444 nHitBottom
= mnVirHeight
+ (RULER_OFF
* 2);
1447 pHitTest
->nAryPos
= 0;
1448 pHitTest
->mnDragSize
= RulerDragSize::Move
;
1449 pHitTest
->bSize
= false;
1450 pHitTest
->bSizeBar
= false;
1452 // so that leftover tabs and indents are taken into account
1453 tools::Long nXExtraOff
;
1454 if ( !mpData
->pTabs
.empty() || !mpData
->pIndents
.empty() )
1455 nXExtraOff
= (mnVirHeight
/ 2) - 4;
1461 if ( (nX
< mpData
->nRulVirOff
- nXExtraOff
) ||
1462 (nX
> mpData
->nRulVirOff
+ mpData
->nRulWidth
+ nXExtraOff
) ||
1467 pHitTest
->eType
= RulerType::Outside
;
1471 nX
-= mpData
->nNullVirOff
;
1472 pHitTest
->nPos
= nX
;
1473 pHitTest
->eType
= RulerType::DontKnow
;
1475 // first test the tabs
1476 tools::Rectangle aRect
;
1477 if ( !mpData
->pTabs
.empty() )
1479 aRect
.SetBottom( nHitBottom
);
1480 aRect
.SetTop( aRect
.Bottom() - ruler_tab
.height
- RULER_OFF
);
1482 for ( i
= mpData
->pTabs
.size() - 1; i
>= 0; i
-- )
1484 nStyle
= mpData
->pTabs
[i
].nStyle
;
1485 if ( !(nStyle
& RULER_STYLE_INVISIBLE
) )
1487 nStyle
&= RULER_TAB_STYLE
;
1489 // default tabs are only shown (no action)
1490 if ( nStyle
!= RULER_TAB_DEFAULT
)
1492 n1
= mpData
->pTabs
[i
].nPos
;
1494 if ( nStyle
== RULER_TAB_LEFT
)
1496 aRect
.SetLeft( n1
);
1497 aRect
.SetRight( n1
+ ruler_tab
.width
- 1 );
1499 else if ( nStyle
== RULER_TAB_RIGHT
)
1501 aRect
.SetRight( n1
);
1502 aRect
.SetLeft( n1
- ruler_tab
.width
- 1 );
1506 aRect
.SetLeft( n1
- ruler_tab
.cwidth2
+ 1 );
1507 aRect
.SetRight( n1
- ruler_tab
.cwidth2
+ ruler_tab
.cwidth
);
1510 if ( aRect
.Contains( Point( nX
, nY
) ) )
1512 pHitTest
->eType
= RulerType::Tab
;
1513 pHitTest
->nAryPos
= i
;
1522 if ( !mpData
->pIndents
.empty() )
1524 tools::Long nIndentHeight
= (mnVirHeight
/ 2) - 1;
1525 tools::Long nIndentWidth2
= nIndentHeight
- 3;
1527 for ( i
= mpData
->pIndents
.size(); i
; i
-- )
1529 RulerIndentStyle nIndentStyle
= mpData
->pIndents
[i
-1].nStyle
;
1530 if ( (! bRequireStyle
|| nIndentStyle
== nRequiredStyle
) &&
1531 !mpData
->pIndents
[i
-1].bInvisible
)
1533 n1
= mpData
->pIndents
[i
-1].nPos
;
1535 if ( (nIndentStyle
== RulerIndentStyle::Bottom
) != !bIsHori
)
1537 aRect
.SetLeft( n1
-nIndentWidth2
);
1538 aRect
.SetRight( n1
+nIndentWidth2
);
1539 aRect
.SetTop( nHitBottom
-nIndentHeight
-RULER_OFF
+1 );
1540 aRect
.SetBottom( nHitBottom
);
1544 aRect
.SetLeft( n1
-nIndentWidth2
);
1545 aRect
.SetRight( n1
+nIndentWidth2
);
1547 aRect
.SetBottom( nIndentHeight
+RULER_OFF
-1 );
1550 if ( aRect
.Contains( Point( nX
, nY
) ) )
1552 pHitTest
->eType
= RulerType::Indent
;
1553 pHitTest
->nAryPos
= i
-1;
1561 int nBorderTolerance
= nTolerance
;
1562 if(pHitTest
->bExpandTest
)
1567 for ( i
= mpData
->pBorders
.size(); i
; i
-- )
1569 n1
= mpData
->pBorders
[i
-1].nPos
;
1570 tools::Long n2
= n1
+ mpData
->pBorders
[i
-1].nWidth
;
1572 // borders have at least 3 pixel padding
1573 if ( !mpData
->pBorders
[i
-1].nWidth
)
1575 n1
-= nBorderTolerance
;
1576 n2
+= nBorderTolerance
;
1579 if ( (nX
>= n1
) && (nX
<= n2
) )
1581 RulerBorderStyle nBorderStyle
= mpData
->pBorders
[i
-1].nStyle
;
1582 if ( !(nBorderStyle
& RulerBorderStyle::Invisible
) )
1584 pHitTest
->eType
= RulerType::Border
;
1585 pHitTest
->nAryPos
= i
-1;
1587 if ( !(nBorderStyle
& RulerBorderStyle::Sizeable
) )
1589 if ( nBorderStyle
& RulerBorderStyle::Moveable
)
1591 pHitTest
->bSizeBar
= true;
1592 pHitTest
->mnDragSize
= RulerDragSize::Move
;
1597 tools::Long nMOff
= RULER_MOUSE_BORDERWIDTH
;
1598 while ( nMOff
*2 >= (n2
-n1
-RULER_MOUSE_BORDERMOVE
) )
1609 if ( nX
<= n1
+nMOff
)
1611 pHitTest
->bSize
= true;
1612 pHitTest
->mnDragSize
= RulerDragSize::N1
;
1614 else if ( nX
>= n2
-nMOff
)
1616 pHitTest
->bSize
= true;
1617 pHitTest
->mnDragSize
= RulerDragSize::N2
;
1621 if ( nBorderStyle
& RulerBorderStyle::Moveable
)
1623 pHitTest
->bSizeBar
= true;
1624 pHitTest
->mnDragSize
= RulerDragSize::Move
;
1635 int nMarginTolerance
= pHitTest
->bExpandTest
? nBorderTolerance
: RULER_MOUSE_MARGINWIDTH
;
1637 if ( (mpData
->nMargin1Style
& (RulerMarginStyle::Sizeable
| RulerMarginStyle::Invisible
)) == RulerMarginStyle::Sizeable
)
1639 n1
= mpData
->nMargin1
;
1640 if ( (nX
>= n1
- nMarginTolerance
) && (nX
<= n1
+ nMarginTolerance
) )
1642 pHitTest
->eType
= RulerType::Margin1
;
1643 pHitTest
->bSize
= true;
1647 if ( (mpData
->nMargin2Style
& (RulerMarginStyle::Sizeable
| RulerMarginStyle::Invisible
)) == RulerMarginStyle::Sizeable
)
1649 n1
= mpData
->nMargin2
;
1650 if ( (nX
>= n1
- nMarginTolerance
) && (nX
<= n1
+ nMarginTolerance
) )
1652 pHitTest
->eType
= RulerType::Margin2
;
1653 pHitTest
->bSize
= true;
1659 if ( !mpData
->pTabs
.empty() )
1661 aRect
.SetTop( RULER_OFF
);
1662 aRect
.SetBottom( nHitBottom
);
1664 for ( i
= mpData
->pTabs
.size() - 1; i
>= 0; i
-- )
1666 nStyle
= mpData
->pTabs
[i
].nStyle
;
1667 if ( !(nStyle
& RULER_STYLE_INVISIBLE
) )
1669 nStyle
&= RULER_TAB_STYLE
;
1671 // default tabs are only shown (no action)
1672 if ( nStyle
!= RULER_TAB_DEFAULT
)
1674 n1
= mpData
->pTabs
[i
].nPos
;
1676 if ( nStyle
== RULER_TAB_LEFT
)
1678 aRect
.SetLeft( n1
);
1679 aRect
.SetRight( n1
+ ruler_tab
.width
- 1 );
1681 else if ( nStyle
== RULER_TAB_RIGHT
)
1683 aRect
.SetRight( n1
);
1684 aRect
.SetLeft( n1
- ruler_tab
.width
- 1 );
1688 aRect
.SetLeft( n1
- ruler_tab
.cwidth2
+ 1 );
1689 aRect
.SetRight( n1
- ruler_tab
.cwidth2
+ ruler_tab
.cwidth
);
1692 aRect
.AdjustLeft( -1 );
1693 aRect
.AdjustRight( 1 );
1695 if ( aRect
.Contains( Point( nX
, nY
) ) )
1697 pHitTest
->eType
= RulerType::Tab
;
1698 pHitTest
->nAryPos
= i
;
1709 bool Ruler::ImplDocHitTest( const Point
& rPos
, RulerType eDragType
,
1710 RulerSelection
* pHitTest
, tools::Long nTolerance
) const
1713 bool bRequiredStyle
= false;
1714 RulerIndentStyle nRequiredStyle
= RulerIndentStyle::Top
;
1716 if (eDragType
== RulerType::Indent
)
1718 bRequiredStyle
= true;
1719 nRequiredStyle
= RulerIndentStyle::Bottom
;
1722 if ( mnWinStyle
& WB_HORZ
)
1723 aPos
.AdjustX(mnWinOff
);
1725 aPos
.AdjustY(mnWinOff
);
1727 if ( (eDragType
== RulerType::Indent
) || (eDragType
== RulerType::DontKnow
) )
1729 if ( mnWinStyle
& WB_HORZ
)
1730 aPos
.setY( RULER_OFF
+ 1 );
1732 aPos
.setX( RULER_OFF
+ 1 );
1734 if ( ImplDoHitTest( aPos
, pHitTest
, bRequiredStyle
, nRequiredStyle
, nTolerance
) )
1736 if ( (pHitTest
->eType
== eDragType
) || (eDragType
== RulerType::DontKnow
) )
1741 if ( (eDragType
== RulerType::Indent
) ||
1742 (eDragType
== RulerType::Tab
) ||
1743 (eDragType
== RulerType::DontKnow
) )
1745 if ( mnWinStyle
& WB_HORZ
)
1746 aPos
.setY( mnHeight
- RULER_OFF
- 1 );
1748 aPos
.setX( mnWidth
- RULER_OFF
- 1 );
1750 if ( ImplDoHitTest( aPos
, pHitTest
, bRequiredStyle
, nRequiredStyle
, nTolerance
) )
1752 if ( (pHitTest
->eType
== eDragType
) || (eDragType
== RulerType::DontKnow
) )
1757 if ( (eDragType
== RulerType::Margin1
) || (eDragType
== RulerType::Margin2
) ||
1758 (eDragType
== RulerType::Border
) || (eDragType
== RulerType::DontKnow
) )
1760 if ( mnWinStyle
& WB_HORZ
)
1761 aPos
.setY( RULER_OFF
+ (mnVirHeight
/ 2) );
1763 aPos
.setX( RULER_OFF
+ (mnVirHeight
/ 2) );
1765 if ( ImplDoHitTest( aPos
, pHitTest
, false, RulerIndentStyle::Top
, nTolerance
) )
1767 if ( (pHitTest
->eType
== eDragType
) || (eDragType
== RulerType::DontKnow
) )
1772 pHitTest
->eType
= RulerType::DontKnow
;
1777 bool Ruler::ImplStartDrag( RulerSelection
const * pHitTest
, sal_uInt16 nModifier
)
1779 // don't trigger drag if a border that was clicked can not be changed
1780 if ( (pHitTest
->eType
== RulerType::Border
) &&
1781 !pHitTest
->bSize
&& !pHitTest
->bSizeBar
)
1785 meDragType
= pHitTest
->eType
;
1786 mnDragPos
= pHitTest
->nPos
;
1787 mnDragAryPos
= pHitTest
->nAryPos
;
1788 mnDragSize
= pHitTest
->mnDragSize
;
1789 mnDragModifier
= nModifier
;
1790 *mpDragData
= *mpSaveData
;
1791 mpData
= mpDragData
.get();
1796 // if the handler allows dragging, initialize dragging
1798 mnStartDragPos
= mnDragPos
;
1800 Invalidate(InvalidateFlags::NoErase
);
1805 // otherwise reset the data
1806 meDragType
= RulerType::DontKnow
;
1809 mnDragSize
= RulerDragSize::Move
;
1811 mpData
= mpSaveData
.get();
1817 void Ruler::ImplDrag( const Point
& rPos
)
1821 tools::Long nOutHeight
;
1823 if ( mnWinStyle
& WB_HORZ
)
1827 nOutHeight
= mnHeight
;
1833 nOutHeight
= mnWidth
;
1836 // calculate and fit X
1838 if ( nX
< mpData
->nRulVirOff
)
1840 nX
= mpData
->nRulVirOff
;
1842 else if ( nX
> mpData
->nRulVirOff
+mpData
->nRulWidth
)
1844 nX
= mpData
->nRulVirOff
+mpData
->nRulWidth
;
1846 nX
-= mpData
->nNullVirOff
;
1848 // if upper or left from ruler, then consider old values
1849 mbDragDelete
= false;
1852 if ( !mbDragCanceled
)
1855 mbDragCanceled
= true;
1856 ImplRulerData aTempData
= *mpDragData
;
1857 *mpDragData
= *mpSaveData
;
1862 mnDragPos
= mnStartDragPos
;
1866 Invalidate(InvalidateFlags::NoErase
);
1868 // reset the data as before cancel
1869 *mpDragData
= std::move(aTempData
);
1874 mbDragCanceled
= false;
1876 // +2, so the tabs are not cleared too quickly
1877 if ( nY
> nOutHeight
+ 2 )
1878 mbDragDelete
= true;
1887 Invalidate(InvalidateFlags::NoErase
);
1891 void Ruler::ImplEndDrag()
1894 if ( mbDragCanceled
)
1895 *mpDragData
= *mpSaveData
;
1897 *mpSaveData
= *mpDragData
;
1899 mpData
= mpSaveData
.get();
1905 // reset drag values
1906 meDragType
= RulerType::DontKnow
;
1909 mnDragSize
= RulerDragSize::Move
;
1910 mbDragCanceled
= false;
1911 mbDragDelete
= false;
1916 Invalidate(InvalidateFlags::NoErase
);
1919 void Ruler::MouseButtonDown( const MouseEvent
& rMEvt
)
1921 if ( !rMEvt
.IsLeft() || IsTracking() )
1924 Point aMousePos
= rMEvt
.GetPosPixel();
1925 sal_uInt16 nMouseClicks
= rMEvt
.GetClicks();
1926 sal_uInt16 nMouseModifier
= rMEvt
.GetModifier();
1931 Invalidate(InvalidateFlags::NoErase
);
1934 if ( maExtraRect
.Contains( aMousePos
) )
1940 RulerSelection aHitTest
;
1941 bool bHitTestResult
= ImplDoHitTest(aMousePos
, &aHitTest
);
1943 if ( nMouseClicks
== 1 )
1945 if ( bHitTestResult
)
1947 ImplStartDrag( &aHitTest
, nMouseModifier
);
1951 // calculate position inside of ruler area
1952 if ( aHitTest
.eType
== RulerType::DontKnow
)
1954 mnDragPos
= aHitTest
.nPos
;
1958 // call HitTest again as a click, for example, could set a new tab
1959 if ( ImplDoHitTest(aMousePos
, &aHitTest
) )
1960 ImplStartDrag(&aHitTest
, nMouseModifier
);
1968 mnDragPos
= aHitTest
.nPos
;
1969 mnDragAryPos
= aHitTest
.nAryPos
;
1971 meDragType
= aHitTest
.eType
;
1975 meDragType
= RulerType::DontKnow
;
1982 void Ruler::MouseMove( const MouseEvent
& rMEvt
)
1984 PointerStyle ePtrStyle
= PointerStyle::Arrow
;
1986 mxPreviousHitTest
.swap(mxCurrentHitTest
);
1988 mxCurrentHitTest
.reset(new RulerSelection
);
1990 maHoverSelection
.eType
= RulerType::DontKnow
;
1992 if (ImplDoHitTest( rMEvt
.GetPosPixel(), mxCurrentHitTest
.get() ))
1994 maHoverSelection
= *mxCurrentHitTest
;
1996 if (mxCurrentHitTest
->bSize
)
1998 if (mnWinStyle
& WB_HORZ
)
2000 if (mxCurrentHitTest
->mnDragSize
== RulerDragSize::N1
)
2001 ePtrStyle
= PointerStyle::TabSelectW
;
2002 else if (mxCurrentHitTest
->mnDragSize
== RulerDragSize::N2
)
2003 ePtrStyle
= PointerStyle::TabSelectE
;
2005 ePtrStyle
= PointerStyle::ESize
;
2009 if (mxCurrentHitTest
->mnDragSize
== RulerDragSize::N1
)
2010 ePtrStyle
= PointerStyle::WindowNSize
;
2011 else if (mxCurrentHitTest
->mnDragSize
== RulerDragSize::N2
)
2012 ePtrStyle
= PointerStyle::WindowSSize
;
2014 ePtrStyle
= PointerStyle::SSize
;
2017 else if (mxCurrentHitTest
->bSizeBar
)
2019 if (mnWinStyle
& WB_HORZ
)
2020 ePtrStyle
= PointerStyle::HSizeBar
;
2022 ePtrStyle
= PointerStyle::VSizeBar
;
2026 if (mxPreviousHitTest
!= nullptr && mxPreviousHitTest
->eType
!= mxCurrentHitTest
->eType
)
2031 SetPointer( ePtrStyle
);
2035 Invalidate(InvalidateFlags::NoErase
);
2039 void Ruler::Tracking( const TrackingEvent
& rTEvt
)
2041 if ( rTEvt
.IsTrackingEnded() )
2043 // reset the old state at cancel
2044 if ( rTEvt
.IsTrackingCanceled() )
2046 mbDragCanceled
= true;
2053 ImplDrag( rTEvt
.GetMouseEvent().GetPosPixel() );
2056 void Ruler::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
2058 ImplDraw(rRenderContext
);
2060 // consider extra field
2061 if (mnWinStyle
& WB_EXTRAFIELD
)
2062 ImplDrawExtra(rRenderContext
);
2065 void Ruler::Resize()
2067 Size aWinSize
= GetOutputSizePixel();
2069 tools::Long nNewHeight
;
2070 if ( mnWinStyle
& WB_HORZ
)
2072 if ( aWinSize
.Height() != mnHeight
)
2073 nNewHeight
= aWinSize
.Height();
2079 if ( aWinSize
.Width() != mnWidth
)
2080 nNewHeight
= aWinSize
.Width();
2088 bool bVisible
= IsReallyVisible();
2089 if ( bVisible
&& !mpData
->pLines
.empty() )
2091 mnUpdateFlags
|= RULER_UPDATE_LINES
;
2092 Invalidate(InvalidateFlags::NoErase
);
2095 // recalculate some values if the height/width changes
2096 // extra field should always be updated
2097 ImplInitExtraField( mpData
->bTextRTL
);
2101 mnVirHeight
= nNewHeight
- mnBorderWidth
- ( RULER_OFF
* 2 );
2105 if ( mpData
->bAutoPageWidth
)
2107 else if ( mbAutoWinWidth
)
2111 // clear part of the border
2115 Invalidate(InvalidateFlags::NoErase
);
2116 else if ( mpData
->bAutoPageWidth
)
2118 // only at AutoPageWidth do we need to redraw
2119 tools::Rectangle aRect
;
2121 if ( mnWinStyle
& WB_HORZ
)
2123 if ( mnWidth
< aWinSize
.Width() )
2124 aRect
.SetLeft( mnWidth
- RULER_RESIZE_OFF
);
2126 aRect
.SetLeft( aWinSize
.Width() - RULER_RESIZE_OFF
);
2127 aRect
.SetRight( aRect
.Left() + RULER_RESIZE_OFF
);
2128 aRect
.SetTop( RULER_OFF
);
2129 aRect
.SetBottom( RULER_OFF
+ mnVirHeight
);
2133 if ( mnHeight
< aWinSize
.Height() )
2134 aRect
.SetTop( mnHeight
-RULER_RESIZE_OFF
);
2136 aRect
.SetTop( aWinSize
.Height()-RULER_RESIZE_OFF
);
2137 aRect
.SetBottom( aRect
.Top() + RULER_RESIZE_OFF
);
2138 aRect
.SetLeft( RULER_OFF
);
2139 aRect
.SetRight( RULER_OFF
+ mnVirHeight
);
2142 Invalidate(aRect
, InvalidateFlags::NoErase
);
2146 mnWidth
= aWinSize
.Width();
2147 mnHeight
= aWinSize
.Height();
2150 void Ruler::StateChanged( StateChangedType nType
)
2152 Window::StateChanged( nType
);
2154 if ( nType
== StateChangedType::InitShow
)
2156 else if ( nType
== StateChangedType::UpdateMode
)
2158 if ( IsReallyVisible() && IsUpdateMode() )
2161 else if ( (nType
== StateChangedType::Zoom
) ||
2162 (nType
== StateChangedType::ControlFont
) )
2164 ImplInitSettings( true, false, false );
2167 else if ( nType
== StateChangedType::ControlForeground
)
2169 ImplInitSettings( false, true, false );
2172 else if ( nType
== StateChangedType::ControlBackground
)
2174 ImplInitSettings( false, false, true );
2179 void Ruler::DataChanged( const DataChangedEvent
& rDCEvt
)
2181 Window::DataChanged( rDCEvt
);
2183 if ( (rDCEvt
.GetType() == DataChangedEventType::FONTS
) ||
2184 (rDCEvt
.GetType() == DataChangedEventType::DISPLAY
) ||
2185 (rDCEvt
.GetType() == DataChangedEventType::FONTSUBSTITUTION
) ||
2186 ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
2187 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
)) )
2190 ImplInitSettings( true, true, true );
2195 bool Ruler::StartDrag()
2204 void Ruler::EndDrag()
2212 void Ruler::DoubleClick()
2214 maDoubleClickHdl
.Call( this );
2217 void Ruler::ExtraDown()
2221 void Ruler::Activate()
2225 // update positionlines - draw is delayed
2226 mnUpdateFlags
|= RULER_UPDATE_LINES
;
2227 Invalidate(InvalidateFlags::NoErase
);
2230 void Ruler::Deactivate()
2232 // clear positionlines
2233 Invalidate(InvalidateFlags::NoErase
);
2238 bool Ruler::StartDocDrag( const MouseEvent
& rMEvt
, RulerType eDragType
, tools::Long nTolerance
)
2242 Point aMousePos
= rMEvt
.GetPosPixel();
2243 sal_uInt16 nMouseClicks
= rMEvt
.GetClicks();
2244 sal_uInt16 nMouseModifier
= rMEvt
.GetModifier();
2245 RulerSelection aHitTest
;
2247 if(eDragType
!= RulerType::DontKnow
)
2248 aHitTest
.bExpandTest
= true;
2253 if (!IsReallyVisible())
2255 // set mpData for ImplDocHitTest()
2256 ImplFormat(*GetOutDev());
2259 Invalidate(InvalidateFlags::NoErase
);
2262 if ( nMouseClicks
== 1 )
2264 if ( ImplDocHitTest( aMousePos
, eDragType
, &aHitTest
, nTolerance
) )
2266 PointerStyle aPtr
= PointerStyle::Arrow
;
2268 if ( aHitTest
.bSize
)
2270 if ( mnWinStyle
& WB_HORZ
)
2271 aPtr
= PointerStyle::ESize
;
2273 aPtr
= PointerStyle::SSize
;
2275 else if ( aHitTest
.bSizeBar
)
2277 if ( mnWinStyle
& WB_HORZ
)
2278 aPtr
= PointerStyle::HSizeBar
;
2280 aPtr
= PointerStyle::VSizeBar
;
2283 return ImplStartDrag( &aHitTest
, nMouseModifier
);
2286 else if ( nMouseClicks
== 2 )
2288 if ( ImplDocHitTest( aMousePos
, eDragType
, &aHitTest
, nTolerance
) )
2290 mnDragPos
= aHitTest
.nPos
;
2291 mnDragAryPos
= aHitTest
.nAryPos
;
2306 void Ruler::CancelDrag()
2310 ImplDrag( Point( -1, -1 ) );
2315 RulerType
Ruler::GetRulerType( const Point
& rPos
, sal_uInt16
* pAryPos
)
2317 RulerSelection aHitTest
;
2320 if ( IsReallyVisible() && mbFormat
)
2322 Invalidate(InvalidateFlags::NoErase
);
2325 (void)ImplDoHitTest(rPos
, &aHitTest
);
2329 *pAryPos
= aHitTest
.nAryPos
;
2330 return aHitTest
.eType
;
2333 void Ruler::SetWinPos( tools::Long nNewOff
, tools::Long nNewWidth
)
2335 // should widths be automatically calculated
2337 mbAutoWinWidth
= true;
2339 mbAutoWinWidth
= false;
2342 mnWinWidth
= nNewWidth
;
2346 void Ruler::SetPagePos( tools::Long nNewOff
, tools::Long nNewWidth
)
2348 // should we do anything?
2349 if ( (mpData
->nPageOff
== nNewOff
) && (mpData
->nPageWidth
== nNewWidth
) )
2352 // should widths be automatically calculated
2354 mpData
->bAutoPageWidth
= true;
2356 mpData
->bAutoPageWidth
= false;
2358 mpData
->nPageOff
= nNewOff
;
2359 mpData
->nPageWidth
= nNewWidth
;
2363 void Ruler::SetBorderPos( tools::Long nOff
)
2365 if ( mnWinStyle
& WB_BORDER
)
2367 if ( mnBorderOff
!= nOff
)
2371 if ( IsReallyVisible() && IsUpdateMode() )
2372 Invalidate(InvalidateFlags::NoErase
);
2377 void Ruler::SetUnit( FieldUnit eNewUnit
)
2379 if ( meUnit
== eNewUnit
)
2386 mnUnitIndex
= RULER_UNIT_MM
;
2389 mnUnitIndex
= RULER_UNIT_CM
;
2392 mnUnitIndex
= RULER_UNIT_M
;
2395 mnUnitIndex
= RULER_UNIT_KM
;
2397 case FieldUnit::INCH
:
2398 mnUnitIndex
= RULER_UNIT_INCH
;
2400 case FieldUnit::FOOT
:
2401 mnUnitIndex
= RULER_UNIT_FOOT
;
2403 case FieldUnit::MILE
:
2404 mnUnitIndex
= RULER_UNIT_MILE
;
2406 case FieldUnit::POINT
:
2407 mnUnitIndex
= RULER_UNIT_POINT
;
2409 case FieldUnit::PICA
:
2410 mnUnitIndex
= RULER_UNIT_PICA
;
2412 case FieldUnit::CHAR
:
2413 mnUnitIndex
= RULER_UNIT_CHAR
;
2415 case FieldUnit::LINE
:
2416 mnUnitIndex
= RULER_UNIT_LINE
;
2419 SAL_WARN( "svtools.control", "Ruler::SetUnit() - Wrong Unit" );
2423 maMapMode
.SetMapUnit( aImplRulerUnitTab
[mnUnitIndex
].eMapUnit
);
2427 void Ruler::SetZoom( const Fraction
& rNewZoom
)
2429 DBG_ASSERT( rNewZoom
.GetNumerator(), "Ruler::SetZoom() with scale 0 is not allowed" );
2431 if ( maZoom
!= rNewZoom
)
2434 maMapMode
.SetScaleX( maZoom
);
2435 maMapMode
.SetScaleY( maZoom
);
2440 void Ruler::SetExtraType( RulerExtra eNewExtraType
, sal_uInt16 nStyle
)
2442 if ( mnWinStyle
& WB_EXTRAFIELD
)
2444 meExtraType
= eNewExtraType
;
2445 mnExtraStyle
= nStyle
;
2446 if (IsReallyVisible() && IsUpdateMode())
2451 void Ruler::SetNullOffset( tools::Long nPos
)
2453 if ( mpData
->nNullOff
!= nPos
)
2455 mpData
->nNullVirOff
+= nPos
- mpData
->nNullOff
;
2456 mpData
->nNullOff
= nPos
;
2461 void Ruler::SetLeftFrameMargin( tools::Long nPos
)
2463 if ( mpData
->nLeftFrameMargin
!= nPos
)
2465 mpData
->nLeftFrameMargin
= nPos
;
2470 void Ruler::SetRightFrameMargin( tools::Long nPos
)
2472 if ( mpData
->nRightFrameMargin
!= nPos
)
2474 mpData
->nRightFrameMargin
= nPos
;
2479 void Ruler::SetMargin1( tools::Long nPos
, RulerMarginStyle nMarginStyle
)
2481 if ( (mpData
->nMargin1
!= nPos
) || (mpData
->nMargin1Style
!= nMarginStyle
) )
2483 mpData
->nMargin1
= nPos
;
2484 mpData
->nMargin1Style
= nMarginStyle
;
2489 void Ruler::SetMargin2( tools::Long nPos
, RulerMarginStyle nMarginStyle
)
2491 DBG_ASSERT( (nPos
>= mpData
->nMargin1
) ||
2492 (mpData
->nMargin1Style
& RulerMarginStyle::Invisible
) ||
2493 (mpData
->nMargin2Style
& RulerMarginStyle::Invisible
),
2494 "Ruler::SetMargin2() - Margin2 < Margin1" );
2496 if ( (mpData
->nMargin2
!= nPos
) || (mpData
->nMargin2Style
!= nMarginStyle
) )
2498 mpData
->nMargin2
= nPos
;
2499 mpData
->nMargin2Style
= nMarginStyle
;
2504 void Ruler::SetLines( sal_uInt32 aLineArraySize
, const RulerLine
* pLineArray
)
2506 // To determine if what has changed
2507 if ( mpData
->pLines
.size() == aLineArraySize
)
2509 sal_uInt32 i
= aLineArraySize
;
2510 std::vector
<RulerLine
>::const_iterator aItr1
= mpData
->pLines
.begin();
2511 const RulerLine
* pAry2
= pLineArray
;
2514 if ( aItr1
->nPos
!= pAry2
->nPos
)
2524 // New values and new share issue
2526 bMustUpdate
= IsReallyVisible() && IsUpdateMode();
2530 Invalidate(InvalidateFlags::NoErase
);
2533 if ( !aLineArraySize
|| !pLineArray
)
2535 if ( mpData
->pLines
.empty() )
2537 mpData
->pLines
.clear();
2541 if ( mpData
->pLines
.size() != aLineArraySize
)
2543 mpData
->pLines
.resize(aLineArraySize
);
2546 std::copy( pLineArray
,
2547 pLineArray
+ aLineArraySize
,
2548 mpData
->pLines
.begin() );
2551 Invalidate(InvalidateFlags::NoErase
);
2555 void Ruler::SetBorders( sal_uInt32 aBorderArraySize
, const RulerBorder
* pBorderArray
)
2557 if ( !aBorderArraySize
|| !pBorderArray
)
2559 if ( mpData
->pBorders
.empty() )
2561 mpData
->pBorders
.clear();
2565 if ( mpData
->pBorders
.size() != aBorderArraySize
)
2567 mpData
->pBorders
.resize(aBorderArraySize
);
2571 sal_uInt32 i
= aBorderArraySize
;
2572 const RulerBorder
* pAry1
= mpData
->pBorders
.data();
2573 const RulerBorder
* pAry2
= pBorderArray
;
2576 if ( (pAry1
->nPos
!= pAry2
->nPos
) ||
2577 (pAry1
->nWidth
!= pAry2
->nWidth
) ||
2578 (pAry1
->nStyle
!= pAry2
->nStyle
) )
2587 std::copy( pBorderArray
,
2588 pBorderArray
+ aBorderArraySize
,
2589 mpData
->pBorders
.begin() );
2595 void Ruler::SetIndents( sal_uInt32 aIndentArraySize
, const RulerIndent
* pIndentArray
)
2598 if ( !aIndentArraySize
|| !pIndentArray
)
2600 if ( mpData
->pIndents
.empty() )
2602 mpData
->pIndents
.clear();
2606 if ( mpData
->pIndents
.size() != aIndentArraySize
)
2608 mpData
->pIndents
.resize(aIndentArraySize
);
2612 sal_uInt32 i
= aIndentArraySize
;
2613 const RulerIndent
* pAry1
= mpData
->pIndents
.data();
2614 const RulerIndent
* pAry2
= pIndentArray
;
2617 if ( (pAry1
->nPos
!= pAry2
->nPos
) ||
2618 (pAry1
->nStyle
!= pAry2
->nStyle
) )
2628 std::copy( pIndentArray
,
2629 pIndentArray
+ aIndentArraySize
,
2630 mpData
->pIndents
.begin() );
2636 void Ruler::SetTabs( sal_uInt32 aTabArraySize
, const RulerTab
* pTabArray
)
2638 if ( aTabArraySize
== 0 || pTabArray
== nullptr )
2640 if ( mpData
->pTabs
.empty() )
2642 mpData
->pTabs
.clear();
2646 if ( mpData
->pTabs
.size() != aTabArraySize
)
2648 mpData
->pTabs
.resize(aTabArraySize
);
2652 sal_uInt32 i
= aTabArraySize
;
2653 std::vector
<RulerTab
>::iterator aTabIterator
= mpData
->pTabs
.begin();
2654 const RulerTab
* pInputArray
= pTabArray
;
2657 RulerTab
& aCurrent
= *aTabIterator
;
2658 if ( aCurrent
.nPos
!= pInputArray
->nPos
||
2659 aCurrent
.nStyle
!= pInputArray
->nStyle
)
2670 std::copy(pTabArray
, pTabArray
+ aTabArraySize
, mpData
->pTabs
.begin());
2676 const std::vector
<RulerTab
>& Ruler::GetTabs() const
2678 return mpData
->pTabs
;
2681 void Ruler::SetStyle( WinBits nStyle
)
2683 if ( mnWinStyle
!= nStyle
)
2685 mnWinStyle
= nStyle
;
2686 ImplInitExtraField( true );
2690 void Ruler::DrawTab(vcl::RenderContext
& rRenderContext
, const Color
&rFillColor
, const Point
& rPos
, sal_uInt16 nStyle
)
2693 sal_uInt16 nTabStyle
= nStyle
& (RULER_TAB_STYLE
| RULER_TAB_RTL
);
2695 rRenderContext
.Push(vcl::PushFlags::LINECOLOR
| vcl::PushFlags::FILLCOLOR
);
2696 rRenderContext
.SetLineColor();
2697 rRenderContext
.SetFillColor(rFillColor
);
2698 ImplCenterTabPos(aPos
, nTabStyle
);
2699 ImplDrawRulerTab(rRenderContext
, aPos
, nTabStyle
, nStyle
);
2700 rRenderContext
.Pop();
2703 void Ruler::SetTextRTL(bool bRTL
)
2705 if(mpData
->bTextRTL
!= bRTL
)
2707 mpData
->bTextRTL
= bRTL
;
2708 if ( IsReallyVisible() && IsUpdateMode() )
2709 ImplInitExtraField( true );
2714 tools::Long
Ruler::GetPageOffset() const
2716 return mpData
->nPageOff
;
2719 tools::Long
Ruler::GetNullOffset() const
2721 return mpData
->nNullOff
;
2724 tools::Long
Ruler::GetMargin1() const
2726 return mpData
->nMargin1
;
2729 tools::Long
Ruler::GetMargin2() const
2731 return mpData
->nMargin2
;
2734 const RulerUnitData
& Ruler::GetCurrentRulerUnit() const
2736 return aImplRulerUnitTab
[mnUnitIndex
];
2739 void Ruler::DrawTicks()
2742 Invalidate(InvalidateFlags::NoErase
);
2745 uno::Reference
< XAccessible
> Ruler::CreateAccessible()
2747 vcl::Window
* pParent
= GetAccessibleParentWindow();
2748 OSL_ENSURE( pParent
, "-SvxRuler::CreateAccessible(): No Parent!" );
2749 uno::Reference
< XAccessible
> xAccParent
= pParent
->GetAccessible();
2750 if( xAccParent
.is() )
2752 // MT: Fixed compiler issue because the address from a temporary object was used.
2753 // BUT: Should it really be a Pointer, instead of const&???
2755 if ( mnWinStyle
& WB_HORZ
)
2757 aStr
= SvtResId(STR_SVT_ACC_RULER_HORZ_NAME
);
2761 aStr
= SvtResId(STR_SVT_ACC_RULER_VERT_NAME
);
2763 mxAccContext
= new SvtRulerAccessible( xAccParent
, *this, aStr
);
2764 SetAccessible(mxAccContext
);
2765 return mxAccContext
;
2768 return uno::Reference
< XAccessible
>();
2771 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */