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 <vcl/settings.hxx>
21 #include <vcl/outdev.hxx>
22 #include <vcl/decoview.hxx>
23 #include <vcl/window.hxx>
24 #include <vcl/ctrl.hxx>
26 static constexpr auto BUTTON_DRAW_FLATTEST
= DrawButtonFlags::Flat
|
27 DrawButtonFlags::Pressed
|
28 DrawButtonFlags::Checked
|
29 DrawButtonFlags::Highlight
;
35 long AdjustRectToSquare( tools::Rectangle
&rRect
)
37 const long nWidth
= rRect
.GetWidth();
38 const long nHeight
= rRect
.GetHeight();
39 long nSide
= std::min( nWidth
, nHeight
);
41 if ( nSide
&& !(nSide
& 1) )
43 // we prefer an odd size
47 // Make the rectangle a square
48 rRect
.SetSize( Size( nSide
, nSide
) );
50 // and place it at the center of the original rectangle
51 rRect
.Move( (nWidth
-nSide
)/2, (nHeight
-nSide
)/2 );
56 void ImplDrawSymbol( OutputDevice
* pDev
, tools::Rectangle nRect
, const SymbolType eType
)
58 const long nSide
= AdjustRectToSquare( nRect
);
63 pDev
->DrawPixel( Point( nRect
.Left(), nRect
.Top() ) );
67 // Precalculate some values
68 const long n2
= nSide
/2;
69 const long n4
= (n2
+1)/2;
70 const long n8
= (n4
+1)/2;
71 const long n16
= (n8
+1)/2;
72 const Point aCenter
= nRect
.Center();
76 case SymbolType::ARROW_UP
:
77 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Top() ) );
78 for ( long i
=1; i
<= n2
; ++i
)
81 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Top() ),
82 Point( aCenter
.X()+i
, nRect
.Top() ) );
83 pDev
->DrawPixel( Point( aCenter
.X()-i
, nRect
.Top() ) );
84 pDev
->DrawPixel( Point( aCenter
.X()+i
, nRect
.Top() ) );
86 pDev
->DrawRect( tools::Rectangle( aCenter
.X()-n8
, nRect
.Top()+1,
87 aCenter
.X()+n8
, nRect
.Bottom() ) );
90 case SymbolType::ARROW_DOWN
:
91 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Bottom() ) );
92 for ( long i
=1; i
<= n2
; ++i
)
94 nRect
.AdjustBottom( -1 );
95 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Bottom() ),
96 Point( aCenter
.X()+i
, nRect
.Bottom() ) );
97 pDev
->DrawPixel( Point( aCenter
.X()-i
, nRect
.Bottom() ) );
98 pDev
->DrawPixel( Point( aCenter
.X()+i
, nRect
.Bottom() ) );
100 pDev
->DrawRect( tools::Rectangle( aCenter
.X()-n8
, nRect
.Top(),
101 aCenter
.X()+n8
, nRect
.Bottom()-1 ) );
104 case SymbolType::ARROW_LEFT
:
105 pDev
->DrawPixel( Point( nRect
.Left(), aCenter
.Y() ) );
106 for ( long i
=1; i
<= n2
; ++i
)
108 nRect
.AdjustLeft( 1 );
109 pDev
->DrawLine( Point( nRect
.Left(), aCenter
.Y()-i
),
110 Point( nRect
.Left(), aCenter
.Y()+i
) );
111 pDev
->DrawPixel( Point( nRect
.Left(), aCenter
.Y()-i
) );
112 pDev
->DrawPixel( Point( nRect
.Left(), aCenter
.Y()+i
) );
114 pDev
->DrawRect( tools::Rectangle( nRect
.Left()+1, aCenter
.Y()-n8
,
115 nRect
.Right(), aCenter
.Y()+n8
) );
118 case SymbolType::ARROW_RIGHT
:
119 pDev
->DrawPixel( Point( nRect
.Right(), aCenter
.Y() ) );
120 for ( long i
=1; i
<= n2
; ++i
)
122 nRect
.AdjustRight( -1 );
123 pDev
->DrawLine( Point( nRect
.Right(), aCenter
.Y()-i
),
124 Point( nRect
.Right(), aCenter
.Y()+i
) );
125 pDev
->DrawPixel( Point( nRect
.Right(), aCenter
.Y()-i
) );
126 pDev
->DrawPixel( Point( nRect
.Right(), aCenter
.Y()+i
) );
128 pDev
->DrawRect( tools::Rectangle( nRect
.Left(), aCenter
.Y()-n8
,
129 nRect
.Right()-1, aCenter
.Y()+n8
) );
132 case SymbolType::SPIN_UP
:
133 nRect
.AdjustTop(n4
);
134 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Top() ) );
135 for ( long i
=1; i
<= n2
; ++i
)
137 nRect
.AdjustTop( 1 );
138 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Top() ),
139 Point( aCenter
.X()+i
, nRect
.Top() ) );
140 pDev
->DrawPixel( Point( aCenter
.X()-i
, nRect
.Top() ) );
141 pDev
->DrawPixel( Point( aCenter
.X()+i
, nRect
.Top() ) );
145 case SymbolType::SPIN_DOWN
:
146 nRect
.AdjustBottom( -n4
);
147 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Bottom() ) );
148 for ( long i
=1; i
<= n2
; ++i
)
150 nRect
.AdjustBottom( -1 );
151 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Bottom() ),
152 Point( aCenter
.X()+i
, nRect
.Bottom() ) );
153 pDev
->DrawPixel( Point( aCenter
.X()-i
, nRect
.Bottom() ) );
154 pDev
->DrawPixel( Point( aCenter
.X()+i
, nRect
.Bottom() ) );
158 case SymbolType::SPIN_LEFT
:
159 case SymbolType::FIRST
:
160 case SymbolType::PREV
:
162 nRect
.AdjustLeft(n4
);
163 if ( eType
==SymbolType::FIRST
)
165 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top() ),
166 Point( nRect
.Left(), nRect
.Bottom() ) );
167 nRect
.AdjustLeft( 1 );
170 tools::Polygon
aTriangle(3);
171 aTriangle
.SetPoint(Point(nRect
.Left() + n2
, aCenter
.Y() - n2
), 0);
172 aTriangle
.SetPoint(Point(nRect
.Left(), aCenter
.Y()), 1);
173 aTriangle
.SetPoint(Point(nRect
.Left() + n2
, aCenter
.Y() + n2
), 2);
175 pDev
->Push(PushFlags::LINECOLOR
);
176 pDev
->SetLineColor();
177 pDev
->DrawPolygon(aTriangle
);
183 case SymbolType::SPIN_RIGHT
:
184 case SymbolType::LAST
:
185 case SymbolType::NEXT
:
186 case SymbolType::PLAY
:
188 nRect
.AdjustRight( -n4
);
189 if ( eType
==SymbolType::LAST
)
191 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Top() ),
192 Point( nRect
.Right(), nRect
.Bottom() ) );
193 nRect
.AdjustRight( -1 );
196 tools::Polygon
aTriangle(3);
197 aTriangle
.SetPoint(Point(nRect
.Right() - n2
, aCenter
.Y() - n2
), 0);
198 aTriangle
.SetPoint(Point(nRect
.Right(), aCenter
.Y()), 1);
199 aTriangle
.SetPoint(Point(nRect
.Right() - n2
, aCenter
.Y() + n2
), 2);
201 pDev
->Push(PushFlags::LINECOLOR
);
202 pDev
->SetLineColor();
203 pDev
->DrawPolygon(aTriangle
);
208 case SymbolType::PAGEUP
:
209 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Top() ) );
210 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Top()+n2
) );
211 for ( long i
=1; i
< n2
; ++i
)
213 nRect
.AdjustTop( 1 );
214 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Top() ),
215 Point( aCenter
.X()+i
, nRect
.Top() ) );
216 pDev
->DrawPixel( Point( aCenter
.X()-i
, nRect
.Top() ) );
217 pDev
->DrawPixel( Point( aCenter
.X()+i
, nRect
.Top() ) );
218 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Top()+n2
),
219 Point( aCenter
.X()+i
, nRect
.Top()+n2
) );
220 pDev
->DrawPixel( Point( aCenter
.X()-i
, nRect
.Top()+n2
) );
221 pDev
->DrawPixel( Point( aCenter
.X()+i
, nRect
.Top()+n2
) );
225 case SymbolType::PAGEDOWN
:
226 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Bottom() ) );
227 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Bottom()-n2
) );
228 for ( long i
=1; i
< n2
; ++i
)
230 nRect
.AdjustBottom( -1 );
231 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Bottom() ),
232 Point( aCenter
.X()+i
, nRect
.Bottom() ) );
233 pDev
->DrawPixel( Point( aCenter
.X()-i
, nRect
.Bottom() ) );
234 pDev
->DrawPixel( Point( aCenter
.X()+i
, nRect
.Bottom() ) );
235 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Bottom()-n2
),
236 Point( aCenter
.X()+i
, nRect
.Bottom()-n2
) );
237 pDev
->DrawPixel( Point( aCenter
.X()-i
, nRect
.Bottom()-n2
) );
238 pDev
->DrawPixel( Point( aCenter
.X()+i
, nRect
.Bottom()-n2
) );
242 case SymbolType::RADIOCHECKMARK
:
244 // Midpoint circle algorithm
249 pDev
->DrawLine( Point( aCenter
.X(), aCenter
.Y()-y
),
250 Point( aCenter
.X(), aCenter
.Y()+y
) );
255 // Draw vertical lines close to sides
256 pDev
->DrawLine( Point( aCenter
.X()+y
, aCenter
.Y()-x
),
257 Point( aCenter
.X()+y
, aCenter
.Y()+x
) );
258 pDev
->DrawLine( Point( aCenter
.X()-y
, aCenter
.Y()-x
),
259 Point( aCenter
.X()-y
, aCenter
.Y()+x
) );
265 // Draw vertical lines close to center
266 pDev
->DrawLine( Point( aCenter
.X()-x
, aCenter
.Y()-y
),
267 Point( aCenter
.X()-x
, aCenter
.Y()+y
) );
268 pDev
->DrawLine( Point( aCenter
.X()+x
, aCenter
.Y()-y
),
269 Point( aCenter
.X()+x
, aCenter
.Y()+y
) );
274 case SymbolType::STOP
:
275 pDev
->DrawRect( nRect
);
278 case SymbolType::CLOSE
:
279 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top() ),
280 Point( nRect
.Right(), nRect
.Bottom() ) );
281 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom() ),
282 Point( nRect
.Right(), nRect
.Top() ) );
283 for ( long i
=1; i
<n8
; ++i
)
285 pDev
->DrawLine( Point( nRect
.Left()+i
, nRect
.Top() ),
286 Point( nRect
.Right(), nRect
.Bottom()-i
) );
287 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top()+i
),
288 Point( nRect
.Right()-i
, nRect
.Bottom() ) );
289 pDev
->DrawLine( Point( nRect
.Left()+i
, nRect
.Bottom() ),
290 Point( nRect
.Right(), nRect
.Top()+i
) );
291 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom()-i
),
292 Point( nRect
.Right()-i
, nRect
.Top() ) );
296 case SymbolType::ROLLDOWN
:
297 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top() ),
298 Point( nRect
.Left(), nRect
.Bottom() ) );
299 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Top() ),
300 Point( nRect
.Right(), nRect
.Bottom() ) );
301 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom() ),
302 Point( nRect
.Right(), nRect
.Bottom() ) );
304 case SymbolType::ROLLUP
:
305 pDev
->DrawRect( tools::Rectangle( nRect
.Left(), nRect
.Top(),
306 nRect
.Right(), nRect
.Top()+n8
) );
309 case SymbolType::CHECKMARK
:
312 nRect
.AdjustTop( -(n3
/2) );
313 nRect
.AdjustBottom( -(n3
/2) );
314 // #106953# never mirror checkmarks
315 if ( pDev
->HasMirroredGraphics() && pDev
->IsRTLEnabled() )
317 // Draw a mirrored checkmark so that it looks "normal" in a
318 // mirrored graphics device (double mirroring!)
319 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Bottom()-n3
),
320 Point( nRect
.Right()-n3
, nRect
.Bottom() ) );
321 pDev
->DrawLine( Point( nRect
.Right()-n3
, nRect
.Bottom() ),
322 Point( nRect
.Left(), nRect
.Top()+n3
) );
323 nRect
.AdjustTop( 1 );
324 nRect
.AdjustBottom( 1 );
325 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Bottom()-n3
),
326 Point( nRect
.Right()-n3
, nRect
.Bottom() ) );
327 pDev
->DrawLine( Point( nRect
.Right()-n3
, nRect
.Bottom() ),
328 Point( nRect
.Left(), nRect
.Top()+n3
) );
332 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom()-n3
),
333 Point( nRect
.Left()+n3
, nRect
.Bottom() ) );
334 pDev
->DrawLine( Point( nRect
.Left()+n3
, nRect
.Bottom() ),
335 Point( nRect
.Right(), nRect
.Top()+n3
) );
336 nRect
.AdjustTop( 1 );
337 nRect
.AdjustBottom( 1 );
338 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom()-n3
),
339 Point( nRect
.Left()+n3
, nRect
.Bottom() ) );
340 pDev
->DrawLine( Point( nRect
.Left()+n3
, nRect
.Bottom() ),
341 Point( nRect
.Right(), nRect
.Top()+n3
) );
346 case SymbolType::FLOAT
:
347 nRect
.AdjustRight( -n4
);
348 nRect
.AdjustTop(n4
+1 );
349 pDev
->DrawRect( tools::Rectangle( nRect
.Left(), nRect
.Top(),
350 nRect
.Right(), nRect
.Top()+n8
) );
351 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top()+n8
),
352 Point( nRect
.Left(), nRect
.Bottom() ) );
353 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom() ),
354 Point( nRect
.Right(), nRect
.Bottom() ) );
355 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Top()+n8
),
356 Point( nRect
.Right(), nRect
.Bottom() ) );
357 nRect
.AdjustRight(n4
);
358 nRect
.AdjustTop( -(n4
+1) );
359 nRect
.AdjustLeft(n4
);
360 nRect
.AdjustBottom( -(n4
+1) );
361 pDev
->DrawRect( tools::Rectangle( nRect
.Left(), nRect
.Top(),
362 nRect
.Right(), nRect
.Top()+n8
) );
363 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top()+n8
),
364 Point( nRect
.Left(), nRect
.Bottom() ) );
365 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom() ),
366 Point( nRect
.Right(), nRect
.Bottom() ) );
367 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Top()+n8
),
368 Point( nRect
.Right(), nRect
.Bottom() ) );
371 case SymbolType::DOCK
:
372 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top() ),
373 Point( nRect
.Right(), nRect
.Top() ) );
374 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top() ),
375 Point( nRect
.Left(), nRect
.Bottom() ) );
376 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom() ),
377 Point( nRect
.Right(), nRect
.Bottom() ) );
378 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Top() ),
379 Point( nRect
.Right(), nRect
.Bottom() ) );
382 case SymbolType::HIDE
:
383 pDev
->DrawRect( tools::Rectangle( nRect
.Left()+n8
, nRect
.Bottom()-n8
,
384 nRect
.Right()-n8
, nRect
.Bottom() ) );
387 case SymbolType::PLUS
:
388 pDev
->DrawRect( tools::Rectangle( nRect
.Left(), aCenter
.Y()-n16
,
389 nRect
.Right(), aCenter
.Y()+n16
) );
390 pDev
->DrawRect( tools::Rectangle( aCenter
.X()-n16
, nRect
.Top(),
391 aCenter
.X()+n16
, nRect
.Bottom() ) );
393 case SymbolType::DONTKNOW
:
394 case SymbolType::IMAGE
:
395 case SymbolType::HELP
: break;
399 void ImplDrawDPILineRect( OutputDevice
*const pDev
, tools::Rectangle
& rRect
,
400 const Color
*const pColor
, const bool bRound
= false )
402 long nLineWidth
= pDev
->GetDPIX()/300;
403 long nLineHeight
= pDev
->GetDPIY()/300;
411 if ( (nLineWidth
== 1) && (nLineHeight
== 1) )
413 pDev
->SetLineColor( *pColor
);
416 pDev
->DrawLine( Point( rRect
.Left()+1, rRect
.Top()), Point( rRect
.Right()-1, rRect
.Top()) );
417 pDev
->DrawLine( Point( rRect
.Left()+1, rRect
.Bottom()), Point( rRect
.Right()-1, rRect
.Bottom()) );
418 pDev
->DrawLine( Point( rRect
.Left(), rRect
.Top()+1), Point( rRect
.Left(), rRect
.Bottom()-1) );
419 pDev
->DrawLine( Point( rRect
.Right(), rRect
.Top()+1), Point( rRect
.Right(), rRect
.Bottom()-1) );
423 pDev
->SetFillColor();
424 pDev
->DrawRect( rRect
);
429 const long nWidth
= rRect
.GetWidth();
430 const long nHeight
= rRect
.GetHeight();
431 pDev
->SetLineColor();
432 pDev
->SetFillColor( *pColor
);
433 pDev
->DrawRect( tools::Rectangle( rRect
.TopLeft(), Size( nWidth
, nLineHeight
) ) );
434 pDev
->DrawRect( tools::Rectangle( rRect
.TopLeft(), Size( nLineWidth
, nHeight
) ) );
435 pDev
->DrawRect( tools::Rectangle( Point( rRect
.Left(), rRect
.Bottom()-nLineHeight
),
436 Size( nWidth
, nLineHeight
) ) );
437 pDev
->DrawRect( tools::Rectangle( Point( rRect
.Right()-nLineWidth
, rRect
.Top() ),
438 Size( nLineWidth
, nHeight
) ) );
442 rRect
.AdjustLeft(nLineWidth
);
443 rRect
.AdjustTop(nLineHeight
);
444 rRect
.AdjustRight( -nLineWidth
);
445 rRect
.AdjustBottom( -nLineHeight
);
448 void ImplDraw2ColorFrame( OutputDevice
*const pDev
, tools::Rectangle
& rRect
,
449 const Color
& rLeftTopColor
, const Color
& rRightBottomColor
)
451 pDev
->SetLineColor( rLeftTopColor
);
452 pDev
->DrawLine( rRect
.TopLeft(), rRect
.BottomLeft() );
453 pDev
->DrawLine( rRect
.TopLeft(), rRect
.TopRight() );
454 pDev
->SetLineColor( rRightBottomColor
);
455 pDev
->DrawLine( rRect
.BottomLeft(), rRect
.BottomRight() );
456 pDev
->DrawLine( rRect
.TopRight(), rRect
.BottomRight() );
458 // reduce drawing area
459 rRect
.AdjustLeft( 1 );
460 rRect
.AdjustTop( 1 );
461 rRect
.AdjustRight( -1 );
462 rRect
.AdjustBottom( -1 );
465 void ImplDrawButton( OutputDevice
*const pDev
, tools::Rectangle aFillRect
,
466 const DrawButtonFlags nStyle
)
468 const StyleSettings
& rStyleSettings
= pDev
->GetSettings().GetStyleSettings();
470 if ( (nStyle
& DrawButtonFlags::Mono
) ||
471 (rStyleSettings
.GetOptions() & StyleSettingsOptions::Mono
) )
473 const Color
aBlackColor(COL_BLACK
);
475 if ( nStyle
& DrawButtonFlags::Default
)
477 // default selection shows a wider border
478 ImplDrawDPILineRect( pDev
, aFillRect
, &aBlackColor
);
481 ImplDrawDPILineRect( pDev
, aFillRect
, &aBlackColor
);
483 Size
aBrdSize( 1, 1 );
484 if ( pDev
->GetOutDevType() == OUTDEV_PRINTER
)
486 aBrdSize
= pDev
->LogicToPixel( Size( 20, 20 ), MapMode(MapUnit::Map100thMM
) );
487 if ( !aBrdSize
.Width() )
488 aBrdSize
.setWidth( 1 );
489 if ( !aBrdSize
.Height() )
490 aBrdSize
.setHeight( 1 );
493 pDev
->SetLineColor();
494 pDev
->SetFillColor( aBlackColor
);
495 const tools::Rectangle
aOrigFillRect(aFillRect
);
496 if ( nStyle
& (DrawButtonFlags::Pressed
| DrawButtonFlags::Checked
) )
499 aFillRect
.AdjustLeft(aBrdSize
.Width() );
500 aFillRect
.AdjustTop(aBrdSize
.Height() );
501 // draw top and left borders (aOrigFillRect-aFillRect)
502 pDev
->DrawRect( tools::Rectangle( aOrigFillRect
.Left(), aOrigFillRect
.Top(),
503 aOrigFillRect
.Right(), aFillRect
.Top()-1 ) );
504 pDev
->DrawRect( tools::Rectangle( aOrigFillRect
.Left(), aOrigFillRect
.Top(),
505 aFillRect
.Left()-1, aOrigFillRect
.Bottom() ) );
510 aFillRect
.AdjustRight( -(aBrdSize
.Width()) );
511 aFillRect
.AdjustBottom( -(aBrdSize
.Height()) );
512 // draw bottom and right borders (aOrigFillRect-aFillRect)
513 pDev
->DrawRect( tools::Rectangle( aOrigFillRect
.Left(), aFillRect
.Bottom()+1,
514 aOrigFillRect
.Right(), aOrigFillRect
.Bottom() ) );
515 pDev
->DrawRect( tools::Rectangle( aFillRect
.Right()+1, aOrigFillRect
.Top(),
516 aOrigFillRect
.Right(), aOrigFillRect
.Bottom() ) );
519 // Hack: in monochrome mode on printers we like to have grey buttons
520 if ( pDev
->GetOutDevType() == OUTDEV_PRINTER
)
521 pDev
->SetFillColor( COL_LIGHTGRAY
);
523 pDev
->SetFillColor( COL_WHITE
);
524 pDev
->DrawRect( aFillRect
);
528 if ( nStyle
& DrawButtonFlags::Default
)
530 const Color aDefBtnColor
= rStyleSettings
.GetDarkShadowColor();
531 ImplDrawDPILineRect( pDev
, aFillRect
, &aDefBtnColor
);
534 if ( nStyle
& DrawButtonFlags::NoLeftLightBorder
)
536 pDev
->SetLineColor( rStyleSettings
.GetLightBorderColor() );
537 pDev
->DrawLine( Point( aFillRect
.Left(), aFillRect
.Top() ),
538 Point( aFillRect
.Left(), aFillRect
.Bottom() ) );
539 aFillRect
.AdjustLeft( 1 );
544 if ( nStyle
& (DrawButtonFlags::Pressed
| DrawButtonFlags::Checked
) )
546 aColor1
= rStyleSettings
.GetDarkShadowColor();
547 aColor2
= rStyleSettings
.GetLightColor();
551 if ( nStyle
& DrawButtonFlags::NoLightBorder
)
552 aColor1
= rStyleSettings
.GetLightBorderColor();
554 aColor1
= rStyleSettings
.GetLightColor();
555 if ( (nStyle
& BUTTON_DRAW_FLATTEST
) == DrawButtonFlags::Flat
)
556 aColor2
= rStyleSettings
.GetShadowColor();
558 aColor2
= rStyleSettings
.GetDarkShadowColor();
561 ImplDraw2ColorFrame( pDev
, aFillRect
, aColor1
, aColor2
);
563 if ( (nStyle
& BUTTON_DRAW_FLATTEST
) != DrawButtonFlags::Flat
)
565 if ( nStyle
& (DrawButtonFlags::Pressed
| DrawButtonFlags::Checked
) )
567 aColor1
= rStyleSettings
.GetShadowColor();
568 aColor2
= rStyleSettings
.GetLightBorderColor();
572 if ( nStyle
& DrawButtonFlags::NoLightBorder
)
573 aColor1
= rStyleSettings
.GetLightColor();
575 aColor1
= rStyleSettings
.GetLightBorderColor();
576 aColor2
= rStyleSettings
.GetShadowColor();
578 ImplDraw2ColorFrame( pDev
, aFillRect
, aColor1
, aColor2
);
581 pDev
->SetLineColor();
582 if ( nStyle
& (DrawButtonFlags::Checked
| DrawButtonFlags::DontKnow
) )
583 pDev
->SetFillColor( rStyleSettings
.GetCheckedColor() );
585 pDev
->SetFillColor( rStyleSettings
.GetFaceColor() );
586 pDev
->DrawRect( aFillRect
);
590 void ImplDrawFrame( OutputDevice
*const pDev
, tools::Rectangle
& rRect
,
591 const StyleSettings
& rStyleSettings
, DrawFrameStyle nStyle
, DrawFrameFlags nFlags
)
593 vcl::Window
*const pWin
= (pDev
->GetOutDevType()==OUTDEV_WINDOW
) ? static_cast<vcl::Window
*>(pDev
) : nullptr;
595 const bool bMenuStyle(nFlags
& DrawFrameFlags::Menu
);
597 // UseFlatBorders disables 3D style for all frames except menus
598 // menus may use different border colors (eg on XP)
599 // normal frames will be drawn using the shadow color
600 // whereas window frame borders will use black
601 bool bFlatBorders
= !bMenuStyle
&& rStyleSettings
.GetUseFlatBorders();
603 // no flat borders for standard VCL controls (ie formcontrols that keep their classic look)
604 // will not affect frame windows (like dropdowns)
605 if( bFlatBorders
&& pWin
&& pWin
->GetType() == WindowType::BORDERWINDOW
&& (pWin
!= pWin
->ImplGetFrameWindow()) )
607 // check for formcontrol, i.e., a control without NWF enabled
608 Control
*const pControl
= dynamic_cast< Control
* >( pWin
->GetWindow( GetWindowType::Client
) );
609 if( !pControl
|| !pControl
->IsNativeWidgetEnabled() )
610 bFlatBorders
= false;
613 const bool bNoDraw(nFlags
& DrawFrameFlags::NoDraw
);
615 if ( (rStyleSettings
.GetOptions() & StyleSettingsOptions::Mono
) ||
616 (pDev
->GetOutDevType() == OUTDEV_PRINTER
) ||
618 nFlags
|= DrawFrameFlags::Mono
;
620 if( nStyle
!= DrawFrameStyle::NWF
&&
621 pWin
&& pWin
->IsNativeControlSupported(ControlType::Frame
, ControlPart::Border
) )
623 long nControlFlags
= static_cast<long>(nStyle
);
624 nControlFlags
|= static_cast<long>(nFlags
);
625 nControlFlags
|= static_cast<long>(pWin
->GetType() == WindowType::BORDERWINDOW
?
626 DrawFrameFlags::BorderWindowBorder
: DrawFrameFlags::NONE
);
627 ImplControlValue
aControlValue( nControlFlags
);
629 tools::Rectangle aBound
, aContent
;
630 tools::Rectangle
aNatRgn( rRect
);
631 if( pWin
->GetNativeControlRegion(ControlType::Frame
, ControlPart::Border
,
632 aNatRgn
, ControlState::NONE
, aControlValue
, aBound
, aContent
) )
634 // if bNoDraw is true then don't call the drawing routine
635 // but just update the target rectangle
637 pWin
->DrawNativeControl( ControlType::Frame
, ControlPart::Border
, aContent
, ControlState::ENABLED
,
638 aControlValue
, OUString()) )
646 if ( nFlags
& DrawFrameFlags::Mono
)
648 // no round corners for window frame borders
649 const bool bRound
= bFlatBorders
&& !(nFlags
& DrawFrameFlags::WindowBorder
);
653 ImplDrawDPILineRect( pDev
, rRect
, nullptr, bRound
);
657 Color aColor
= bRound
? rStyleSettings
.GetShadowColor()
658 : pDev
->GetSettings().GetStyleSettings().GetMonoColor();
659 // when the MonoColor wasn't set, check face color
661 (bRound
&& aColor
.IsDark()) ||
663 (aColor
== COL_BLACK
) &&
664 pDev
->GetSettings().GetStyleSettings().GetFaceColor().IsDark()
670 ImplDrawDPILineRect( pDev
, rRect
, &aColor
, bRound
);
679 case DrawFrameStyle::In
:
680 case DrawFrameStyle::Out
:
681 rRect
.AdjustLeft( 1 );
682 rRect
.AdjustTop( 1 );
683 rRect
.AdjustRight( -1 );
684 rRect
.AdjustBottom( -1 );
687 case DrawFrameStyle::Group
:
688 case DrawFrameStyle::DoubleIn
:
689 case DrawFrameStyle::DoubleOut
:
690 rRect
.AdjustLeft(2 );
692 rRect
.AdjustRight( -2 );
693 rRect
.AdjustBottom( -2 );
696 case DrawFrameStyle::NWF
:
697 // enough space for the native rendering
698 rRect
.AdjustLeft(4 );
700 rRect
.AdjustRight( -4 );
701 rRect
.AdjustBottom( -4 );
710 case DrawFrameStyle::Group
:
711 pDev
->SetFillColor();
712 pDev
->SetLineColor( rStyleSettings
.GetLightColor() );
713 pDev
->DrawRect( tools::Rectangle( rRect
.Left()+1, rRect
.Top()+1,
714 rRect
.Right(), rRect
.Bottom() ) );
715 pDev
->SetLineColor( rStyleSettings
.GetShadowColor() );
716 pDev
->DrawRect( tools::Rectangle( rRect
.Left(), rRect
.Top(),
717 rRect
.Right()-1, rRect
.Bottom()-1 ) );
719 // adjust target rectangle
720 rRect
.AdjustLeft(2 );
722 rRect
.AdjustRight( -2 );
723 rRect
.AdjustBottom( -2 );
726 case DrawFrameStyle::In
:
727 ImplDraw2ColorFrame( pDev
, rRect
,
728 rStyleSettings
.GetShadowColor(),
729 rStyleSettings
.GetLightColor() );
732 case DrawFrameStyle::Out
:
733 ImplDraw2ColorFrame( pDev
, rRect
,
734 rStyleSettings
.GetLightColor(),
735 rStyleSettings
.GetShadowColor() );
738 case DrawFrameStyle::DoubleIn
:
742 ImplDraw2ColorFrame( pDev
, rRect
,
743 rStyleSettings
.GetShadowColor(),
744 rStyleSettings
.GetShadowColor() );
745 ImplDraw2ColorFrame( pDev
, rRect
,
746 rStyleSettings
.GetFaceColor(),
747 rStyleSettings
.GetFaceColor() );
751 ImplDraw2ColorFrame( pDev
, rRect
,
752 rStyleSettings
.GetShadowColor(),
753 rStyleSettings
.GetLightColor() );
754 ImplDraw2ColorFrame( pDev
, rRect
,
755 rStyleSettings
.GetDarkShadowColor(),
756 rStyleSettings
.GetLightBorderColor() );
760 case DrawFrameStyle::DoubleOut
:
763 ImplDraw2ColorFrame( pDev
, rRect
,
764 rStyleSettings
.GetMenuBorderColor(),
765 rStyleSettings
.GetDarkShadowColor() );
766 if ( !rStyleSettings
.GetUseFlatMenus() )
768 ImplDraw2ColorFrame( pDev
, rRect
,
769 rStyleSettings
.GetLightColor(),
770 rStyleSettings
.GetShadowColor() );
775 ImplDraw2ColorFrame( pDev
, rRect
,
776 bFlatBorders
? // no 3d effect
777 rStyleSettings
.GetDarkShadowColor() :
778 rStyleSettings
.GetLightBorderColor(),
779 rStyleSettings
.GetDarkShadowColor() );
780 ImplDraw2ColorFrame( pDev
, rRect
,
781 rStyleSettings
.GetLightColor(),
782 rStyleSettings
.GetShadowColor() );
786 case DrawFrameStyle::NWF
:
787 // no rendering, just enough space for the native rendering
788 rRect
.AdjustLeft(4 );
790 rRect
.AdjustRight( -4 );
791 rRect
.AdjustBottom( -4 );
799 } // end anonymous namespace
801 DecorationView::DecorationView(OutputDevice
* pOutDev
) :
805 void DecorationView::DrawSymbol( const tools::Rectangle
& rRect
, SymbolType eType
,
806 const Color
& rColor
, DrawSymbolFlags nStyle
)
808 const StyleSettings
& rStyleSettings
= mpOutDev
->GetSettings().GetStyleSettings();
809 const tools::Rectangle aRect
= mpOutDev
->LogicToPixel( rRect
);
810 const Color aOldLineColor
= mpOutDev
->GetLineColor();
811 const Color aOldFillColor
= mpOutDev
->GetFillColor();
812 const bool bOldMapMode
= mpOutDev
->IsMapModeEnabled();
813 Color
nColor(rColor
);
814 mpOutDev
->EnableMapMode( false );
816 if ( (rStyleSettings
.GetOptions() & StyleSettingsOptions::Mono
) ||
817 (mpOutDev
->GetOutDevType() == OUTDEV_PRINTER
) )
818 nStyle
|= DrawSymbolFlags::Mono
;
820 if ( nStyle
& DrawSymbolFlags::Mono
)
822 // Monochrome: set color to black if enabled, to gray if disabled
823 nColor
= ( nStyle
& DrawSymbolFlags::Disable
) ? COL_GRAY
: COL_BLACK
;
827 if ( nStyle
& DrawSymbolFlags::Disable
)
829 // Draw shifted and brighter symbol for embossed look
830 mpOutDev
->SetLineColor( rStyleSettings
.GetLightColor() );
831 mpOutDev
->SetFillColor( rStyleSettings
.GetLightColor() );
832 ImplDrawSymbol( mpOutDev
, aRect
+ Point(1, 1) , eType
);
833 nColor
= rStyleSettings
.GetShadowColor();
837 // Set selected color and draw the symbol
838 mpOutDev
->SetLineColor( nColor
);
839 mpOutDev
->SetFillColor( nColor
);
840 ImplDrawSymbol( mpOutDev
, aRect
, eType
);
842 // Restore previous settings
843 mpOutDev
->SetLineColor( aOldLineColor
);
844 mpOutDev
->SetFillColor( aOldFillColor
);
845 mpOutDev
->EnableMapMode( bOldMapMode
);
848 void DecorationView::DrawFrame( const tools::Rectangle
& rRect
,
849 const Color
& rLeftTopColor
,
850 const Color
& rRightBottomColor
)
852 tools::Rectangle aRect
= mpOutDev
->LogicToPixel( rRect
);
853 const Color aOldLineColor
= mpOutDev
->GetLineColor();
854 const bool bOldMapMode
= mpOutDev
->IsMapModeEnabled();
855 mpOutDev
->EnableMapMode( false );
856 ImplDraw2ColorFrame( mpOutDev
, aRect
, rLeftTopColor
, rRightBottomColor
);
857 mpOutDev
->SetLineColor( aOldLineColor
);
858 mpOutDev
->EnableMapMode( bOldMapMode
);
861 void DecorationView::DrawHighlightFrame( const tools::Rectangle
& rRect
,
862 DrawHighlightFrameStyle nStyle
)
864 const StyleSettings
& rStyleSettings
= mpOutDev
->GetSettings().GetStyleSettings();
865 Color aLightColor
= rStyleSettings
.GetLightColor();
866 Color aShadowColor
= rStyleSettings
.GetShadowColor();
868 if ( (rStyleSettings
.GetOptions() & StyleSettingsOptions::Mono
) ||
869 (mpOutDev
->GetOutDevType() == OUTDEV_PRINTER
) )
871 aLightColor
= COL_BLACK
;
872 aShadowColor
= COL_BLACK
;
876 Wallpaper aBackground
= mpOutDev
->GetBackground();
877 if ( aBackground
.IsBitmap() || aBackground
.IsGradient() )
879 aLightColor
= rStyleSettings
.GetFaceColor();
880 aShadowColor
= COL_BLACK
;
884 Color aBackColor
= aBackground
.GetColor();
885 if ( (aLightColor
.GetColorError( aBackColor
) < 96) ||
886 (aShadowColor
.GetColorError( aBackColor
) < 96) )
888 aLightColor
= COL_WHITE
;
889 aShadowColor
= COL_BLACK
;
891 if ( aLightColor
.GetColorError( aBackColor
) < 96 )
892 aLightColor
.DecreaseLuminance( 64 );
893 if ( aShadowColor
.GetColorError( aBackColor
) < 96 )
894 aShadowColor
.IncreaseLuminance( 64 );
899 if ( nStyle
== DrawHighlightFrameStyle::In
)
901 Color aTempColor
= aLightColor
;
902 aLightColor
= aShadowColor
;
903 aShadowColor
= aTempColor
;
906 DrawFrame( rRect
, aLightColor
, aShadowColor
);
909 tools::Rectangle
DecorationView::DrawFrame( const tools::Rectangle
& rRect
, DrawFrameStyle nStyle
, DrawFrameFlags nFlags
)
911 tools::Rectangle aRect
= rRect
;
912 bool bOldMap
= mpOutDev
->IsMapModeEnabled();
915 aRect
= mpOutDev
->LogicToPixel( aRect
);
916 mpOutDev
->EnableMapMode( false );
919 if ( !rRect
.IsEmpty() )
921 if ( nFlags
& DrawFrameFlags::NoDraw
)
922 ImplDrawFrame( mpOutDev
, aRect
, mpOutDev
->GetSettings().GetStyleSettings(), nStyle
, nFlags
);
925 Color aOldLineColor
= mpOutDev
->GetLineColor();
926 Color aOldFillColor
= mpOutDev
->GetFillColor();
927 ImplDrawFrame( mpOutDev
, aRect
, mpOutDev
->GetSettings().GetStyleSettings(), nStyle
, nFlags
);
928 mpOutDev
->SetLineColor( aOldLineColor
);
929 mpOutDev
->SetFillColor( aOldFillColor
);
935 mpOutDev
->EnableMapMode( bOldMap
);
936 aRect
= mpOutDev
->PixelToLogic( aRect
);
942 tools::Rectangle
DecorationView::DrawButton( const tools::Rectangle
& rRect
, DrawButtonFlags nStyle
)
944 if ( rRect
.IsEmpty() )
949 tools::Rectangle aRect
= rRect
;
950 const bool bOldMap
= mpOutDev
->IsMapModeEnabled();
954 aRect
= mpOutDev
->LogicToPixel( aRect
);
955 mpOutDev
->EnableMapMode( false );
958 const Color aOldLineColor
= mpOutDev
->GetLineColor();
959 const Color aOldFillColor
= mpOutDev
->GetFillColor();
960 ImplDrawButton( mpOutDev
, aRect
, nStyle
);
961 mpOutDev
->SetLineColor( aOldLineColor
);
962 mpOutDev
->SetFillColor( aOldFillColor
);
964 // keep border free, although it is used at default representation
965 aRect
.AdjustLeft( 1 );
966 aRect
.AdjustTop( 1 );
967 aRect
.AdjustRight( -1 );
968 aRect
.AdjustBottom( -1 );
970 if ( nStyle
& DrawButtonFlags::NoLightBorder
)
972 aRect
.AdjustLeft( 1 );
973 aRect
.AdjustTop( 1 );
975 else if ( nStyle
& DrawButtonFlags::NoLeftLightBorder
)
977 aRect
.AdjustLeft( 1 );
980 if ( nStyle
& DrawButtonFlags::Pressed
)
982 if ( (aRect
.GetHeight() > 10) && (aRect
.GetWidth() > 10) )
984 aRect
.AdjustLeft(4 );
986 aRect
.AdjustRight( -1 );
987 aRect
.AdjustBottom( -1 );
991 aRect
.AdjustLeft(3 );
993 aRect
.AdjustRight( -2 );
994 aRect
.AdjustBottom( -2 );
997 else if ( nStyle
& DrawButtonFlags::Checked
)
999 aRect
.AdjustLeft(3 );
1000 aRect
.AdjustTop(3 );
1001 aRect
.AdjustRight( -2 );
1002 aRect
.AdjustBottom( -2 );
1006 aRect
.AdjustLeft(2 );
1007 aRect
.AdjustTop(2 );
1008 aRect
.AdjustRight( -3 );
1009 aRect
.AdjustBottom( -3 );
1014 mpOutDev
->EnableMapMode( bOldMap
);
1015 aRect
= mpOutDev
->PixelToLogic( aRect
);
1021 void DecorationView::DrawSeparator( const Point
& rStart
, const Point
& rStop
, bool bVertical
)
1023 Point
aStart( rStart
), aStop( rStop
);
1024 const StyleSettings
& rStyleSettings
= mpOutDev
->GetSettings().GetStyleSettings();
1025 vcl::Window
*const pWin
= (mpOutDev
->GetOutDevType()==OUTDEV_WINDOW
) ? static_cast<vcl::Window
*>(mpOutDev
.get()) : nullptr;
1028 ControlPart nPart
= ( bVertical
? ControlPart::SeparatorVert
: ControlPart::SeparatorHorz
);
1029 bool nativeSupported
= pWin
->IsNativeControlSupported( ControlType::Fixedline
, nPart
);
1030 ImplControlValue aValue
;
1031 tools::Rectangle
aRect(rStart
,rStop
);
1032 if(nativeSupported
&& pWin
->DrawNativeControl(ControlType::Fixedline
,nPart
,aRect
,ControlState::NONE
,aValue
,OUString()))
1036 mpOutDev
->Push( PushFlags::LINECOLOR
);
1037 if ( rStyleSettings
.GetOptions() & StyleSettingsOptions::Mono
)
1038 mpOutDev
->SetLineColor( COL_BLACK
);
1040 mpOutDev
->SetLineColor( rStyleSettings
.GetShadowColor() );
1042 mpOutDev
->DrawLine( aStart
, aStop
);
1043 if ( !(rStyleSettings
.GetOptions() & StyleSettingsOptions::Mono
) )
1045 mpOutDev
->SetLineColor( rStyleSettings
.GetLightColor() );
1048 aStart
.AdjustX( 1 );
1053 aStart
.AdjustY( 1 );
1056 mpOutDev
->DrawLine( aStart
, aStop
);
1061 void DecorationView::DrawHandle(const tools::Rectangle
& rRect
)
1063 const StyleSettings
& rStyleSettings
= mpOutDev
->GetSettings().GetStyleSettings();
1065 Size aOutputSize
= rRect
.GetSize();
1067 mpOutDev
->SetLineColor(rStyleSettings
.GetDarkShadowColor());
1068 mpOutDev
->SetFillColor(rStyleSettings
.GetDarkShadowColor());
1070 const sal_Int32 nNumberOfPoints
= 3;
1072 long nHalfWidth
= aOutputSize
.Width() / 2.0f
;
1074 float fDistance
= aOutputSize
.Height();
1075 fDistance
/= (nNumberOfPoints
+ 1);
1077 long nRadius
= aOutputSize
.Width();
1078 nRadius
/= (nNumberOfPoints
+ 2);
1080 for (long i
= 1; i
<= nNumberOfPoints
; i
++)
1082 tools::Rectangle
aLocation(nHalfWidth
- nRadius
,
1083 round(fDistance
* i
) - nRadius
,
1084 nHalfWidth
+ nRadius
,
1085 round(fDistance
* i
) + nRadius
);
1086 mpOutDev
->DrawEllipse(aLocation
);
1090 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */