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::lang
;
41 using namespace ::com::sun::star::accessibility
;
44 #define RULER_RESIZE_OFF 4
45 #define RULER_MIN_SIZE 3
47 #define RULER_VAR_SIZE 8
49 #define RULER_UPDATE_LINES 0x01
51 #define RULER_CLIP 150
53 #define RULER_UNIT_MM 0
54 #define RULER_UNIT_CM 1
55 #define RULER_UNIT_M 2
56 #define RULER_UNIT_KM 3
57 #define RULER_UNIT_INCH 4
58 #define RULER_UNIT_FOOT 5
59 #define RULER_UNIT_MILE 6
60 #define RULER_UNIT_POINT 7
61 #define RULER_UNIT_PICA 8
62 #define RULER_UNIT_CHAR 9
63 #define RULER_UNIT_LINE 10
64 #define RULER_UNIT_COUNT 11
69 * Pre-calculates glyph items for rText on rRenderContext. Subsequent calls
70 * avoid the calculation and just return a pointer to rTextGlyphs.
72 SalLayoutGlyphs
* lcl_GetRulerTextGlyphs(const vcl::RenderContext
& rRenderContext
, const OUString
& rText
,
73 SalLayoutGlyphs
& rTextGlyphs
)
75 if (rTextGlyphs
.IsValid())
76 // Use pre-calculated result.
79 // Calculate glyph items.
81 std::unique_ptr
<SalLayout
> pLayout
= rRenderContext
.ImplLayout(
82 rText
, 0, rText
.getLength(), Point(0, 0), 0, {}, {}, SalLayoutFlags::GlyphItemsOnly
);
86 // Remember the calculation result.
87 rTextGlyphs
= pLayout
->GetGlyphs();
98 std::vector
<RulerLine
> pLines
;
99 std::vector
<RulerBorder
> pBorders
;
100 std::vector
<RulerIndent
> pIndents
;
101 std::vector
<RulerTab
> pTabs
;
103 tools::Long nNullVirOff
;
104 tools::Long nRulVirOff
;
105 tools::Long nRulWidth
;
106 tools::Long nPageOff
;
107 tools::Long nPageWidth
;
108 tools::Long nNullOff
;
109 tools::Long nMargin1
;
110 tools::Long nMargin2
;
111 // In this context, "frame margin" means paragraph margins (indents)
112 tools::Long nLeftFrameMargin
;
113 tools::Long nRightFrameMargin
;
114 RulerMarginStyle nMargin1Style
;
115 RulerMarginStyle nMargin2Style
;
123 ImplRulerData::ImplRulerData() :
132 nLeftFrameMargin (0),
133 nRightFrameMargin (0),
134 nMargin1Style (RulerMarginStyle::NONE
),
135 nMargin2Style (RulerMarginStyle::NONE
),
136 bAutoPageWidth (true), // Page width == EditWin width
141 const RulerUnitData aImplRulerUnitTab
[RULER_UNIT_COUNT
] =
143 { MapUnit::Map100thMM
, 100, 25.0, 25.0, 50.0, 100.0, " mm" }, // MM
144 { MapUnit::Map100thMM
, 1000, 100.0, 500.0, 1000.0, 1000.0, " cm" }, // CM
145 { MapUnit::MapMM
, 1000, 10.0, 250.0, 500.0, 1000.0, " m" }, // M
146 { MapUnit::MapCM
, 100000, 12500.0, 25000.0, 50000.0, 100000.0, " km" }, // KM
147 { MapUnit::Map1000thInch
, 1000, 62.5, 125.0, 500.0, 1000.0, "\"" }, // INCH
148 { MapUnit::Map100thInch
, 1200, 120.0, 120.0, 600.0, 1200.0, "'" }, // FOOT
149 { MapUnit::Map10thInch
, 633600, 63360.0, 63360.0, 316800.0, 633600.0, " miles" }, // MILE
150 { MapUnit::MapPoint
, 1, 12.0, 12.0, 12.0, 36.0, " pt" }, // POINT
151 { MapUnit::Map100thMM
, 423, 423.0, 423.0, 423.0, 846.0, " pc" }, // PICA
152 { MapUnit::Map100thMM
, 371, 371.0, 371.0, 371.0, 743.0, " ch" }, // CHAR
153 { MapUnit::Map100thMM
, 551, 551.0, 551.0, 551.0, 1102.0, " li" } // LINE
156 static RulerTabData ruler_tab
=
158 0, // DPIScaleFactor to be set
159 7, // ruler_tab_width
160 6, // ruler_tab_height
161 2, // ruler_tab_height2
162 2, // ruler_tab_width2
163 8, // ruler_tab_cwidth
164 4, // ruler_tab_cwidth2
165 4, // ruler_tab_cwidth3
166 2, // ruler_tab_cwidth4
167 4, // ruler_tab_dheight
168 1, // ruler_tab_dheight2
169 5, // ruler_tab_dwidth
170 3, // ruler_tab_dwidth2
171 3, // ruler_tab_dwidth3
172 1, // ruler_tab_dwidth4
173 5 // ruler_tab_textoff
176 void Ruler::ImplInit( WinBits nWinBits
)
178 // Set default WinBits
179 if ( !(nWinBits
& WB_VERT
) )
183 // RTL: no UI mirroring for horizontal rulers, because
184 // the document is also not mirrored
188 // Initialize variables
189 mnWinStyle
= nWinBits
; // Window-Style
190 mnBorderOff
= 0; // Border-Offset
191 mnWinOff
= 0; // EditWinOffset
192 mnWinWidth
= 0; // EditWinWidth
193 mnWidth
= 0; // Window width
194 mnHeight
= 0; // Window height
195 mnVirOff
= 0; // Offset of VirtualDevice from top-left corner
196 mnVirWidth
= 0; // width or height from VirtualDevice
197 mnVirHeight
= 0; // height of width from VirtualDevice
198 mnDragPos
= 0; // Drag-Position (Null point)
199 mnDragAryPos
= 0; // Drag-Array-Index
200 mnDragSize
= RulerDragSize::Move
; // Did size change at dragging
201 mnDragModifier
= 0; // Modifier key at dragging
202 mnExtraStyle
= 0; // Style of Extra field
205 mbCalc
= true; // Should recalculate page width
206 mbFormat
= true; // Should redraw
207 mbDrag
= false; // Currently at dragging
208 mbDragDelete
= false; // Has mouse left the dragging area
209 mbDragCanceled
= false; // Dragging cancelled?
210 mbAutoWinWidth
= true; // EditWinWidth == RulerWidth
211 mbActive
= true; // Is ruler active
212 mnUpdateFlags
= 0; // What needs to be updated
213 mpData
= mpSaveData
.get(); // Pointer to normal data
214 meExtraType
= RulerExtra::DontKnow
; // What is in extra field
215 meDragType
= RulerType::DontKnow
; // Which element is dragged
218 mnUnitIndex
= RULER_UNIT_CM
;
219 meUnit
= FieldUnit::CM
;
220 maZoom
= Fraction( 1, 1 );
222 // Recalculate border widths
223 if ( nWinBits
& WB_BORDER
)
229 ImplInitSettings( true, true, true );
231 // Setup the default size
232 tools::Rectangle aRect
;
233 GetOutDev()->GetTextBoundRect( aRect
, "0123456789" );
234 tools::Long nDefHeight
= aRect
.GetHeight() + RULER_OFF
* 2 + ruler_tab
.textoff
* 2 + mnBorderWidth
;
237 if ( nWinBits
& WB_HORZ
)
238 aDefSize
.setHeight( nDefHeight
);
240 aDefSize
.setWidth( nDefHeight
);
241 SetOutputSizePixel( aDefSize
);
242 SetType(WindowType::RULER
);
245 Ruler::Ruler( vcl::Window
* pParent
, WinBits nWinStyle
) :
246 Window( pParent
, nWinStyle
& WB_3DLOOK
),
247 maVirDev( VclPtr
<VirtualDevice
>::Create(*GetOutDev()) ),
248 maMapMode( MapUnit::Map100thMM
),
249 mpSaveData(new ImplRulerData
),
251 mpDragData(new ImplRulerData
)
253 // Check to see if the ruler constructor has
254 // already been called before otherwise
255 // we end up with over-scaled elements
256 if (ruler_tab
.DPIScaleFactor
== 0)
258 ruler_tab
.DPIScaleFactor
= GetDPIScaleFactor();
259 ruler_tab
.width
*= ruler_tab
.DPIScaleFactor
;
260 ruler_tab
.height
*= ruler_tab
.DPIScaleFactor
;
261 ruler_tab
.height2
*= ruler_tab
.DPIScaleFactor
;
262 ruler_tab
.width2
*= ruler_tab
.DPIScaleFactor
;
263 ruler_tab
.cwidth
*= ruler_tab
.DPIScaleFactor
;
264 ruler_tab
.cwidth2
*= ruler_tab
.DPIScaleFactor
;
265 ruler_tab
.cwidth3
*= ruler_tab
.DPIScaleFactor
;
266 ruler_tab
.cwidth4
*= ruler_tab
.DPIScaleFactor
;
267 ruler_tab
.dheight
*= ruler_tab
.DPIScaleFactor
;
268 ruler_tab
.dheight2
*= ruler_tab
.DPIScaleFactor
;
269 ruler_tab
.dwidth
*= ruler_tab
.DPIScaleFactor
;
270 ruler_tab
.dwidth2
*= ruler_tab
.DPIScaleFactor
;
271 ruler_tab
.dwidth3
*= ruler_tab
.DPIScaleFactor
;
272 ruler_tab
.dwidth4
*= ruler_tab
.DPIScaleFactor
;
273 ruler_tab
.textoff
*= ruler_tab
.DPIScaleFactor
;
277 ImplInit( nWinStyle
);
285 void Ruler::dispose()
289 mxAccContext
.clear();
293 void Ruler::ImplVDrawLine(vcl::RenderContext
& rRenderContext
, tools::Long nX1
, tools::Long nY1
, tools::Long nX2
, tools::Long nY2
)
295 if ( nX1
< -RULER_CLIP
)
298 if ( nX2
< -RULER_CLIP
)
301 tools::Long nClip
= mnVirWidth
+ RULER_CLIP
;
309 if ( mnWinStyle
& WB_HORZ
)
310 rRenderContext
.DrawLine( Point( nX1
, nY1
), Point( nX2
, nY2
) );
312 rRenderContext
.DrawLine( Point( nY1
, nX1
), Point( nY2
, nX2
) );
315 void Ruler::ImplVDrawRect(vcl::RenderContext
& rRenderContext
, tools::Long nX1
, tools::Long nY1
, tools::Long nX2
, tools::Long nY2
)
317 if ( nX1
< -RULER_CLIP
)
320 if ( nX2
< -RULER_CLIP
)
323 tools::Long nClip
= mnVirWidth
+ RULER_CLIP
;
331 if ( mnWinStyle
& WB_HORZ
)
332 rRenderContext
.DrawRect(tools::Rectangle(nX1
, nY1
, nX2
, nY2
));
334 rRenderContext
.DrawRect(tools::Rectangle(nY1
, nX1
, nY2
, nX2
));
337 void Ruler::ImplVDrawText(vcl::RenderContext
& rRenderContext
, tools::Long nX
, tools::Long nY
, const OUString
& rText
, tools::Long nMin
, tools::Long nMax
)
339 tools::Rectangle aRect
;
340 SalLayoutGlyphs
* pTextLayout
341 = lcl_GetRulerTextGlyphs(rRenderContext
, rText
, maTextGlyphs
[rText
]);
342 rRenderContext
.GetTextBoundRect(aRect
, rText
, 0, 0, -1, 0, {}, {}, pTextLayout
);
344 tools::Long nShiftX
= ( aRect
.GetWidth() / 2 ) + aRect
.Left();
345 tools::Long nShiftY
= ( aRect
.GetHeight() / 2 ) + aRect
.Top();
347 if ( (nX
> -RULER_CLIP
) && (nX
< mnVirWidth
+ RULER_CLIP
) && ( nX
< nMax
- nShiftX
) && ( nX
> nMin
+ nShiftX
) )
349 if ( mnWinStyle
& WB_HORZ
)
350 rRenderContext
.DrawText(Point(nX
- nShiftX
, nY
- nShiftY
), rText
, 0, -1, nullptr,
351 nullptr, pTextLayout
);
353 rRenderContext
.DrawText(Point(nY
- nShiftX
, nX
- nShiftY
), rText
, 0, -1, nullptr,
354 nullptr, pTextLayout
);
358 void Ruler::ImplInvertLines(vcl::RenderContext
& rRenderContext
)
361 if (mpData
->pLines
.empty() || !mbActive
|| mbDrag
|| mbFormat
|| (mnUpdateFlags
& RULER_UPDATE_LINES
) )
364 tools::Long nNullWinOff
= mpData
->nNullVirOff
+ mnVirOff
;
365 tools::Long nRulX1
= mpData
->nRulVirOff
+ mnVirOff
;
366 tools::Long nRulX2
= nRulX1
+ mpData
->nRulWidth
;
367 tools::Long nY
= (RULER_OFF
* 2) + mnVirHeight
- 1;
369 // Calculate rectangle
370 tools::Rectangle aRect
;
371 if (mnWinStyle
& WB_HORZ
)
372 aRect
.SetBottom( nY
);
374 aRect
.SetRight( nY
);
377 for (const RulerLine
& rLine
: mpData
->pLines
)
379 const tools::Long n
= rLine
.nPos
+ nNullWinOff
;
380 if ((n
>= nRulX1
) && (n
< nRulX2
))
382 if (mnWinStyle
& WB_HORZ
)
390 aRect
.SetBottom( n
);
392 tools::Rectangle aTempRect
= aRect
;
394 if (mnWinStyle
& WB_HORZ
)
395 aTempRect
.SetBottom( RULER_OFF
- 1 );
397 aTempRect
.SetRight( RULER_OFF
- 1 );
399 rRenderContext
.Erase(aTempRect
);
401 if (mnWinStyle
& WB_HORZ
)
403 aTempRect
.SetBottom( aRect
.Bottom() );
404 aTempRect
.SetTop( aTempRect
.Bottom() - RULER_OFF
+ 1 );
408 aTempRect
.SetRight( aRect
.Right() );
409 aTempRect
.SetLeft( aTempRect
.Right() - RULER_OFF
+ 1 );
411 rRenderContext
.Erase(aTempRect
);
412 GetOutDev()->Invert(aRect
);
418 void Ruler::ImplDrawTicks(vcl::RenderContext
& rRenderContext
, tools::Long nMin
, tools::Long nMax
, tools::Long nStart
, tools::Long nTop
, tools::Long nBottom
)
420 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
421 double nCenter
= nTop
+ ((nBottom
- nTop
) / 2);
423 tools::Long nTickLength3
= (nBottom
- nTop
) * 0.5;
424 tools::Long nTickLength2
= nTickLength3
* 0.66;
425 tools::Long nTickLength1
= nTickLength2
* 0.66;
427 tools::Long nScale
= ruler_tab
.DPIScaleFactor
;
428 tools::Long DPIOffset
= nScale
- 1;
430 double nTick4
= aImplRulerUnitTab
[mnUnitIndex
].nTick4
;
432 double nTickCount
= aImplRulerUnitTab
[mnUnitIndex
].nTick1
/ nScale
;
433 double nTickUnit
= 0;
434 tools::Long nTickWidth
;
435 bool bNoTicks
= false;
437 Size aPixSize
= rRenderContext
.LogicToPixel(Size(nTick4
, nTick4
), maMapMode
);
439 if (mnUnitIndex
== RULER_UNIT_CHAR
)
441 if (mnCharWidth
== 0)
443 nTick4
= mnCharWidth
* 2;
444 nTick2
= mnCharWidth
;
445 nTickCount
= mnCharWidth
;
446 nTickUnit
= mnCharWidth
;
448 else if (mnUnitIndex
== RULER_UNIT_LINE
)
450 if (mnLineHeight
== 0)
452 nTick4
= mnLineHeight
* 2;
453 nTick2
= mnLineHeight
;
454 nTickUnit
= mnLineHeight
;
455 nTickCount
= mnLineHeight
;
458 if (mnWinStyle
& WB_HORZ
)
460 nTickWidth
= aPixSize
.Width();
464 vcl::Font aFont
= rRenderContext
.GetFont();
465 if (mnWinStyle
& WB_RIGHT_ALIGNED
)
466 aFont
.SetOrientation(2700_deg10
);
468 aFont
.SetOrientation(900_deg10
);
469 rRenderContext
.SetFont(aFont
);
470 nTickWidth
= aPixSize
.Height();
473 tools::Long nMaxWidth
= rRenderContext
.PixelToLogic(Size(mpData
->nPageWidth
, 0), maMapMode
).Width();
475 nMaxWidth
= -nMaxWidth
;
477 if ((mnUnitIndex
== RULER_UNIT_CHAR
) || (mnUnitIndex
== RULER_UNIT_LINE
))
478 nMaxWidth
/= nTickUnit
;
480 nMaxWidth
/= aImplRulerUnitTab
[mnUnitIndex
].nTickUnit
;
482 OUString aNumString
= OUString::number(nMaxWidth
);
483 tools::Long nTxtWidth
= rRenderContext
.GetTextWidth( aNumString
);
484 const tools::Long nTextOff
= 4;
486 // Determine the number divider for ruler drawn numbers - means which numbers
487 // should be shown on the ruler and which should be skipped because the ruler
488 // is not big enough to draw them
489 if (nTickWidth
< nTxtWidth
+ nTextOff
)
491 // Calculate the scale of the ruler
492 tools::Long nMulti
= 1;
493 tools::Long nOrgTick4
= nTick4
;
495 while (nTickWidth
< nTxtWidth
+ nTextOff
)
497 tools::Long nOldMulti
= nMulti
;
500 else if (nMulti
< 10)
502 else if (nMulti
< 100)
504 else if (nMulti
< 1000)
509 // Overflow - in this case don't draw ticks and exit
510 if (nMulti
< nOldMulti
)
516 nTick4
= nOrgTick4
* nMulti
;
517 aPixSize
= rRenderContext
.LogicToPixel(Size(nTick4
, nTick4
), maMapMode
);
518 if (mnWinStyle
& WB_HORZ
)
519 nTickWidth
= aPixSize
.Width();
521 nTickWidth
= aPixSize
.Height();
527 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
537 if ((mnUnitIndex
!= RULER_UNIT_CHAR
) && (mnUnitIndex
!= RULER_UNIT_LINE
))
539 nTick2
= aImplRulerUnitTab
[mnUnitIndex
].nTick2
;
540 nTick3
= aImplRulerUnitTab
[mnUnitIndex
].nTick3
;
545 nTickGapSize
= rRenderContext
.LogicToPixel(Size(nTickCount
, nTickCount
), maMapMode
);
546 tools::Long nTickGap1
= mnWinStyle
& WB_HORZ
? nTickGapSize
.Width() : nTickGapSize
.Height();
547 nTickGapSize
= rRenderContext
.LogicToPixel(Size(nTick2
, nTick2
), maMapMode
);
548 tools::Long nTickGap2
= mnWinStyle
& WB_HORZ
? nTickGapSize
.Width() : nTickGapSize
.Height();
549 nTickGapSize
= rRenderContext
.LogicToPixel(Size(nTick3
, nTick3
), maMapMode
);
550 tools::Long nTickGap3
= mnWinStyle
& WB_HORZ
? nTickGapSize
.Width() : nTickGapSize
.Height();
552 while (((nStart
- n
) >= nMin
) || ((nStart
+ n
) <= nMax
))
559 // 0 is only painted when Margin1 is not equal to zero
560 if ((mpData
->nMargin1Style
& RulerMarginStyle::Invisible
) || (mpData
->nMargin1
!= 0))
563 ImplVDrawText(rRenderContext
, nStart
, nCenter
, aNumString
);
569 aPixSize
= rRenderContext
.LogicToPixel(Size(nTick
, nTick
), maMapMode
);
571 if (mnWinStyle
& WB_HORZ
)
572 n
= aPixSize
.Width();
574 n
= aPixSize
.Height();
576 // Tick4 - Output (Text)
577 double aStep
= nTick
/ nTick4
;
578 double aRest
= std::abs(aStep
- std::floor(aStep
));
579 double nAcceptanceDelta
= 0.0001;
580 rRenderContext
.SetFillColor(rStyleSettings
.GetShadowColor());
582 if (aRest
< nAcceptanceDelta
)
584 if ((mnUnitIndex
== RULER_UNIT_CHAR
) || (mnUnitIndex
== RULER_UNIT_LINE
))
585 aNumString
= OUString::number(nTick
/ nTickUnit
);
587 aNumString
= OUString::number(nTick
/ aImplRulerUnitTab
[mnUnitIndex
].nTickUnit
);
589 tools::Long nHorizontalLocation
= nStart
+ n
;
590 ImplVDrawText(rRenderContext
, nHorizontalLocation
, nCenter
, aNumString
, nMin
, nMax
);
592 if (nMin
< nHorizontalLocation
&& nHorizontalLocation
< nMax
)
594 ImplVDrawRect(rRenderContext
, nHorizontalLocation
, nBottom
- 1 * nScale
, nHorizontalLocation
+ DPIOffset
, nBottom
);
595 ImplVDrawRect(rRenderContext
, nHorizontalLocation
, nTop
, nHorizontalLocation
+ DPIOffset
, nTop
+ 1 * nScale
);
598 nHorizontalLocation
= nStart
- n
;
599 ImplVDrawText(rRenderContext
, nHorizontalLocation
, nCenter
, aNumString
, nMin
, nMax
);
601 if (nMin
< nHorizontalLocation
&& nHorizontalLocation
< nMax
)
603 ImplVDrawRect(rRenderContext
, nHorizontalLocation
, nBottom
,
604 nHorizontalLocation
+ DPIOffset
, nBottom
- 1 * nScale
);
605 ImplVDrawRect(rRenderContext
, nHorizontalLocation
, nTop
,
606 nHorizontalLocation
+ DPIOffset
, nTop
+ 1 * nScale
);
609 // Tick/Tick2 - Output (Strokes)
612 tools::Long nTickLength
= nTickLength1
;
614 aStep
= (nTick
/ nTick2
);
615 aRest
= std::abs(aStep
- std::floor(aStep
));
616 if (aRest
< nAcceptanceDelta
)
617 nTickLength
= nTickLength2
;
619 aStep
= (nTick
/ nTick3
);
620 aRest
= std::abs(aStep
- std::floor(aStep
));
621 if (aRest
< nAcceptanceDelta
)
622 nTickLength
= nTickLength3
;
624 if ((nTickLength
== nTickLength1
&& nTickGap1
> 6) ||
625 (nTickLength
== nTickLength2
&& nTickGap2
> 6) ||
626 (nTickLength
== nTickLength3
&& nTickGap3
> 6))
628 tools::Long nT1
= nCenter
- (nTickLength
/ 2.0);
629 tools::Long nT2
= nT1
+ nTickLength
- 1;
635 ImplVDrawRect(rRenderContext
, nT
, nT1
, nT
+ DPIOffset
, nT2
);
638 ImplVDrawRect(rRenderContext
, nT
, nT1
, nT
+ DPIOffset
, nT2
);
646 void Ruler::ImplDrawBorders(vcl::RenderContext
& rRenderContext
, tools::Long nMin
, tools::Long nMax
, tools::Long nVirTop
, tools::Long nVirBottom
)
648 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
655 for (std::vector
<RulerBorder
>::size_type i
= 0; i
< mpData
->pBorders
.size(); i
++)
657 if (mpData
->pBorders
[i
].nStyle
& RulerBorderStyle::Invisible
)
660 n1
= mpData
->pBorders
[i
].nPos
+ mpData
->nNullVirOff
;
661 n2
= n1
+ mpData
->pBorders
[i
].nWidth
;
663 if (((n1
>= nMin
) && (n1
<= nMax
)) || ((n2
>= nMin
) && (n2
<= nMax
)))
667 rRenderContext
.SetLineColor();
668 rRenderContext
.SetFillColor(rStyleSettings
.GetFaceColor());
669 ImplVDrawRect(rRenderContext
, n1
, nVirTop
, n2
, nVirBottom
);
671 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
672 ImplVDrawLine(rRenderContext
, n1
+ 1, nVirTop
, n1
+ 1, nVirBottom
);
673 ImplVDrawLine(rRenderContext
, n1
, nVirTop
, n2
, nVirTop
);
675 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
676 ImplVDrawLine(rRenderContext
, n1
, nVirTop
, n1
, nVirBottom
);
677 ImplVDrawLine(rRenderContext
, n1
, nVirBottom
, n2
, nVirBottom
);
678 ImplVDrawLine(rRenderContext
, n2
- 1, nVirTop
, n2
- 1, nVirBottom
);
680 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
681 ImplVDrawLine(rRenderContext
, n2
, nVirTop
, n2
, nVirBottom
);
683 if (mpData
->pBorders
[i
].nStyle
& RulerBorderStyle::Variable
)
685 if (n2
- n1
> RULER_VAR_SIZE
+ 4)
687 nTemp1
= n1
+ (((n2
- n1
+ 1) - RULER_VAR_SIZE
) / 2);
688 nTemp2
= nVirTop
+ (((nVirBottom
- nVirTop
+ 1) - RULER_VAR_SIZE
) / 2);
689 tools::Long nTemp3
= nTemp1
+ RULER_VAR_SIZE
- 1;
690 tools::Long nTemp4
= nTemp2
+ RULER_VAR_SIZE
- 1;
691 tools::Long nTempY
= nTemp2
;
693 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
694 while (nTempY
<= nTemp4
)
696 ImplVDrawLine(rRenderContext
, nTemp1
, nTempY
, nTemp3
, nTempY
);
701 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
702 while (nTempY
<= nTemp4
)
704 ImplVDrawLine(rRenderContext
, nTemp1
, nTempY
, nTemp3
, nTempY
);
710 if (mpData
->pBorders
[i
].nStyle
& RulerBorderStyle::Sizeable
)
712 if (n2
- n1
> RULER_VAR_SIZE
+ 10)
714 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
715 ImplVDrawLine(rRenderContext
, n1
+ 4, nVirTop
+ 3, n1
+ 4, nVirBottom
- 3);
716 ImplVDrawLine(rRenderContext
, n2
- 5, nVirTop
+ 3, n2
- 5, nVirBottom
- 3);
717 rRenderContext
.SetLineColor(rStyleSettings
.GetLightColor());
718 ImplVDrawLine(rRenderContext
, n1
+ 5, nVirTop
+ 3, n1
+ 5, nVirBottom
- 3);
719 ImplVDrawLine(rRenderContext
, n2
- 4, nVirTop
+ 3, n2
- 4, nVirBottom
- 3);
725 n
= n1
+ ((n2
- n1
) / 2);
726 rRenderContext
.SetLineColor(rStyleSettings
.GetShadowColor());
728 ImplVDrawLine(rRenderContext
, n
- 1, nVirTop
, n
- 1, nVirBottom
);
729 ImplVDrawLine(rRenderContext
, n
+ 1, nVirTop
, n
+ 1, nVirBottom
);
730 rRenderContext
.SetLineColor();
731 rRenderContext
.SetFillColor(rStyleSettings
.GetWindowColor());
732 ImplVDrawRect(rRenderContext
, n
, nVirTop
, n
, nVirBottom
);
738 void Ruler::ImplDrawIndent(vcl::RenderContext
& rRenderContext
, const tools::Polygon
& rPoly
, bool bIsHit
)
740 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
742 rRenderContext
.SetLineColor(rStyleSettings
.GetDarkShadowColor());
743 rRenderContext
.SetFillColor(bIsHit
? rStyleSettings
.GetDarkShadowColor() : rStyleSettings
.GetWorkspaceColor());
744 tools::Polygon
aPolygon(rPoly
);
745 aPolygon
.Optimize(PolyOptimizeFlags::CLOSE
);
746 rRenderContext
.DrawPolygon(aPolygon
);
749 void Ruler::ImplDrawIndents(vcl::RenderContext
& rRenderContext
, tools::Long nMin
, tools::Long nMax
, tools::Long nVirTop
, tools::Long nVirBottom
)
752 tools::Long nIndentHeight
= (mnVirHeight
/ 2) - 1;
753 tools::Long nIndentWidth2
= nIndentHeight
-3;
755 tools::Polygon
aPoly(5);
757 for (std::vector
<RulerIndent
>::size_type j
= 0; j
< mpData
->pIndents
.size(); j
++)
759 if (mpData
->pIndents
[j
].bInvisible
)
762 RulerIndentStyle nIndentStyle
= mpData
->pIndents
[j
].nStyle
;
764 n
= mpData
->pIndents
[j
].nPos
+mpData
->nNullVirOff
;
766 if ((n
>= nMin
) && (n
<= nMax
))
768 if (nIndentStyle
== RulerIndentStyle::Bottom
)
770 aPoly
.SetPoint(Point(n
+ 0, nVirBottom
- nIndentHeight
), 0);
771 aPoly
.SetPoint(Point(n
- nIndentWidth2
, nVirBottom
- 3), 1);
772 aPoly
.SetPoint(Point(n
- nIndentWidth2
, nVirBottom
), 2);
773 aPoly
.SetPoint(Point(n
+ nIndentWidth2
, nVirBottom
), 3);
774 aPoly
.SetPoint(Point(n
+ nIndentWidth2
, nVirBottom
- 3), 4);
778 aPoly
.SetPoint(Point(n
+ 0, nVirTop
+ nIndentHeight
), 0);
779 aPoly
.SetPoint(Point(n
- nIndentWidth2
, nVirTop
+ 3), 1);
780 aPoly
.SetPoint(Point(n
- nIndentWidth2
, nVirTop
), 2);
781 aPoly
.SetPoint(Point(n
+ nIndentWidth2
, nVirTop
), 3);
782 aPoly
.SetPoint(Point(n
+ nIndentWidth2
, nVirTop
+ 3), 4);
785 if (0 == (mnWinStyle
& WB_HORZ
))
788 for (sal_uInt16 i
= 0; i
< 5; i
++)
791 Point
aSet(nVirBottom
- aTmp
.Y(), aTmp
.X());
796 if (mxCurrentHitTest
!= nullptr && mxCurrentHitTest
->eType
== RulerType::Indent
)
798 bIsHit
= mxCurrentHitTest
->nAryPos
== j
;
800 else if(mbDrag
&& meDragType
== RulerType::Indent
)
802 bIsHit
= mnDragAryPos
== j
;
804 ImplDrawIndent(rRenderContext
, aPoly
, bIsHit
);
809 static void ImplCenterTabPos(Point
& rPos
, sal_uInt16 nTabStyle
)
811 bool bRTL
= 0 != (nTabStyle
& RULER_TAB_RTL
);
812 nTabStyle
&= RULER_TAB_STYLE
;
813 rPos
.AdjustY(ruler_tab
.height
/2 );
815 if ( (!bRTL
&& nTabStyle
== RULER_TAB_LEFT
) ||
816 ( bRTL
&& nTabStyle
== RULER_TAB_RIGHT
) )
818 rPos
.AdjustX( -(ruler_tab
.width
/ 2) );
820 else if ( (!bRTL
&& nTabStyle
== RULER_TAB_RIGHT
) ||
821 ( bRTL
&& nTabStyle
== RULER_TAB_LEFT
) )
823 rPos
.AdjustX(ruler_tab
.width
/ 2 );
827 static void lcl_RotateRect_Impl(tools::Rectangle
& rRect
, const tools::Long nReference
, bool bRightAligned
)
832 tools::Rectangle
aTmp(rRect
);
833 rRect
.SetTop( aTmp
.Left() );
834 rRect
.SetBottom( aTmp
.Right() );
835 rRect
.SetLeft( aTmp
.Top() );
836 rRect
.SetRight( aTmp
.Bottom() );
840 tools::Long nRef
= 2 * nReference
;
841 rRect
.SetLeft( nRef
- rRect
.Left() );
842 rRect
.SetRight( nRef
- rRect
.Right() );
846 static void ImplDrawRulerTab(vcl::RenderContext
& rRenderContext
, const Point
& rPos
,
847 sal_uInt16 nStyle
, WinBits nWinBits
)
849 if (nStyle
& RULER_STYLE_INVISIBLE
)
852 sal_uInt16 nTabStyle
= nStyle
& RULER_TAB_STYLE
;
853 bool bRTL
= 0 != (nStyle
& RULER_TAB_RTL
);
855 // Scale by the screen DPI scaling factor
856 // However when doing this some of the rectangles
857 // drawn become asymmetric due to the +1 offsets
858 sal_uInt16 DPIOffset
= rRenderContext
.GetDPIScaleFactor() - 1;
860 // A tabstop is drawn using three rectangles
861 tools::Rectangle aRect1
; // A horizontal short line
862 tools::Rectangle aRect2
; // A vertical short line
863 tools::Rectangle aRect3
; // A small square
867 if (nTabStyle
== RULER_TAB_DEFAULT
)
869 aRect1
.SetLeft( rPos
.X() - ruler_tab
.dwidth2
+ 1 );
870 aRect1
.SetTop( rPos
.Y() - ruler_tab
.dheight2
+ 1 );
871 aRect1
.SetRight( rPos
.X() - ruler_tab
.dwidth2
+ ruler_tab
.dwidth
+ DPIOffset
);
872 aRect1
.SetBottom( rPos
.Y() );
874 aRect2
.SetLeft( rPos
.X() - ruler_tab
.dwidth2
+ ruler_tab
.dwidth3
);
875 aRect2
.SetTop( rPos
.Y() - ruler_tab
.dheight
+ 1 );
876 aRect2
.SetRight( rPos
.X() - ruler_tab
.dwidth2
+ ruler_tab
.dwidth3
+ ruler_tab
.dwidth4
- 1 );
877 aRect2
.SetBottom( rPos
.Y() );
880 else if ((!bRTL
&& nTabStyle
== RULER_TAB_LEFT
) || (bRTL
&& nTabStyle
== RULER_TAB_RIGHT
))
882 aRect1
.SetLeft( rPos
.X() );
883 aRect1
.SetTop( rPos
.Y() - ruler_tab
.height2
+ 1 );
884 aRect1
.SetRight( rPos
.X() + ruler_tab
.width
- 1 );
885 aRect1
.SetBottom( rPos
.Y() );
887 aRect2
.SetLeft( rPos
.X() );
888 aRect2
.SetTop( rPos
.Y() - ruler_tab
.height
+ 1 );
889 aRect2
.SetRight( rPos
.X() + ruler_tab
.width2
- 1 );
890 aRect2
.SetBottom( rPos
.Y() );
892 else if ((!bRTL
&& nTabStyle
== RULER_TAB_RIGHT
) || (bRTL
&& nTabStyle
== RULER_TAB_LEFT
))
894 aRect1
.SetLeft( rPos
.X() - ruler_tab
.width
+ 1 );
895 aRect1
.SetTop( rPos
.Y() - ruler_tab
.height2
+ 1 );
896 aRect1
.SetRight( rPos
.X() );
897 aRect1
.SetBottom( rPos
.Y() );
899 aRect2
.SetLeft( rPos
.X() - ruler_tab
.width2
+ 1 );
900 aRect2
.SetTop( rPos
.Y() - ruler_tab
.height
+ 1 );
901 aRect2
.SetRight( rPos
.X() );
902 aRect2
.SetBottom( rPos
.Y() );
906 aRect1
.SetLeft( rPos
.X() - ruler_tab
.cwidth2
+ 1 );
907 aRect1
.SetTop( rPos
.Y() - ruler_tab
.height2
+ 1 );
908 aRect1
.SetRight( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth
+ DPIOffset
);
909 aRect1
.SetBottom( rPos
.Y() );
911 aRect2
.SetLeft( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth3
);
912 aRect2
.SetTop( rPos
.Y() - ruler_tab
.height
+ 1 );
913 aRect2
.SetRight( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth3
+ ruler_tab
.cwidth4
- 1 );
914 aRect2
.SetBottom( rPos
.Y() );
916 if (nTabStyle
== RULER_TAB_DECIMAL
)
918 aRect3
.SetLeft( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth
- 1 );
919 aRect3
.SetTop( rPos
.Y() - ruler_tab
.height
+ 1 + 1 - DPIOffset
);
920 aRect3
.SetRight( rPos
.X() - ruler_tab
.cwidth2
+ ruler_tab
.cwidth
+ DPIOffset
);
921 aRect3
.SetBottom( rPos
.Y() - ruler_tab
.height
+ 1 + 2 );
924 if (0 == (nWinBits
& WB_HORZ
))
926 bool bRightAligned
= 0 != (nWinBits
& WB_RIGHT_ALIGNED
);
927 lcl_RotateRect_Impl(aRect1
, rPos
.Y(), bRightAligned
);
928 lcl_RotateRect_Impl(aRect2
, rPos
.Y(), bRightAligned
);
929 lcl_RotateRect_Impl(aRect3
, rPos
.Y(), bRightAligned
);
931 rRenderContext
.DrawRect(aRect1
);
932 rRenderContext
.DrawRect(aRect2
);
934 if (!aRect3
.IsEmpty())
935 rRenderContext
.DrawRect(aRect3
);
938 void Ruler::ImplDrawTab(vcl::RenderContext
& rRenderContext
, const Point
& rPos
, sal_uInt16 nStyle
)
940 if (nStyle
& RULER_STYLE_INVISIBLE
)
943 rRenderContext
.SetLineColor();
945 if (nStyle
& RULER_STYLE_DONTKNOW
)
946 rRenderContext
.SetFillColor(rRenderContext
.GetSettings().GetStyleSettings().GetFaceColor());
948 rRenderContext
.SetFillColor(rRenderContext
.GetSettings().GetStyleSettings().GetDarkShadowColor());
950 if (mpData
->bTextRTL
)
951 nStyle
|= RULER_TAB_RTL
;
953 ImplDrawRulerTab(rRenderContext
, rPos
, nStyle
, GetStyle());
956 void Ruler::ImplDrawTabs(vcl::RenderContext
& rRenderContext
, tools::Long nMin
, tools::Long nMax
, tools::Long nVirTop
, tools::Long nVirBottom
)
958 for (const RulerTab
& rTab
: mpData
->pTabs
)
960 if (rTab
.nStyle
& RULER_STYLE_INVISIBLE
)
963 tools::Long aPosition
;
964 aPosition
= rTab
.nPos
;
965 aPosition
+= +mpData
->nNullVirOff
;
966 tools::Long nTopBottom
= (GetStyle() & WB_RIGHT_ALIGNED
) ? nVirTop
: nVirBottom
;
967 if (nMin
<= aPosition
&& aPosition
<= nMax
)
968 ImplDrawTab(rRenderContext
, Point( aPosition
, nTopBottom
), rTab
.nStyle
);
972 static int adjustSize(int nOrig
)
977 // make sure we return an odd number, that looks better in the ruler
978 return ( (3*nOrig
) / 8) * 2 + 1;
981 void Ruler::ApplySettings(vcl::RenderContext
& rRenderContext
)
983 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
985 vcl::Font aFont
= rStyleSettings
.GetToolFont();
986 // make the font a bit smaller than default
987 Size
aSize(adjustSize(aFont
.GetFontSize().Width()), adjustSize(aFont
.GetFontSize().Height()));
988 aFont
.SetFontSize(aSize
);
990 ApplyControlFont(rRenderContext
, aFont
);
992 ApplyControlForeground(*GetOutDev(), rStyleSettings
.GetDarkShadowColor());
996 svtools::ColorConfig aColorConfig
;
997 aColor
= aColorConfig
.GetColorValue(svtools::APPBACKGROUND
).nColor
;
998 ApplyControlBackground(rRenderContext
, aColor
);
999 // A hack to get it to change the non-ruler application background to change immediately
1000 if (aColor
!= maVirDev
->GetBackground().GetColor())
1002 maVirDev
->SetBackground(aColor
);
1007 void Ruler::ImplInitSettings(bool bFont
, bool bForeground
, bool bBackground
)
1009 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1013 vcl::Font aFont
= rStyleSettings
.GetToolFont();
1014 // make the font a bit smaller than default
1015 Size
aSize(adjustSize(aFont
.GetFontSize().Width()), adjustSize(aFont
.GetFontSize().Height()));
1016 aFont
.SetFontSize(aSize
);
1018 ApplyControlFont(*GetOutDev(), aFont
);
1021 if (bForeground
|| bFont
)
1023 ApplyControlForeground(*GetOutDev(), rStyleSettings
.GetDarkShadowColor());
1030 svtools::ColorConfig aColorConfig
;
1031 aColor
= aColorConfig
.GetColorValue(svtools::APPBACKGROUND
).nColor
;
1032 ApplyControlBackground(*GetOutDev(), aColor
);
1035 maVirDev
->SetSettings( GetSettings() );
1036 maVirDev
->SetBackground( GetBackground() );
1037 vcl::Font aFont
= GetFont();
1039 if (mnWinStyle
& WB_VERT
)
1040 aFont
.SetOrientation(900_deg10
);
1042 maVirDev
->SetFont(aFont
);
1043 maVirDev
->SetTextColor(GetTextColor());
1044 maVirDev
->SetTextFillColor(GetTextFillColor());
1047 void Ruler::ImplCalc()
1050 mpData
->nRulVirOff
= mnWinOff
+ mpData
->nPageOff
;
1051 if ( mpData
->nRulVirOff
> mnVirOff
)
1052 mpData
->nRulVirOff
-= mnVirOff
;
1054 mpData
->nRulVirOff
= 0;
1055 tools::Long nRulWinOff
= mpData
->nRulVirOff
+mnVirOff
;
1057 // calculate non-visual part of the page
1058 tools::Long nNotVisPageWidth
;
1059 if ( mpData
->nPageOff
< 0 )
1061 nNotVisPageWidth
= -(mpData
->nPageOff
);
1062 if ( nRulWinOff
< mnWinOff
)
1063 nNotVisPageWidth
-= mnWinOff
-nRulWinOff
;
1066 nNotVisPageWidth
= 0;
1069 if ( mnWinStyle
& WB_HORZ
)
1071 if ( mbAutoWinWidth
)
1072 mnWinWidth
= mnWidth
- mnVirOff
;
1073 if ( mpData
->bAutoPageWidth
)
1074 mpData
->nPageWidth
= mnWinWidth
;
1075 mpData
->nRulWidth
= std::min( mnWinWidth
, mpData
->nPageWidth
-nNotVisPageWidth
);
1076 if ( nRulWinOff
+mpData
->nRulWidth
> mnWidth
)
1077 mpData
->nRulWidth
= mnWidth
-nRulWinOff
;
1081 if ( mbAutoWinWidth
)
1082 mnWinWidth
= mnHeight
- mnVirOff
;
1083 if ( mpData
->bAutoPageWidth
)
1084 mpData
->nPageWidth
= mnWinWidth
;
1085 mpData
->nRulWidth
= std::min( mnWinWidth
, mpData
->nPageWidth
-nNotVisPageWidth
);
1086 if ( nRulWinOff
+mpData
->nRulWidth
> mnHeight
)
1087 mpData
->nRulWidth
= mnHeight
-nRulWinOff
;
1093 void Ruler::ImplFormat(vcl::RenderContext
const & rRenderContext
)
1095 // if already formatted, don't do it again
1099 // don't do anything if the window still has no size
1103 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
1104 tools::Long nP1
; // pixel position of Page1
1105 tools::Long nP2
; // pixel position of Page2
1106 tools::Long nM1
; // pixel position of Margin1
1107 tools::Long nM2
; // pixel position of Margin2
1108 tools::Long nVirTop
; // top/left corner
1109 tools::Long nVirBottom
; // bottom/right corner
1110 tools::Long nVirLeft
; // left/top corner
1111 tools::Long nVirRight
; // right/bottom corner
1112 tools::Long nNullVirOff
; // for faster calculation
1118 mpData
->nNullVirOff
= mnWinOff
+ mpData
->nPageOff
+ mpData
->nNullOff
- mnVirOff
;
1120 nNullVirOff
= mpData
->nNullVirOff
;
1121 nVirLeft
= mpData
->nRulVirOff
;
1122 nVirRight
= nVirLeft
+ mpData
->nRulWidth
- 1;
1124 nVirBottom
= mnVirHeight
- 1;
1126 if (!IsReallyVisible())
1131 // initialize VirtualDevice
1132 if (mnWinStyle
& WB_HORZ
)
1134 aVirDevSize
.setWidth( mnVirWidth
);
1135 aVirDevSize
.setHeight( mnVirHeight
);
1139 aVirDevSize
.setHeight( mnVirWidth
);
1140 aVirDevSize
.setWidth( mnVirHeight
);
1142 if (aVirDevSize
!= maVirDev
->GetOutputSizePixel())
1143 maVirDev
->SetOutputSizePixel(aVirDevSize
);
1147 // calculate margins
1148 if (!(mpData
->nMargin1Style
& RulerMarginStyle::Invisible
))
1150 nM1
= mpData
->nMargin1
+ nNullVirOff
;
1151 if (mpData
->bAutoPageWidth
)
1158 nP1
= nNullVirOff
- mpData
->nNullOff
;
1165 if (!(mpData
->nMargin2Style
& RulerMarginStyle::Invisible
))
1167 nM2
= mpData
->nMargin2
+ nNullVirOff
;
1168 if (mpData
->bAutoPageWidth
)
1171 if (nM2
> nVirRight
)
1175 nP2
= nNullVirOff
- mpData
->nNullOff
+ mpData
->nPageWidth
;
1185 // top/bottom border
1186 maVirDev
->SetLineColor(rStyleSettings
.GetShadowColor());
1187 ImplVDrawLine(*maVirDev
, nVirLeft
, nVirTop
+ 1, nM1
, nVirTop
+ 1); //top left line
1188 ImplVDrawLine(*maVirDev
, nM2
, nVirTop
+ 1, nP2
- 1, nVirTop
+ 1); //top right line
1193 // draw margin1, margin2 and in-between
1194 maVirDev
->SetLineColor();
1195 maVirDev
->SetFillColor(rStyleSettings
.GetDialogColor());
1197 ImplVDrawRect(*maVirDev
, nP1
, nVirTop
+ 1, nM1
, nVirBottom
); //left gray rectangle
1199 ImplVDrawRect(*maVirDev
, nM2
, nVirTop
+ 1, nP2
, nVirBottom
); //right gray rectangle
1202 maVirDev
->SetFillColor(rStyleSettings
.GetWindowColor());
1203 ImplVDrawRect(*maVirDev
, nM1
+ 1, nVirTop
, nM2
- 1, nVirBottom
); //center rectangle
1205 maVirDev
->SetLineColor(rStyleSettings
.GetShadowColor());
1208 ImplVDrawLine(*maVirDev
, nM1
, nVirTop
+ 1, nM1
, nVirBottom
); //right line of the left rectangle
1209 ImplVDrawLine(*maVirDev
, nP1
, nVirBottom
, nM1
, nVirBottom
); //bottom line of the left rectangle
1210 if (nP1
>= nVirLeft
)
1212 ImplVDrawLine(*maVirDev
, nP1
, nVirTop
+ 1, nP1
, nVirBottom
); //left line of the left rectangle
1213 ImplVDrawLine(*maVirDev
, nP1
, nVirBottom
, nP1
+ 1, nVirBottom
); //?
1218 ImplVDrawLine(*maVirDev
, nM2
, nVirBottom
, nP2
- 1, nVirBottom
); //bottom line of the right rectangle
1219 ImplVDrawLine(*maVirDev
, nM2
, nVirTop
+ 1, nM2
, nVirBottom
); //left line of the right rectangle
1220 if (nP2
<= nVirRight
+ 1)
1221 ImplVDrawLine(*maVirDev
, nP2
- 1, nVirTop
+ 1, nP2
- 1, nVirBottom
); //right line of the right rectangle
1224 tools::Long nMin
= nVirLeft
;
1225 tools::Long nMax
= nP2
;
1226 tools::Long nStart
= 0;
1228 if (mpData
->bTextRTL
)
1229 nStart
= mpData
->nRightFrameMargin
+ nNullVirOff
;
1231 nStart
= mpData
->nLeftFrameMargin
+ nNullVirOff
;
1236 if (nP2
< nVirRight
)
1240 ImplDrawTicks(*maVirDev
, nMin
, nMax
, nStart
, nVirTop
, nVirBottom
);
1243 if (!mpData
->pBorders
.empty())
1244 ImplDrawBorders(*maVirDev
, nVirLeft
, nP2
, nVirTop
, nVirBottom
);
1247 if (!mpData
->pIndents
.empty())
1248 ImplDrawIndents(*maVirDev
, nVirLeft
, nP2
, nVirTop
- 1, nVirBottom
+ 1);
1251 if (!mpData
->pTabs
.empty())
1252 ImplDrawTabs(*maVirDev
, nVirLeft
, nP2
, nVirTop
-1, nVirBottom
+ 1);
1257 void Ruler::ImplInitExtraField( bool bUpdate
)
1259 Size aWinSize
= GetOutputSizePixel();
1261 // extra field evaluate
1262 if ( mnWinStyle
& WB_EXTRAFIELD
)
1264 maExtraRect
.SetLeft( RULER_OFF
);
1265 maExtraRect
.SetTop( RULER_OFF
);
1266 maExtraRect
.SetRight( RULER_OFF
+ mnVirHeight
- 1 );
1267 maExtraRect
.SetBottom( RULER_OFF
+ mnVirHeight
- 1 );
1268 if(mpData
->bTextRTL
)
1270 if(mnWinStyle
& WB_HORZ
)
1271 maExtraRect
.Move(aWinSize
.Width() - maExtraRect
.GetWidth() - maExtraRect
.Left(), 0);
1273 maExtraRect
.Move(0, aWinSize
.Height() - maExtraRect
.GetHeight() - maExtraRect
.Top());
1277 mnVirOff
= maExtraRect
.Right()+1;
1282 maExtraRect
.SetEmpty();
1286 // mnVirWidth depends on mnVirOff
1287 if ( (mnVirWidth
> RULER_MIN_SIZE
) ||
1288 ((aWinSize
.Width() > RULER_MIN_SIZE
) && (aWinSize
.Height() > RULER_MIN_SIZE
)) )
1290 if ( mnWinStyle
& WB_HORZ
)
1291 mnVirWidth
= aWinSize
.Width()-mnVirOff
;
1293 mnVirWidth
= aWinSize
.Height()-mnVirOff
;
1295 if ( mnVirWidth
< RULER_MIN_SIZE
)
1307 void Ruler::ImplDraw(vcl::RenderContext
& rRenderContext
)
1311 ImplFormat(rRenderContext
);
1314 if (!IsReallyVisible())
1317 // output the ruler to the virtual device
1319 Size aVirDevSize
= maVirDev
->GetOutputSizePixel();
1321 if (mnWinStyle
& WB_HORZ
)
1323 aOffPos
.setX( mnVirOff
);
1324 if (mpData
->bTextRTL
)
1325 aVirDevSize
.AdjustWidth( -(maExtraRect
.GetWidth()) );
1327 aOffPos
.setY( RULER_OFF
);
1331 aOffPos
.setX( RULER_OFF
);
1332 aOffPos
.setY( mnVirOff
);
1334 rRenderContext
.DrawOutDev(aOffPos
, aVirDevSize
, Point(), aVirDevSize
, *maVirDev
);
1336 // redraw positionlines
1337 ImplInvertLines(rRenderContext
);
1340 void Ruler::ImplDrawExtra(vcl::RenderContext
& rRenderContext
)
1342 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
1343 tools::Rectangle aRect
= maExtraRect
;
1344 bool bEraseRect
= false;
1346 aRect
.AdjustLeft(2 );
1347 aRect
.AdjustTop(2 );
1348 aRect
.AdjustRight( -2 );
1349 aRect
.AdjustBottom( -2 );
1351 if (mnExtraStyle
& RULER_STYLE_HIGHLIGHT
)
1353 rRenderContext
.SetFillColor(rStyleSettings
.GetCheckedColor());
1359 rRenderContext
.SetLineColor();
1360 rRenderContext
.DrawRect(aRect
);
1364 if (meExtraType
== RulerExtra::NullOffset
)
1366 rRenderContext
.SetLineColor(rStyleSettings
.GetButtonTextColor());
1367 rRenderContext
.DrawLine(Point(aRect
.Left() + 1, aRect
.Top() + 4),
1368 Point(aRect
.Right() - 1, aRect
.Top() + 4));
1369 rRenderContext
.DrawLine(Point(aRect
.Left() + 4, aRect
.Top() + 1),
1370 Point(aRect
.Left() + 4, aRect
.Bottom() - 1));
1372 else if (meExtraType
== RulerExtra::Tab
)
1374 sal_uInt16 nTabStyle
= mnExtraStyle
& RULER_TAB_STYLE
;
1375 if (mpData
->bTextRTL
)
1376 nTabStyle
|= RULER_TAB_RTL
;
1377 Point aCenter
= aRect
.Center();
1378 Point
aDraw(aCenter
);
1379 ImplCenterTabPos(aDraw
, nTabStyle
);
1380 WinBits nWinBits
= GetStyle();
1381 if (0 == (nWinBits
& WB_HORZ
))
1383 if ((nWinBits
& WB_RIGHT_ALIGNED
) != 0)
1384 aDraw
.setY( 2 * aCenter
.Y() - aDraw
.Y() );
1386 if (mpData
->bTextRTL
)
1388 tools::Long nTemp
= aDraw
.X();
1389 aDraw
.setX( aDraw
.Y() );
1390 aDraw
.setY( nTemp
);
1393 ImplDrawTab(rRenderContext
, aDraw
, nTabStyle
);
1397 void Ruler::ImplUpdate( bool bMustCalc
)
1399 // clear lines in this place so they aren't considered at recalculation
1401 Invalidate(InvalidateFlags::NoErase
);
1408 // abort if we are dragging as drag-handler will update the ruler after drag is finished
1412 // otherwise trigger update
1413 if (IsReallyVisible() && IsUpdateMode())
1415 Invalidate(InvalidateFlags::NoErase
);
1419 bool Ruler::ImplDoHitTest( const Point
& rPos
, RulerSelection
* pHitTest
,
1420 bool bRequireStyle
, RulerIndentStyle nRequiredStyle
) 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
= 1;
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
;
1580 if ( (nX
>= n1
) && (nX
<= n2
) )
1582 RulerBorderStyle nBorderStyle
= mpData
->pBorders
[i
-1].nStyle
;
1583 if ( !(nBorderStyle
& RulerBorderStyle::Invisible
) )
1585 pHitTest
->eType
= RulerType::Border
;
1586 pHitTest
->nAryPos
= i
-1;
1588 if ( !(nBorderStyle
& RulerBorderStyle::Sizeable
) )
1590 if ( nBorderStyle
& RulerBorderStyle::Moveable
)
1592 pHitTest
->bSizeBar
= true;
1593 pHitTest
->mnDragSize
= RulerDragSize::Move
;
1598 tools::Long nMOff
= RULER_MOUSE_BORDERWIDTH
;
1599 while ( nMOff
*2 >= (n2
-n1
-RULER_MOUSE_BORDERMOVE
) )
1610 if ( nX
<= n1
+nMOff
)
1612 pHitTest
->bSize
= true;
1613 pHitTest
->mnDragSize
= RulerDragSize::N1
;
1615 else if ( nX
>= n2
-nMOff
)
1617 pHitTest
->bSize
= true;
1618 pHitTest
->mnDragSize
= RulerDragSize::N2
;
1622 if ( nBorderStyle
& RulerBorderStyle::Moveable
)
1624 pHitTest
->bSizeBar
= true;
1625 pHitTest
->mnDragSize
= RulerDragSize::Move
;
1636 int nMarginTolerance
= pHitTest
->bExpandTest
? nBorderTolerance
: RULER_MOUSE_MARGINWIDTH
;
1638 if ( (mpData
->nMargin1Style
& (RulerMarginStyle::Sizeable
| RulerMarginStyle::Invisible
)) == RulerMarginStyle::Sizeable
)
1640 n1
= mpData
->nMargin1
;
1641 if ( (nX
>= n1
- nMarginTolerance
) && (nX
<= n1
+ nMarginTolerance
) )
1643 pHitTest
->eType
= RulerType::Margin1
;
1644 pHitTest
->bSize
= true;
1648 if ( (mpData
->nMargin2Style
& (RulerMarginStyle::Sizeable
| RulerMarginStyle::Invisible
)) == RulerMarginStyle::Sizeable
)
1650 n1
= mpData
->nMargin2
;
1651 if ( (nX
>= n1
- nMarginTolerance
) && (nX
<= n1
+ nMarginTolerance
) )
1653 pHitTest
->eType
= RulerType::Margin2
;
1654 pHitTest
->bSize
= true;
1660 if ( !mpData
->pTabs
.empty() )
1662 aRect
.SetTop( RULER_OFF
);
1663 aRect
.SetBottom( nHitBottom
);
1665 for ( i
= mpData
->pTabs
.size() - 1; i
>= 0; i
-- )
1667 nStyle
= mpData
->pTabs
[i
].nStyle
;
1668 if ( !(nStyle
& RULER_STYLE_INVISIBLE
) )
1670 nStyle
&= RULER_TAB_STYLE
;
1672 // default tabs are only shown (no action)
1673 if ( nStyle
!= RULER_TAB_DEFAULT
)
1675 n1
= mpData
->pTabs
[i
].nPos
;
1677 if ( nStyle
== RULER_TAB_LEFT
)
1679 aRect
.SetLeft( n1
);
1680 aRect
.SetRight( n1
+ ruler_tab
.width
- 1 );
1682 else if ( nStyle
== RULER_TAB_RIGHT
)
1684 aRect
.SetRight( n1
);
1685 aRect
.SetLeft( n1
- ruler_tab
.width
- 1 );
1689 aRect
.SetLeft( n1
- ruler_tab
.cwidth2
+ 1 );
1690 aRect
.SetRight( n1
- ruler_tab
.cwidth2
+ ruler_tab
.cwidth
);
1693 aRect
.AdjustLeft( -1 );
1694 aRect
.AdjustRight( 1 );
1696 if ( aRect
.Contains( Point( nX
, nY
) ) )
1698 pHitTest
->eType
= RulerType::Tab
;
1699 pHitTest
->nAryPos
= i
;
1710 bool Ruler::ImplDocHitTest( const Point
& rPos
, RulerType eDragType
,
1711 RulerSelection
* pHitTest
) const
1714 bool bRequiredStyle
= false;
1715 RulerIndentStyle nRequiredStyle
= RulerIndentStyle::Top
;
1717 if (eDragType
== RulerType::Indent
)
1719 bRequiredStyle
= true;
1720 nRequiredStyle
= RulerIndentStyle::Bottom
;
1723 if ( mnWinStyle
& WB_HORZ
)
1724 aPos
.AdjustX(mnWinOff
);
1726 aPos
.AdjustY(mnWinOff
);
1728 if ( (eDragType
== RulerType::Indent
) || (eDragType
== RulerType::DontKnow
) )
1730 if ( mnWinStyle
& WB_HORZ
)
1731 aPos
.setY( RULER_OFF
+ 1 );
1733 aPos
.setX( RULER_OFF
+ 1 );
1735 if ( ImplDoHitTest( aPos
, pHitTest
, bRequiredStyle
, nRequiredStyle
) )
1737 if ( (pHitTest
->eType
== eDragType
) || (eDragType
== RulerType::DontKnow
) )
1742 if ( (eDragType
== RulerType::Indent
) ||
1743 (eDragType
== RulerType::Tab
) ||
1744 (eDragType
== RulerType::DontKnow
) )
1746 if ( mnWinStyle
& WB_HORZ
)
1747 aPos
.setY( mnHeight
- RULER_OFF
- 1 );
1749 aPos
.setX( mnWidth
- RULER_OFF
- 1 );
1751 if ( ImplDoHitTest( aPos
, pHitTest
, bRequiredStyle
, nRequiredStyle
) )
1753 if ( (pHitTest
->eType
== eDragType
) || (eDragType
== RulerType::DontKnow
) )
1758 if ( (eDragType
== RulerType::Margin1
) || (eDragType
== RulerType::Margin2
) ||
1759 (eDragType
== RulerType::Border
) || (eDragType
== RulerType::DontKnow
) )
1761 if ( mnWinStyle
& WB_HORZ
)
1762 aPos
.setY( RULER_OFF
+ (mnVirHeight
/ 2) );
1764 aPos
.setX( RULER_OFF
+ (mnVirHeight
/ 2) );
1766 if ( ImplDoHitTest( aPos
, pHitTest
) )
1768 if ( (pHitTest
->eType
== eDragType
) || (eDragType
== RulerType::DontKnow
) )
1773 pHitTest
->eType
= RulerType::DontKnow
;
1778 bool Ruler::ImplStartDrag( RulerSelection
const * pHitTest
, sal_uInt16 nModifier
)
1780 // don't trigger drag if a border that was clicked can not be changed
1781 if ( (pHitTest
->eType
== RulerType::Border
) &&
1782 !pHitTest
->bSize
&& !pHitTest
->bSizeBar
)
1786 meDragType
= pHitTest
->eType
;
1787 mnDragPos
= pHitTest
->nPos
;
1788 mnDragAryPos
= pHitTest
->nAryPos
;
1789 mnDragSize
= pHitTest
->mnDragSize
;
1790 mnDragModifier
= nModifier
;
1791 *mpDragData
= *mpSaveData
;
1792 mpData
= mpDragData
.get();
1797 // if the handler allows dragging, initialize dragging
1799 mnStartDragPos
= mnDragPos
;
1801 Invalidate(InvalidateFlags::NoErase
);
1806 // otherwise reset the data
1807 meDragType
= RulerType::DontKnow
;
1810 mnDragSize
= RulerDragSize::Move
;
1812 mpData
= mpSaveData
.get();
1818 void Ruler::ImplDrag( const Point
& rPos
)
1822 tools::Long nOutHeight
;
1824 if ( mnWinStyle
& WB_HORZ
)
1828 nOutHeight
= mnHeight
;
1834 nOutHeight
= mnWidth
;
1837 // calculate and fit X
1839 if ( nX
< mpData
->nRulVirOff
)
1841 nX
= mpData
->nRulVirOff
;
1843 else if ( nX
> mpData
->nRulVirOff
+mpData
->nRulWidth
)
1845 nX
= mpData
->nRulVirOff
+mpData
->nRulWidth
;
1847 nX
-= mpData
->nNullVirOff
;
1849 // if upper or left from ruler, then consider old values
1850 mbDragDelete
= false;
1853 if ( !mbDragCanceled
)
1856 mbDragCanceled
= true;
1857 ImplRulerData aTempData
= *mpDragData
;
1858 *mpDragData
= *mpSaveData
;
1863 mnDragPos
= mnStartDragPos
;
1867 Invalidate(InvalidateFlags::NoErase
);
1869 // reset the data as before cancel
1870 *mpDragData
= aTempData
;
1875 mbDragCanceled
= false;
1877 // +2, so the tabs are not cleared too quickly
1878 if ( nY
> nOutHeight
+ 2 )
1879 mbDragDelete
= true;
1888 Invalidate(InvalidateFlags::NoErase
);
1892 void Ruler::ImplEndDrag()
1895 if ( mbDragCanceled
)
1896 *mpDragData
= *mpSaveData
;
1898 *mpSaveData
= *mpDragData
;
1900 mpData
= mpSaveData
.get();
1906 // reset drag values
1907 meDragType
= RulerType::DontKnow
;
1910 mnDragSize
= RulerDragSize::Move
;
1911 mbDragCanceled
= false;
1912 mbDragDelete
= false;
1917 Invalidate(InvalidateFlags::NoErase
);
1920 void Ruler::MouseButtonDown( const MouseEvent
& rMEvt
)
1922 if ( !rMEvt
.IsLeft() || IsTracking() )
1925 Point aMousePos
= rMEvt
.GetPosPixel();
1926 sal_uInt16 nMouseClicks
= rMEvt
.GetClicks();
1927 sal_uInt16 nMouseModifier
= rMEvt
.GetModifier();
1932 Invalidate(InvalidateFlags::NoErase
);
1935 if ( maExtraRect
.Contains( aMousePos
) )
1941 RulerSelection aHitTest
;
1942 bool bHitTestResult
= ImplDoHitTest(aMousePos
, &aHitTest
);
1944 if ( nMouseClicks
== 1 )
1946 if ( bHitTestResult
)
1948 ImplStartDrag( &aHitTest
, nMouseModifier
);
1952 // calculate position inside of ruler area
1953 if ( aHitTest
.eType
== RulerType::DontKnow
)
1955 mnDragPos
= aHitTest
.nPos
;
1959 // call HitTest again as a click, for example, could set a new tab
1960 if ( ImplDoHitTest(aMousePos
, &aHitTest
) )
1961 ImplStartDrag(&aHitTest
, nMouseModifier
);
1969 mnDragPos
= aHitTest
.nPos
;
1970 mnDragAryPos
= aHitTest
.nAryPos
;
1972 meDragType
= aHitTest
.eType
;
1976 meDragType
= RulerType::DontKnow
;
1983 void Ruler::MouseMove( const MouseEvent
& rMEvt
)
1985 PointerStyle ePtrStyle
= PointerStyle::Arrow
;
1987 mxPreviousHitTest
.swap(mxCurrentHitTest
);
1989 mxCurrentHitTest
.reset(new RulerSelection
);
1991 maHoverSelection
.eType
= RulerType::DontKnow
;
1993 if (ImplDoHitTest( rMEvt
.GetPosPixel(), mxCurrentHitTest
.get() ))
1995 maHoverSelection
= *mxCurrentHitTest
;
1997 if (mxCurrentHitTest
->bSize
)
1999 if (mnWinStyle
& WB_HORZ
)
2001 if (mxCurrentHitTest
->mnDragSize
== RulerDragSize::N1
)
2002 ePtrStyle
= PointerStyle::TabSelectW
;
2003 else if (mxCurrentHitTest
->mnDragSize
== RulerDragSize::N2
)
2004 ePtrStyle
= PointerStyle::TabSelectE
;
2006 ePtrStyle
= PointerStyle::ESize
;
2010 if (mxCurrentHitTest
->mnDragSize
== RulerDragSize::N1
)
2011 ePtrStyle
= PointerStyle::WindowNSize
;
2012 else if (mxCurrentHitTest
->mnDragSize
== RulerDragSize::N2
)
2013 ePtrStyle
= PointerStyle::WindowSSize
;
2015 ePtrStyle
= PointerStyle::SSize
;
2018 else if (mxCurrentHitTest
->bSizeBar
)
2020 if (mnWinStyle
& WB_HORZ
)
2021 ePtrStyle
= PointerStyle::HSizeBar
;
2023 ePtrStyle
= PointerStyle::VSizeBar
;
2027 if (mxPreviousHitTest
!= nullptr && mxPreviousHitTest
->eType
!= mxCurrentHitTest
->eType
)
2032 SetPointer( ePtrStyle
);
2036 Invalidate(InvalidateFlags::NoErase
);
2040 void Ruler::Tracking( const TrackingEvent
& rTEvt
)
2042 if ( rTEvt
.IsTrackingEnded() )
2044 // reset the old state at cancel
2045 if ( rTEvt
.IsTrackingCanceled() )
2047 mbDragCanceled
= true;
2054 ImplDrag( rTEvt
.GetMouseEvent().GetPosPixel() );
2057 void Ruler::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
2059 ImplDraw(rRenderContext
);
2061 // consider extra field
2062 if (mnWinStyle
& WB_EXTRAFIELD
)
2063 ImplDrawExtra(rRenderContext
);
2066 void Ruler::Resize()
2068 Size aWinSize
= GetOutputSizePixel();
2070 tools::Long nNewHeight
;
2071 if ( mnWinStyle
& WB_HORZ
)
2073 if ( aWinSize
.Height() != mnHeight
)
2074 nNewHeight
= aWinSize
.Height();
2080 if ( aWinSize
.Width() != mnWidth
)
2081 nNewHeight
= aWinSize
.Width();
2089 bool bVisible
= IsReallyVisible();
2090 if ( bVisible
&& !mpData
->pLines
.empty() )
2092 mnUpdateFlags
|= RULER_UPDATE_LINES
;
2093 Invalidate(InvalidateFlags::NoErase
);
2096 // recalculate some values if the height/width changes
2097 // extra field should always be updated
2098 ImplInitExtraField( mpData
->bTextRTL
);
2102 mnVirHeight
= nNewHeight
- mnBorderWidth
- ( RULER_OFF
* 2 );
2106 if ( mpData
->bAutoPageWidth
)
2108 else if ( mbAutoWinWidth
)
2112 // clear part of the border
2116 Invalidate(InvalidateFlags::NoErase
);
2117 else if ( mpData
->bAutoPageWidth
)
2119 // only at AutoPageWidth do we need to redraw
2120 tools::Rectangle aRect
;
2122 if ( mnWinStyle
& WB_HORZ
)
2124 if ( mnWidth
< aWinSize
.Width() )
2125 aRect
.SetLeft( mnWidth
- RULER_RESIZE_OFF
);
2127 aRect
.SetLeft( aWinSize
.Width() - RULER_RESIZE_OFF
);
2128 aRect
.SetRight( aRect
.Left() + RULER_RESIZE_OFF
);
2129 aRect
.SetTop( RULER_OFF
);
2130 aRect
.SetBottom( RULER_OFF
+ mnVirHeight
);
2134 if ( mnHeight
< aWinSize
.Height() )
2135 aRect
.SetTop( mnHeight
-RULER_RESIZE_OFF
);
2137 aRect
.SetTop( aWinSize
.Height()-RULER_RESIZE_OFF
);
2138 aRect
.SetBottom( aRect
.Top() + RULER_RESIZE_OFF
);
2139 aRect
.SetLeft( RULER_OFF
);
2140 aRect
.SetRight( RULER_OFF
+ mnVirHeight
);
2143 Invalidate(aRect
, InvalidateFlags::NoErase
);
2147 mnWidth
= aWinSize
.Width();
2148 mnHeight
= aWinSize
.Height();
2151 void Ruler::StateChanged( StateChangedType nType
)
2153 Window::StateChanged( nType
);
2155 if ( nType
== StateChangedType::InitShow
)
2157 else if ( nType
== StateChangedType::UpdateMode
)
2159 if ( IsReallyVisible() && IsUpdateMode() )
2162 else if ( (nType
== StateChangedType::Zoom
) ||
2163 (nType
== StateChangedType::ControlFont
) )
2165 ImplInitSettings( true, false, false );
2168 else if ( nType
== StateChangedType::ControlForeground
)
2170 ImplInitSettings( false, true, false );
2173 else if ( nType
== StateChangedType::ControlBackground
)
2175 ImplInitSettings( false, false, true );
2180 void Ruler::DataChanged( const DataChangedEvent
& rDCEvt
)
2182 Window::DataChanged( rDCEvt
);
2184 if ( (rDCEvt
.GetType() == DataChangedEventType::FONTS
) ||
2185 (rDCEvt
.GetType() == DataChangedEventType::DISPLAY
) ||
2186 (rDCEvt
.GetType() == DataChangedEventType::FONTSUBSTITUTION
) ||
2187 ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
2188 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
)) )
2191 ImplInitSettings( true, true, true );
2196 bool Ruler::StartDrag()
2205 void Ruler::EndDrag()
2213 void Ruler::DoubleClick()
2215 maDoubleClickHdl
.Call( this );
2218 void Ruler::ExtraDown()
2222 void Ruler::Activate()
2226 // update positionlines - draw is delayed
2227 mnUpdateFlags
|= RULER_UPDATE_LINES
;
2228 Invalidate(InvalidateFlags::NoErase
);
2231 void Ruler::Deactivate()
2233 // clear positionlines
2234 Invalidate(InvalidateFlags::NoErase
);
2239 bool Ruler::StartDocDrag( const MouseEvent
& rMEvt
, RulerType eDragType
)
2243 Point aMousePos
= rMEvt
.GetPosPixel();
2244 sal_uInt16 nMouseClicks
= rMEvt
.GetClicks();
2245 sal_uInt16 nMouseModifier
= rMEvt
.GetModifier();
2246 RulerSelection aHitTest
;
2248 if(eDragType
!= RulerType::DontKnow
)
2249 aHitTest
.bExpandTest
= true;
2254 if (!IsReallyVisible())
2256 // set mpData for ImplDocHitTest()
2257 ImplFormat(*GetOutDev());
2260 Invalidate(InvalidateFlags::NoErase
);
2263 if ( nMouseClicks
== 1 )
2265 if ( ImplDocHitTest( aMousePos
, eDragType
, &aHitTest
) )
2267 PointerStyle aPtr
= PointerStyle::Arrow
;
2269 if ( aHitTest
.bSize
)
2271 if ( mnWinStyle
& WB_HORZ
)
2272 aPtr
= PointerStyle::ESize
;
2274 aPtr
= PointerStyle::SSize
;
2276 else if ( aHitTest
.bSizeBar
)
2278 if ( mnWinStyle
& WB_HORZ
)
2279 aPtr
= PointerStyle::HSizeBar
;
2281 aPtr
= PointerStyle::VSizeBar
;
2284 return ImplStartDrag( &aHitTest
, nMouseModifier
);
2287 else if ( nMouseClicks
== 2 )
2289 if ( ImplDocHitTest( aMousePos
, eDragType
, &aHitTest
) )
2291 mnDragPos
= aHitTest
.nPos
;
2292 mnDragAryPos
= aHitTest
.nAryPos
;
2307 void Ruler::CancelDrag()
2311 ImplDrag( Point( -1, -1 ) );
2316 RulerType
Ruler::GetRulerType( const Point
& rPos
, sal_uInt16
* pAryPos
)
2318 RulerSelection aHitTest
;
2321 if ( IsReallyVisible() && mbFormat
)
2323 Invalidate(InvalidateFlags::NoErase
);
2326 (void)ImplDoHitTest(rPos
, &aHitTest
);
2330 *pAryPos
= aHitTest
.nAryPos
;
2331 return aHitTest
.eType
;
2334 void Ruler::SetWinPos( tools::Long nNewOff
, tools::Long nNewWidth
)
2336 // should widths be automatically calculated
2338 mbAutoWinWidth
= true;
2340 mbAutoWinWidth
= false;
2343 mnWinWidth
= nNewWidth
;
2347 void Ruler::SetPagePos( tools::Long nNewOff
, tools::Long nNewWidth
)
2349 // should we do anything?
2350 if ( (mpData
->nPageOff
== nNewOff
) && (mpData
->nPageWidth
== nNewWidth
) )
2353 // should widths be automatically calculated
2355 mpData
->bAutoPageWidth
= true;
2357 mpData
->bAutoPageWidth
= false;
2359 mpData
->nPageOff
= nNewOff
;
2360 mpData
->nPageWidth
= nNewWidth
;
2364 void Ruler::SetBorderPos( tools::Long nOff
)
2366 if ( mnWinStyle
& WB_BORDER
)
2368 if ( mnBorderOff
!= nOff
)
2372 if ( IsReallyVisible() && IsUpdateMode() )
2373 Invalidate(InvalidateFlags::NoErase
);
2378 void Ruler::SetUnit( FieldUnit eNewUnit
)
2380 if ( meUnit
== eNewUnit
)
2387 mnUnitIndex
= RULER_UNIT_MM
;
2390 mnUnitIndex
= RULER_UNIT_CM
;
2393 mnUnitIndex
= RULER_UNIT_M
;
2396 mnUnitIndex
= RULER_UNIT_KM
;
2398 case FieldUnit::INCH
:
2399 mnUnitIndex
= RULER_UNIT_INCH
;
2401 case FieldUnit::FOOT
:
2402 mnUnitIndex
= RULER_UNIT_FOOT
;
2404 case FieldUnit::MILE
:
2405 mnUnitIndex
= RULER_UNIT_MILE
;
2407 case FieldUnit::POINT
:
2408 mnUnitIndex
= RULER_UNIT_POINT
;
2410 case FieldUnit::PICA
:
2411 mnUnitIndex
= RULER_UNIT_PICA
;
2413 case FieldUnit::CHAR
:
2414 mnUnitIndex
= RULER_UNIT_CHAR
;
2416 case FieldUnit::LINE
:
2417 mnUnitIndex
= RULER_UNIT_LINE
;
2420 SAL_WARN( "svtools.control", "Ruler::SetUnit() - Wrong Unit" );
2424 maMapMode
.SetMapUnit( aImplRulerUnitTab
[mnUnitIndex
].eMapUnit
);
2428 void Ruler::SetZoom( const Fraction
& rNewZoom
)
2430 DBG_ASSERT( rNewZoom
.GetNumerator(), "Ruler::SetZoom() with scale 0 is not allowed" );
2432 if ( maZoom
!= rNewZoom
)
2435 maMapMode
.SetScaleX( maZoom
);
2436 maMapMode
.SetScaleY( maZoom
);
2441 void Ruler::SetExtraType( RulerExtra eNewExtraType
, sal_uInt16 nStyle
)
2443 if ( mnWinStyle
& WB_EXTRAFIELD
)
2445 meExtraType
= eNewExtraType
;
2446 mnExtraStyle
= nStyle
;
2447 if (IsReallyVisible() && IsUpdateMode())
2452 void Ruler::SetNullOffset( tools::Long nPos
)
2454 if ( mpData
->nNullOff
!= nPos
)
2456 mpData
->nNullVirOff
+= nPos
- mpData
->nNullOff
;
2457 mpData
->nNullOff
= nPos
;
2462 void Ruler::SetLeftFrameMargin( tools::Long nPos
)
2464 if ( mpData
->nLeftFrameMargin
!= nPos
)
2466 mpData
->nLeftFrameMargin
= nPos
;
2471 void Ruler::SetRightFrameMargin( tools::Long nPos
)
2473 if ( mpData
->nRightFrameMargin
!= nPos
)
2475 mpData
->nRightFrameMargin
= nPos
;
2480 void Ruler::SetMargin1( tools::Long nPos
, RulerMarginStyle nMarginStyle
)
2482 if ( (mpData
->nMargin1
!= nPos
) || (mpData
->nMargin1Style
!= nMarginStyle
) )
2484 mpData
->nMargin1
= nPos
;
2485 mpData
->nMargin1Style
= nMarginStyle
;
2490 void Ruler::SetMargin2( tools::Long nPos
, RulerMarginStyle nMarginStyle
)
2492 DBG_ASSERT( (nPos
>= mpData
->nMargin1
) ||
2493 (mpData
->nMargin1Style
& RulerMarginStyle::Invisible
) ||
2494 (mpData
->nMargin2Style
& RulerMarginStyle::Invisible
),
2495 "Ruler::SetMargin2() - Margin2 < Margin1" );
2497 if ( (mpData
->nMargin2
!= nPos
) || (mpData
->nMargin2Style
!= nMarginStyle
) )
2499 mpData
->nMargin2
= nPos
;
2500 mpData
->nMargin2Style
= nMarginStyle
;
2505 void Ruler::SetLines( sal_uInt32 aLineArraySize
, const RulerLine
* pLineArray
)
2507 // To determine if what has changed
2508 if ( mpData
->pLines
.size() == aLineArraySize
)
2510 sal_uInt32 i
= aLineArraySize
;
2511 std::vector
<RulerLine
>::const_iterator aItr1
= mpData
->pLines
.begin();
2512 const RulerLine
* pAry2
= pLineArray
;
2515 if ( aItr1
->nPos
!= pAry2
->nPos
)
2525 // New values and new share issue
2527 bMustUpdate
= IsReallyVisible() && IsUpdateMode();
2531 Invalidate(InvalidateFlags::NoErase
);
2534 if ( !aLineArraySize
|| !pLineArray
)
2536 if ( mpData
->pLines
.empty() )
2538 mpData
->pLines
.clear();
2542 if ( mpData
->pLines
.size() != aLineArraySize
)
2544 mpData
->pLines
.resize(aLineArraySize
);
2547 std::copy( pLineArray
,
2548 pLineArray
+ aLineArraySize
,
2549 mpData
->pLines
.begin() );
2552 Invalidate(InvalidateFlags::NoErase
);
2556 void Ruler::SetBorders( sal_uInt32 aBorderArraySize
, const RulerBorder
* pBorderArray
)
2558 if ( !aBorderArraySize
|| !pBorderArray
)
2560 if ( mpData
->pBorders
.empty() )
2562 mpData
->pBorders
.clear();
2566 if ( mpData
->pBorders
.size() != aBorderArraySize
)
2568 mpData
->pBorders
.resize(aBorderArraySize
);
2572 sal_uInt32 i
= aBorderArraySize
;
2573 const RulerBorder
* pAry1
= mpData
->pBorders
.data();
2574 const RulerBorder
* pAry2
= pBorderArray
;
2577 if ( (pAry1
->nPos
!= pAry2
->nPos
) ||
2578 (pAry1
->nWidth
!= pAry2
->nWidth
) ||
2579 (pAry1
->nStyle
!= pAry2
->nStyle
) )
2588 std::copy( pBorderArray
,
2589 pBorderArray
+ aBorderArraySize
,
2590 mpData
->pBorders
.begin() );
2596 void Ruler::SetIndents( sal_uInt32 aIndentArraySize
, const RulerIndent
* pIndentArray
)
2599 if ( !aIndentArraySize
|| !pIndentArray
)
2601 if ( mpData
->pIndents
.empty() )
2603 mpData
->pIndents
.clear();
2607 if ( mpData
->pIndents
.size() != aIndentArraySize
)
2609 mpData
->pIndents
.resize(aIndentArraySize
);
2613 sal_uInt32 i
= aIndentArraySize
;
2614 const RulerIndent
* pAry1
= mpData
->pIndents
.data();
2615 const RulerIndent
* pAry2
= pIndentArray
;
2618 if ( (pAry1
->nPos
!= pAry2
->nPos
) ||
2619 (pAry1
->nStyle
!= pAry2
->nStyle
) )
2629 std::copy( pIndentArray
,
2630 pIndentArray
+ aIndentArraySize
,
2631 mpData
->pIndents
.begin() );
2637 void Ruler::SetTabs( sal_uInt32 aTabArraySize
, const RulerTab
* pTabArray
)
2639 if ( aTabArraySize
== 0 || pTabArray
== nullptr )
2641 if ( mpData
->pTabs
.empty() )
2643 mpData
->pTabs
.clear();
2647 if ( mpData
->pTabs
.size() != aTabArraySize
)
2649 mpData
->pTabs
.resize(aTabArraySize
);
2653 sal_uInt32 i
= aTabArraySize
;
2654 std::vector
<RulerTab
>::iterator aTabIterator
= mpData
->pTabs
.begin();
2655 const RulerTab
* pInputArray
= pTabArray
;
2658 RulerTab
& aCurrent
= *aTabIterator
;
2659 if ( aCurrent
.nPos
!= pInputArray
->nPos
||
2660 aCurrent
.nStyle
!= pInputArray
->nStyle
)
2671 std::copy(pTabArray
, pTabArray
+ aTabArraySize
, mpData
->pTabs
.begin());
2677 const std::vector
<RulerTab
>& Ruler::GetTabs() const
2679 return mpData
->pTabs
;
2682 void Ruler::SetStyle( WinBits nStyle
)
2684 if ( mnWinStyle
!= nStyle
)
2686 mnWinStyle
= nStyle
;
2687 ImplInitExtraField( true );
2691 void Ruler::DrawTab(vcl::RenderContext
& rRenderContext
, const Color
&rFillColor
, const Point
& rPos
, sal_uInt16 nStyle
)
2694 sal_uInt16 nTabStyle
= nStyle
& (RULER_TAB_STYLE
| RULER_TAB_RTL
);
2696 rRenderContext
.Push(vcl::PushFlags::LINECOLOR
| vcl::PushFlags::FILLCOLOR
);
2697 rRenderContext
.SetLineColor();
2698 rRenderContext
.SetFillColor(rFillColor
);
2699 ImplCenterTabPos(aPos
, nTabStyle
);
2700 ImplDrawRulerTab(rRenderContext
, aPos
, nTabStyle
, nStyle
);
2701 rRenderContext
.Pop();
2704 void Ruler::SetTextRTL(bool bRTL
)
2706 if(mpData
->bTextRTL
!= bRTL
)
2708 mpData
->bTextRTL
= bRTL
;
2709 if ( IsReallyVisible() && IsUpdateMode() )
2710 ImplInitExtraField( true );
2715 tools::Long
Ruler::GetPageOffset() const
2717 return mpData
->nPageOff
;
2720 tools::Long
Ruler::GetNullOffset() const
2722 return mpData
->nNullOff
;
2725 tools::Long
Ruler::GetMargin1() const
2727 return mpData
->nMargin1
;
2730 tools::Long
Ruler::GetMargin2() const
2732 return mpData
->nMargin2
;
2736 bool Ruler::GetTextRTL() const
2738 return mpData
->bTextRTL
;
2741 const RulerUnitData
& Ruler::GetCurrentRulerUnit() const
2743 return aImplRulerUnitTab
[mnUnitIndex
];
2746 void Ruler::DrawTicks()
2749 Invalidate(InvalidateFlags::NoErase
);
2752 uno::Reference
< XAccessible
> Ruler::CreateAccessible()
2754 vcl::Window
* pParent
= GetAccessibleParentWindow();
2755 OSL_ENSURE( pParent
, "-SvxRuler::CreateAccessible(): No Parent!" );
2756 uno::Reference
< XAccessible
> xAccParent
= pParent
->GetAccessible();
2757 if( xAccParent
.is() )
2759 // MT: Fixed compiler issue because the address from a temporary object was used.
2760 // BUT: Should it really be a Pointer, instead of const&???
2762 if ( mnWinStyle
& WB_HORZ
)
2764 aStr
= SvtResId(STR_SVT_ACC_RULER_HORZ_NAME
);
2768 aStr
= SvtResId(STR_SVT_ACC_RULER_VERT_NAME
);
2770 mxAccContext
= new SvtRulerAccessible( xAccParent
, *this, aStr
);
2771 SetAccessible(mxAccContext
);
2772 return mxAccContext
;
2775 return uno::Reference
< XAccessible
>();
2778 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */