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 #define BUTTON_DRAW_FLATTEST (DrawButtonFlags::Flat | \
27 DrawButtonFlags::Pressed | \
28 DrawButtonFlags::Checked | \
29 DrawButtonFlags::Highlight)
35 long AdjustRectToSquare( 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
, 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 Point aCenter
= nRect
.Center();
75 case SymbolType::ARROW_UP
:
76 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Top() ) );
77 for ( long i
=1; i
<= n2
; ++i
)
80 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Top() ),
81 Point( aCenter
.X()+i
, nRect
.Top() ) );
83 pDev
->DrawRect( Rectangle( aCenter
.X()-n8
, nRect
.Top()+1,
84 aCenter
.X()+n8
, nRect
.Bottom() ) );
87 case SymbolType::ARROW_DOWN
:
88 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Bottom() ) );
89 for ( long i
=1; i
<= n2
; ++i
)
92 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Bottom() ),
93 Point( aCenter
.X()+i
, nRect
.Bottom() ) );
95 pDev
->DrawRect( Rectangle( aCenter
.X()-n8
, nRect
.Top(),
96 aCenter
.X()+n8
, nRect
.Bottom()-1 ) );
99 case SymbolType::ARROW_LEFT
:
100 pDev
->DrawPixel( Point( nRect
.Left(), aCenter
.Y() ) );
101 for ( long i
=1; i
<= n2
; ++i
)
104 pDev
->DrawLine( Point( nRect
.Left(), aCenter
.Y()-i
),
105 Point( nRect
.Left(), aCenter
.Y()+i
) );
107 pDev
->DrawRect( Rectangle( nRect
.Left()+1, aCenter
.Y()-n8
,
108 nRect
.Right(), aCenter
.Y()+n8
) );
111 case SymbolType::ARROW_RIGHT
:
112 pDev
->DrawPixel( Point( nRect
.Right(), aCenter
.Y() ) );
113 for ( long i
=1; i
<= n2
; ++i
)
116 pDev
->DrawLine( Point( nRect
.Right(), aCenter
.Y()-i
),
117 Point( nRect
.Right(), aCenter
.Y()+i
) );
119 pDev
->DrawRect( Rectangle( nRect
.Left(), aCenter
.Y()-n8
,
120 nRect
.Right()-1, aCenter
.Y()+n8
) );
123 case SymbolType::SPIN_UP
:
125 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Top() ) );
126 for ( long i
=1; i
<= n2
; ++i
)
129 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Top() ),
130 Point( aCenter
.X()+i
, nRect
.Top() ) );
134 case SymbolType::SPIN_DOWN
:
135 nRect
.Bottom() -= n4
;
136 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Bottom() ) );
137 for ( long i
=1; i
<= n2
; ++i
)
140 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Bottom() ),
141 Point( aCenter
.X()+i
, nRect
.Bottom() ) );
145 case SymbolType::SPIN_LEFT
:
146 case SymbolType::FIRST
:
147 case SymbolType::PREV
:
148 case SymbolType::REVERSEPLAY
:
150 if ( eType
==SymbolType::FIRST
)
152 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top() ),
153 Point( nRect
.Left(), nRect
.Bottom() ) );
156 pDev
->DrawPixel( Point( nRect
.Left(), aCenter
.Y() ) );
157 for ( long i
=1; i
<= n2
; ++i
)
160 pDev
->DrawLine( Point( nRect
.Left(), aCenter
.Y()-i
),
161 Point( nRect
.Left(), aCenter
.Y()+i
) );
165 case SymbolType::SPIN_RIGHT
:
166 case SymbolType::LAST
:
167 case SymbolType::NEXT
:
168 case SymbolType::PLAY
:
170 if ( eType
==SymbolType::LAST
)
172 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Top() ),
173 Point( nRect
.Right(), nRect
.Bottom() ) );
176 pDev
->DrawPixel( Point( nRect
.Right(), aCenter
.Y() ) );
177 for ( long i
=1; i
<= n2
; ++i
)
180 pDev
->DrawLine( Point( nRect
.Right(), aCenter
.Y()-i
),
181 Point( nRect
.Right(), aCenter
.Y()+i
) );
185 case SymbolType::PAGEUP
:
186 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Top() ) );
187 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Top()+n2
) );
188 for ( long i
=1; i
< n2
; ++i
)
191 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Top() ),
192 Point( aCenter
.X()+i
, nRect
.Top() ) );
193 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Top()+n2
),
194 Point( aCenter
.X()+i
, nRect
.Top()+n2
) );
198 case SymbolType::PAGEDOWN
:
199 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Bottom() ) );
200 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Bottom()-n2
) );
201 for ( long i
=1; i
< n2
; ++i
)
204 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Bottom() ),
205 Point( aCenter
.X()+i
, nRect
.Bottom() ) );
206 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Bottom()-n2
),
207 Point( aCenter
.X()+i
, nRect
.Bottom()-n2
) );
211 case SymbolType::RADIOCHECKMARK
:
212 case SymbolType::RECORD
:
214 // Midpoint circle algorithm
219 pDev
->DrawLine( Point( aCenter
.X(), aCenter
.Y()-y
),
220 Point( aCenter
.X(), aCenter
.Y()+y
) );
225 // Draw vertical lines close to sides
226 pDev
->DrawLine( Point( aCenter
.X()+y
, aCenter
.Y()-x
),
227 Point( aCenter
.X()+y
, aCenter
.Y()+x
) );
228 pDev
->DrawLine( Point( aCenter
.X()-y
, aCenter
.Y()-x
),
229 Point( aCenter
.X()-y
, aCenter
.Y()+x
) );
235 // Draw vertical lines close to center
236 pDev
->DrawLine( Point( aCenter
.X()-x
, aCenter
.Y()-y
),
237 Point( aCenter
.X()-x
, aCenter
.Y()+y
) );
238 pDev
->DrawLine( Point( aCenter
.X()+x
, aCenter
.Y()-y
),
239 Point( aCenter
.X()+x
, aCenter
.Y()+y
) );
244 case SymbolType::STOP
:
245 pDev
->DrawRect( nRect
);
248 case SymbolType::PAUSE
:
249 pDev
->DrawRect( Rectangle ( nRect
.Left(), nRect
.Top(),
250 aCenter
.X()-n8
, nRect
.Bottom() ) );
251 pDev
->DrawRect( Rectangle ( aCenter
.X()+n8
, nRect
.Top(),
252 nRect
.Right(), nRect
.Bottom() ) );
255 case SymbolType::WINDSTART
:
256 pDev
->DrawLine( Point( nRect
.Left(), aCenter
.Y()-n2
+1 ),
257 Point( nRect
.Left(), aCenter
.Y()+n2
-1 ) );
260 case SymbolType::WINDBACKWARD
:
261 pDev
->DrawPixel( Point( nRect
.Left(), aCenter
.Y() ) );
262 pDev
->DrawPixel( Point( nRect
.Left()+n2
, aCenter
.Y() ) );
263 for ( long i
=1; i
< n2
; ++i
)
266 pDev
->DrawLine( Point( nRect
.Left(), aCenter
.Y()-i
),
267 Point( nRect
.Left(), aCenter
.Y()+i
) );
268 pDev
->DrawLine( Point( nRect
.Left()+n2
, aCenter
.Y()-i
),
269 Point( nRect
.Left()+n2
, aCenter
.Y()+i
) );
273 case SymbolType::WINDEND
:
274 pDev
->DrawLine( Point( nRect
.Right(), aCenter
.Y()-n2
+1 ),
275 Point( nRect
.Right(), aCenter
.Y()+n2
-1 ) );
278 case SymbolType::WINDFORWARD
:
279 pDev
->DrawPixel( Point( nRect
.Right(), aCenter
.Y() ) );
280 pDev
->DrawPixel( Point( nRect
.Right()-n2
, aCenter
.Y() ) );
281 for ( long i
=1; i
< n2
; ++i
)
284 pDev
->DrawLine( Point( nRect
.Right(), aCenter
.Y()-i
),
285 Point( nRect
.Right(), aCenter
.Y()+i
) );
286 pDev
->DrawLine( Point( nRect
.Right()-n2
, aCenter
.Y()-i
),
287 Point( nRect
.Right()-n2
, aCenter
.Y()+i
) );
291 case SymbolType::CLOSE
:
292 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top() ),
293 Point( nRect
.Right(), nRect
.Bottom() ) );
294 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom() ),
295 Point( nRect
.Right(), nRect
.Top() ) );
296 for ( long i
=1; i
<n8
; ++i
)
298 pDev
->DrawLine( Point( nRect
.Left()+i
, nRect
.Top() ),
299 Point( nRect
.Right(), nRect
.Bottom()-i
) );
300 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top()+i
),
301 Point( nRect
.Right()-i
, nRect
.Bottom() ) );
302 pDev
->DrawLine( Point( nRect
.Left()+i
, nRect
.Bottom() ),
303 Point( nRect
.Right(), nRect
.Top()+i
) );
304 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom()-i
),
305 Point( nRect
.Right()-i
, nRect
.Top() ) );
309 case SymbolType::ROLLDOWN
:
310 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top() ),
311 Point( nRect
.Left(), nRect
.Bottom() ) );
312 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Top() ),
313 Point( nRect
.Right(), nRect
.Bottom() ) );
314 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom() ),
315 Point( nRect
.Right(), nRect
.Bottom() ) );
317 case SymbolType::ROLLUP
:
318 pDev
->DrawRect( Rectangle( nRect
.Left(), nRect
.Top(),
319 nRect
.Right(), nRect
.Top()+n8
) );
322 case SymbolType::CHECKMARK
:
326 nRect
.Bottom() -= n3
/2;
327 // #106953# never mirror checkmarks
328 if ( pDev
->HasMirroredGraphics() && pDev
->IsRTLEnabled() )
330 // Draw a mirrored checkmark so that it looks "normal" in a
331 // mirrored graphics device (double mirroring!)
332 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Bottom()-n3
),
333 Point( nRect
.Right()-n3
, nRect
.Bottom() ) );
334 pDev
->DrawLine( Point( nRect
.Right()-n3
, nRect
.Bottom() ),
335 Point( nRect
.Left(), nRect
.Top()+n3
) );
338 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Bottom()-n3
),
339 Point( nRect
.Right()-n3
, nRect
.Bottom() ) );
340 pDev
->DrawLine( Point( nRect
.Right()-n3
, nRect
.Bottom() ),
341 Point( nRect
.Left(), nRect
.Top()+n3
) );
345 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom()-n3
),
346 Point( nRect
.Left()+n3
, nRect
.Bottom() ) );
347 pDev
->DrawLine( Point( nRect
.Left()+n3
, nRect
.Bottom() ),
348 Point( nRect
.Right(), nRect
.Top()+n3
) );
351 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom()-n3
),
352 Point( nRect
.Left()+n3
, nRect
.Bottom() ) );
353 pDev
->DrawLine( Point( nRect
.Left()+n3
, nRect
.Bottom() ),
354 Point( nRect
.Right(), nRect
.Top()+n3
) );
359 case SymbolType::SPIN_UPDOWN
:
360 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Top() ) );
361 pDev
->DrawPixel( Point( aCenter
.X(), nRect
.Bottom() ) );
362 for ( long i
=1; i
< n2
; ++i
)
366 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Top() ),
367 Point( aCenter
.X()+i
, nRect
.Top() ) );
368 pDev
->DrawLine( Point( aCenter
.X()-i
, nRect
.Bottom() ),
369 Point( aCenter
.X()+i
, nRect
.Bottom() ) );
373 case SymbolType::FLOAT
:
376 pDev
->DrawRect( Rectangle( nRect
.Left(), nRect
.Top(),
377 nRect
.Right(), nRect
.Top()+n8
) );
378 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top()+n8
),
379 Point( nRect
.Left(), nRect
.Bottom() ) );
380 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom() ),
381 Point( nRect
.Right(), nRect
.Bottom() ) );
382 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Top()+n8
),
383 Point( nRect
.Right(), nRect
.Bottom() ) );
387 nRect
.Bottom() -= n4
+1;
388 pDev
->DrawRect( Rectangle( nRect
.Left(), nRect
.Top(),
389 nRect
.Right(), nRect
.Top()+n8
) );
390 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top()+n8
),
391 Point( nRect
.Left(), nRect
.Bottom() ) );
392 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom() ),
393 Point( nRect
.Right(), nRect
.Bottom() ) );
394 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Top()+n8
),
395 Point( nRect
.Right(), nRect
.Bottom() ) );
398 case SymbolType::DOCK
:
399 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top() ),
400 Point( nRect
.Right(), nRect
.Top() ) );
401 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Top() ),
402 Point( nRect
.Left(), nRect
.Bottom() ) );
403 pDev
->DrawLine( Point( nRect
.Left(), nRect
.Bottom() ),
404 Point( nRect
.Right(), nRect
.Bottom() ) );
405 pDev
->DrawLine( Point( nRect
.Right(), nRect
.Top() ),
406 Point( nRect
.Right(), nRect
.Bottom() ) );
409 case SymbolType::HIDE
:
410 pDev
->DrawRect( Rectangle( nRect
.Left()+n8
, nRect
.Bottom()-n8
,
411 nRect
.Right()-n8
, nRect
.Bottom() ) );
414 case SymbolType::PLUS
:
415 pDev
->DrawRect( Rectangle( nRect
.Left(), aCenter
.Y()-n8
/2,
416 nRect
.Right()+1, aCenter
.Y()+n8
/2+1 ) );
417 pDev
->DrawRect( Rectangle( aCenter
.X()-n8
/2, nRect
.Top(),
418 aCenter
.X()+n8
/2+1, nRect
.Bottom()+1 ) );
420 case SymbolType::DONTKNOW
:
421 case SymbolType::IMAGE
:
422 case SymbolType::HELP
: break;
426 void ImplDrawDPILineRect( OutputDevice
*const pDev
, Rectangle
& rRect
,
427 const Color
*const pColor
, const bool bRound
= false )
429 long nLineWidth
= pDev
->GetDPIX()/300;
430 long nLineHeight
= pDev
->GetDPIY()/300;
438 if ( (nLineWidth
== 1) && (nLineHeight
== 1) )
440 pDev
->SetLineColor( *pColor
);
443 pDev
->DrawLine( Point( rRect
.Left()+1, rRect
.Top()), Point( rRect
.Right()-1, rRect
.Top()) );
444 pDev
->DrawLine( Point( rRect
.Left()+1, rRect
.Bottom()), Point( rRect
.Right()-1, rRect
.Bottom()) );
445 pDev
->DrawLine( Point( rRect
.Left(), rRect
.Top()+1), Point( rRect
.Left(), rRect
.Bottom()-1) );
446 pDev
->DrawLine( Point( rRect
.Right(), rRect
.Top()+1), Point( rRect
.Right(), rRect
.Bottom()-1) );
450 pDev
->SetFillColor();
451 pDev
->DrawRect( rRect
);
456 const long nWidth
= rRect
.GetWidth();
457 const long nHeight
= rRect
.GetHeight();
458 pDev
->SetLineColor();
459 pDev
->SetFillColor( *pColor
);
460 pDev
->DrawRect( Rectangle( rRect
.TopLeft(), Size( nWidth
, nLineHeight
) ) );
461 pDev
->DrawRect( Rectangle( rRect
.TopLeft(), Size( nLineWidth
, nHeight
) ) );
462 pDev
->DrawRect( Rectangle( Point( rRect
.Left(), rRect
.Bottom()-nLineHeight
),
463 Size( nWidth
, nLineHeight
) ) );
464 pDev
->DrawRect( Rectangle( Point( rRect
.Right()-nLineWidth
, rRect
.Top() ),
465 Size( nLineWidth
, nHeight
) ) );
469 rRect
.Left() += nLineWidth
;
470 rRect
.Top() += nLineHeight
;
471 rRect
.Right() -= nLineWidth
;
472 rRect
.Bottom() -= nLineHeight
;
475 void ImplDraw2ColorFrame( OutputDevice
*const pDev
, Rectangle
& rRect
,
476 const Color
& rLeftTopColor
, const Color
& rRightBottomColor
)
478 pDev
->SetLineColor( rLeftTopColor
);
479 pDev
->DrawLine( rRect
.TopLeft(), rRect
.BottomLeft() );
480 pDev
->DrawLine( rRect
.TopLeft(), rRect
.TopRight() );
481 pDev
->SetLineColor( rRightBottomColor
);
482 pDev
->DrawLine( rRect
.BottomLeft(), rRect
.BottomRight() );
483 pDev
->DrawLine( rRect
.TopRight(), rRect
.BottomRight() );
485 // reduce drawing area
492 void ImplDrawButton( OutputDevice
*const pDev
, Rectangle aFillRect
,
493 const DrawButtonFlags nStyle
)
495 const StyleSettings
& rStyleSettings
= pDev
->GetSettings().GetStyleSettings();
497 if ( (nStyle
& DrawButtonFlags::Mono
) ||
498 (rStyleSettings
.GetOptions() & StyleSettingsOptions::Mono
) )
500 const Color
aBlackColor( COL_BLACK
);
502 if ( nStyle
& DrawButtonFlags::Default
)
504 // default selection shows a wider border
505 ImplDrawDPILineRect( pDev
, aFillRect
, &aBlackColor
);
508 ImplDrawDPILineRect( pDev
, aFillRect
, &aBlackColor
);
510 Size
aBrdSize( 1, 1 );
511 if ( pDev
->GetOutDevType() == OUTDEV_PRINTER
)
513 aBrdSize
= pDev
->LogicToPixel( Size( 20, 20 ), MapMode(MapUnit::Map100thMM
) );
514 if ( !aBrdSize
.Width() )
515 aBrdSize
.Width() = 1;
516 if ( !aBrdSize
.Height() )
517 aBrdSize
.Height() = 1;
520 pDev
->SetLineColor();
521 pDev
->SetFillColor( aBlackColor
);
522 const Rectangle
aOrigFillRect(aFillRect
);
523 if ( nStyle
& (DrawButtonFlags::Pressed
| DrawButtonFlags::Checked
) )
526 aFillRect
.Left() += aBrdSize
.Width();
527 aFillRect
.Top() += aBrdSize
.Height();
528 // draw top and left borders (aOrigFillRect-aFillRect)
529 pDev
->DrawRect( Rectangle( aOrigFillRect
.Left(), aOrigFillRect
.Top(),
530 aOrigFillRect
.Right(), aFillRect
.Top()-1 ) );
531 pDev
->DrawRect( Rectangle( aOrigFillRect
.Left(), aOrigFillRect
.Top(),
532 aFillRect
.Left()-1, aOrigFillRect
.Bottom() ) );
537 aFillRect
.Right() -= aBrdSize
.Width();
538 aFillRect
.Bottom() -= aBrdSize
.Height();
539 // draw bottom and right borders (aOrigFillRect-aFillRect)
540 pDev
->DrawRect( Rectangle( aOrigFillRect
.Left(), aFillRect
.Bottom()+1,
541 aOrigFillRect
.Right(), aOrigFillRect
.Bottom() ) );
542 pDev
->DrawRect( Rectangle( aFillRect
.Right()+1, aOrigFillRect
.Top(),
543 aOrigFillRect
.Right(), aOrigFillRect
.Bottom() ) );
546 if ( !(nStyle
& DrawButtonFlags::NoFill
) )
548 // Hack: in monochrome mode on printers we like to have grey buttons
549 if ( pDev
->GetOutDevType() == OUTDEV_PRINTER
)
550 pDev
->SetFillColor( Color( COL_LIGHTGRAY
) );
552 pDev
->SetFillColor( Color( COL_WHITE
) );
553 pDev
->DrawRect( aFillRect
);
558 if ( nStyle
& DrawButtonFlags::Default
)
560 const Color aDefBtnColor
= rStyleSettings
.GetDarkShadowColor();
561 ImplDrawDPILineRect( pDev
, aFillRect
, &aDefBtnColor
);
564 if ( nStyle
& DrawButtonFlags::NoLeftLightBorder
)
566 pDev
->SetLineColor( rStyleSettings
.GetLightBorderColor() );
567 pDev
->DrawLine( Point( aFillRect
.Left(), aFillRect
.Top() ),
568 Point( aFillRect
.Left(), aFillRect
.Bottom() ) );
574 if ( nStyle
& (DrawButtonFlags::Pressed
| DrawButtonFlags::Checked
) )
576 aColor1
= rStyleSettings
.GetDarkShadowColor();
577 aColor2
= rStyleSettings
.GetLightColor();
581 if ( nStyle
& DrawButtonFlags::NoLightBorder
)
582 aColor1
= rStyleSettings
.GetLightBorderColor();
584 aColor1
= rStyleSettings
.GetLightColor();
585 if ( (nStyle
& BUTTON_DRAW_FLATTEST
) == DrawButtonFlags::Flat
)
586 aColor2
= rStyleSettings
.GetShadowColor();
588 aColor2
= rStyleSettings
.GetDarkShadowColor();
591 ImplDraw2ColorFrame( pDev
, aFillRect
, aColor1
, aColor2
);
593 if ( !((nStyle
& BUTTON_DRAW_FLATTEST
) == DrawButtonFlags::Flat
) )
595 if ( nStyle
& (DrawButtonFlags::Pressed
| DrawButtonFlags::Checked
) )
597 aColor1
= rStyleSettings
.GetShadowColor();
598 aColor2
= rStyleSettings
.GetLightBorderColor();
602 if ( nStyle
& DrawButtonFlags::NoLightBorder
)
603 aColor1
= rStyleSettings
.GetLightColor();
605 aColor1
= rStyleSettings
.GetLightBorderColor();
606 aColor2
= rStyleSettings
.GetShadowColor();
608 ImplDraw2ColorFrame( pDev
, aFillRect
, aColor1
, aColor2
);
611 if ( !(nStyle
& DrawButtonFlags::NoFill
) )
613 pDev
->SetLineColor();
614 if ( nStyle
& (DrawButtonFlags::Checked
| DrawButtonFlags::DontKnow
) )
615 pDev
->SetFillColor( rStyleSettings
.GetCheckedColor() );
617 pDev
->SetFillColor( rStyleSettings
.GetFaceColor() );
618 pDev
->DrawRect( aFillRect
);
623 void ImplDrawFrame( OutputDevice
*const pDev
, Rectangle
& rRect
,
624 const StyleSettings
& rStyleSettings
, DrawFrameStyle nStyle
, DrawFrameFlags nFlags
)
626 vcl::Window
*const pWin
= (pDev
->GetOutDevType()==OUTDEV_WINDOW
) ? static_cast<vcl::Window
*>(pDev
) : nullptr;
628 const bool bMenuStyle(nFlags
& DrawFrameFlags::Menu
);
630 // UseFlatBorders disables 3D style for all frames except menus
631 // menus may use different border colors (eg on XP)
632 // normal frames will be drawn using the shadow color
633 // whereas window frame borders will use black
634 bool bFlatBorders
= !bMenuStyle
&& rStyleSettings
.GetUseFlatBorders();
636 // no flat borders for standard VCL controls (ie formcontrols that keep their classic look)
637 // will not affect frame windows (like dropdowns)
638 if( bFlatBorders
&& pWin
&& pWin
->GetType() == WINDOW_BORDERWINDOW
&& (pWin
!= pWin
->ImplGetFrameWindow()) )
640 // check for formcontrol, i.e., a control without NWF enabled
641 Control
*const pControl
= dynamic_cast< Control
* >( pWin
->GetWindow( GetWindowType::Client
) );
642 if( !pControl
|| !pControl
->IsNativeWidgetEnabled() )
643 bFlatBorders
= false;
646 const bool bNoDraw(nFlags
& DrawFrameFlags::NoDraw
);
648 if ( (rStyleSettings
.GetOptions() & StyleSettingsOptions::Mono
) ||
649 (pDev
->GetOutDevType() == OUTDEV_PRINTER
) ||
651 nFlags
|= DrawFrameFlags::Mono
;
653 if( nStyle
!= DrawFrameStyle::NWF
&&
654 pWin
&& pWin
->IsNativeControlSupported(ControlType::Frame
, ControlPart::Border
) )
656 long nControlFlags
= static_cast<long>(nStyle
);
657 nControlFlags
|= static_cast<long>(nFlags
);
658 nControlFlags
|= static_cast<long>(pWin
->GetType()==WINDOW_BORDERWINDOW
?
659 DrawFrameFlags::BorderWindowBorder
: DrawFrameFlags::NONE
);
660 ImplControlValue
aControlValue( nControlFlags
);
662 Rectangle aBound
, aContent
;
663 Rectangle
aNatRgn( rRect
);
664 if( pWin
->GetNativeControlRegion(ControlType::Frame
, ControlPart::Border
,
665 aNatRgn
, ControlState::NONE
, aControlValue
, OUString(), aBound
, aContent
) )
667 // if bNoDraw is true then don't call the drawing routine
668 // but just update the target rectangle
670 pWin
->DrawNativeControl( ControlType::Frame
, ControlPart::Border
, aContent
, ControlState::ENABLED
,
671 aControlValue
, OUString()) )
679 if ( nFlags
& DrawFrameFlags::Mono
)
681 // no round corners for window frame borders
682 const bool bRound
= bFlatBorders
&& !(nFlags
& DrawFrameFlags::WindowBorder
);
686 ImplDrawDPILineRect( pDev
, rRect
, nullptr, bRound
);
690 Color aColor
= bRound
? rStyleSettings
.GetShadowColor()
691 : pDev
->GetSettings().GetStyleSettings().GetMonoColor();
692 // when the MonoColor wasn't set, check face color
694 (bRound
&& aColor
.IsDark()) ||
696 (aColor
== Color(COL_BLACK
)) &&
697 pDev
->GetSettings().GetStyleSettings().GetFaceColor().IsDark()
701 aColor
= Color( COL_WHITE
);
703 ImplDrawDPILineRect( pDev
, rRect
, &aColor
, bRound
);
712 case DrawFrameStyle::In
:
713 case DrawFrameStyle::Out
:
720 case DrawFrameStyle::Group
:
721 case DrawFrameStyle::DoubleIn
:
722 case DrawFrameStyle::DoubleOut
:
729 case DrawFrameStyle::NWF
:
730 // enough space for the native rendering
743 case DrawFrameStyle::Group
:
744 pDev
->SetFillColor();
745 pDev
->SetLineColor( rStyleSettings
.GetLightColor() );
746 pDev
->DrawRect( Rectangle( rRect
.Left()+1, rRect
.Top()+1,
747 rRect
.Right(), rRect
.Bottom() ) );
748 pDev
->SetLineColor( rStyleSettings
.GetShadowColor() );
749 pDev
->DrawRect( Rectangle( rRect
.Left(), rRect
.Top(),
750 rRect
.Right()-1, rRect
.Bottom()-1 ) );
752 // adjust target rectangle
759 case DrawFrameStyle::In
:
760 ImplDraw2ColorFrame( pDev
, rRect
,
761 rStyleSettings
.GetShadowColor(),
762 rStyleSettings
.GetLightColor() );
765 case DrawFrameStyle::Out
:
766 ImplDraw2ColorFrame( pDev
, rRect
,
767 rStyleSettings
.GetLightColor(),
768 rStyleSettings
.GetShadowColor() );
771 case DrawFrameStyle::DoubleIn
:
775 ImplDraw2ColorFrame( pDev
, rRect
,
776 rStyleSettings
.GetShadowColor(),
777 rStyleSettings
.GetShadowColor() );
778 ImplDraw2ColorFrame( pDev
, rRect
,
779 rStyleSettings
.GetFaceColor(),
780 rStyleSettings
.GetFaceColor() );
784 ImplDraw2ColorFrame( pDev
, rRect
,
785 rStyleSettings
.GetShadowColor(),
786 rStyleSettings
.GetLightColor() );
787 ImplDraw2ColorFrame( pDev
, rRect
,
788 rStyleSettings
.GetDarkShadowColor(),
789 rStyleSettings
.GetLightBorderColor() );
793 case DrawFrameStyle::DoubleOut
:
796 ImplDraw2ColorFrame( pDev
, rRect
,
797 rStyleSettings
.GetMenuBorderColor(),
798 rStyleSettings
.GetDarkShadowColor() );
799 if ( !rStyleSettings
.GetUseFlatMenus() )
801 ImplDraw2ColorFrame( pDev
, rRect
,
802 rStyleSettings
.GetLightColor(),
803 rStyleSettings
.GetShadowColor() );
808 ImplDraw2ColorFrame( pDev
, rRect
,
809 bFlatBorders
? // no 3d effect
810 rStyleSettings
.GetDarkShadowColor() :
811 rStyleSettings
.GetLightBorderColor(),
812 rStyleSettings
.GetDarkShadowColor() );
813 ImplDraw2ColorFrame( pDev
, rRect
,
814 rStyleSettings
.GetLightColor(),
815 rStyleSettings
.GetShadowColor() );
819 case DrawFrameStyle::NWF
:
820 // no rendering, just enough space for the native rendering
832 } // end anonymous namespace
834 DecorationView::DecorationView(OutputDevice
* pOutDev
) :
838 void DecorationView::DrawSymbol( const Rectangle
& rRect
, SymbolType eType
,
839 const Color
& rColor
, DrawSymbolFlags nStyle
)
841 const StyleSettings
& rStyleSettings
= mpOutDev
->GetSettings().GetStyleSettings();
842 const Rectangle aRect
= mpOutDev
->LogicToPixel( rRect
);
843 const Color aOldLineColor
= mpOutDev
->GetLineColor();
844 const Color aOldFillColor
= mpOutDev
->GetFillColor();
845 const bool bOldMapMode
= mpOutDev
->IsMapModeEnabled();
846 Color
nColor(rColor
);
847 mpOutDev
->EnableMapMode( false );
849 if ( (rStyleSettings
.GetOptions() & StyleSettingsOptions::Mono
) ||
850 (mpOutDev
->GetOutDevType() == OUTDEV_PRINTER
) )
851 nStyle
|= DrawSymbolFlags::Mono
;
853 if ( nStyle
& DrawSymbolFlags::Mono
)
855 // Monochrome: set color to black if enabled, to gray if disabled
856 nColor
= Color( ( nStyle
& DrawSymbolFlags::Disable
) ? COL_GRAY
: COL_BLACK
);
860 if ( nStyle
& DrawSymbolFlags::Disable
)
862 // Draw shifted and brighter symbol for embossed look
863 mpOutDev
->SetLineColor( rStyleSettings
.GetLightColor() );
864 mpOutDev
->SetFillColor( rStyleSettings
.GetLightColor() );
865 ImplDrawSymbol( mpOutDev
, aRect
+ Point(1, 1) , eType
);
866 nColor
= rStyleSettings
.GetShadowColor();
870 // Set selected color and draw the symbol
871 mpOutDev
->SetLineColor( nColor
);
872 mpOutDev
->SetFillColor( nColor
);
873 ImplDrawSymbol( mpOutDev
, aRect
, eType
);
875 // Restore previous settings
876 mpOutDev
->SetLineColor( aOldLineColor
);
877 mpOutDev
->SetFillColor( aOldFillColor
);
878 mpOutDev
->EnableMapMode( bOldMapMode
);
881 void DecorationView::DrawFrame( const Rectangle
& rRect
,
882 const Color
& rLeftTopColor
,
883 const Color
& rRightBottomColor
)
885 Rectangle aRect
= mpOutDev
->LogicToPixel( rRect
);
886 const Color aOldLineColor
= mpOutDev
->GetLineColor();
887 const bool bOldMapMode
= mpOutDev
->IsMapModeEnabled();
888 mpOutDev
->EnableMapMode( false );
889 ImplDraw2ColorFrame( mpOutDev
, aRect
, rLeftTopColor
, rRightBottomColor
);
890 mpOutDev
->SetLineColor( aOldLineColor
);
891 mpOutDev
->EnableMapMode( bOldMapMode
);
894 void DecorationView::DrawHighlightFrame( const Rectangle
& rRect
,
895 DrawHighlightFrameStyle nStyle
)
897 const StyleSettings
& rStyleSettings
= mpOutDev
->GetSettings().GetStyleSettings();
898 Color aLightColor
= rStyleSettings
.GetLightColor();
899 Color aShadowColor
= rStyleSettings
.GetShadowColor();
901 if ( (rStyleSettings
.GetOptions() & StyleSettingsOptions::Mono
) ||
902 (mpOutDev
->GetOutDevType() == OUTDEV_PRINTER
) )
904 aLightColor
= Color( COL_BLACK
);
905 aShadowColor
= Color( COL_BLACK
);
909 Wallpaper aBackground
= mpOutDev
->GetBackground();
910 if ( aBackground
.IsBitmap() || aBackground
.IsGradient() )
912 aLightColor
= rStyleSettings
.GetFaceColor();
913 aShadowColor
= Color( COL_BLACK
);
917 Color aBackColor
= aBackground
.GetColor();
918 if ( (aLightColor
.GetColorError( aBackColor
) < 32) ||
919 (aShadowColor
.GetColorError( aBackColor
) < 32) )
921 aLightColor
= Color( COL_WHITE
);
922 aShadowColor
= Color( COL_BLACK
);
924 if ( aLightColor
.GetColorError( aBackColor
) < 32 )
925 aLightColor
.DecreaseLuminance( 64 );
926 if ( aShadowColor
.GetColorError( aBackColor
) < 32 )
927 aShadowColor
.IncreaseLuminance( 64 );
932 if ( nStyle
== DrawHighlightFrameStyle::In
)
934 Color aTempColor
= aLightColor
;
935 aLightColor
= aShadowColor
;
936 aShadowColor
= aTempColor
;
939 DrawFrame( rRect
, aLightColor
, aShadowColor
);
942 Rectangle
DecorationView::DrawFrame( const Rectangle
& rRect
, DrawFrameStyle nStyle
, DrawFrameFlags nFlags
)
944 Rectangle aRect
= rRect
;
945 bool bOldMap
= mpOutDev
->IsMapModeEnabled();
948 aRect
= mpOutDev
->LogicToPixel( aRect
);
949 mpOutDev
->EnableMapMode( false );
952 if ( !rRect
.IsEmpty() )
954 if ( nFlags
& DrawFrameFlags::NoDraw
)
955 ImplDrawFrame( mpOutDev
, aRect
, mpOutDev
->GetSettings().GetStyleSettings(), nStyle
, nFlags
);
958 Color aOldLineColor
= mpOutDev
->GetLineColor();
959 Color aOldFillColor
= mpOutDev
->GetFillColor();
960 ImplDrawFrame( mpOutDev
, aRect
, mpOutDev
->GetSettings().GetStyleSettings(), nStyle
, nFlags
);
961 mpOutDev
->SetLineColor( aOldLineColor
);
962 mpOutDev
->SetFillColor( aOldFillColor
);
968 mpOutDev
->EnableMapMode( bOldMap
);
969 aRect
= mpOutDev
->PixelToLogic( aRect
);
975 Rectangle
DecorationView::DrawButton( const Rectangle
& rRect
, DrawButtonFlags nStyle
)
977 if ( rRect
.IsEmpty() )
982 Rectangle aRect
= rRect
;
983 const bool bOldMap
= mpOutDev
->IsMapModeEnabled();
987 aRect
= mpOutDev
->LogicToPixel( aRect
);
988 mpOutDev
->EnableMapMode( false );
991 const Color aOldLineColor
= mpOutDev
->GetLineColor();
992 const Color aOldFillColor
= mpOutDev
->GetFillColor();
993 ImplDrawButton( mpOutDev
, aRect
, nStyle
);
994 mpOutDev
->SetLineColor( aOldLineColor
);
995 mpOutDev
->SetFillColor( aOldFillColor
);
997 // keep border free, although it is used at default representation
1003 if ( nStyle
& DrawButtonFlags::NoLightBorder
)
1008 else if ( nStyle
& DrawButtonFlags::NoLeftLightBorder
)
1013 if ( nStyle
& DrawButtonFlags::Pressed
)
1015 if ( (aRect
.GetHeight() > 10) && (aRect
.GetWidth() > 10) )
1020 aRect
.Bottom() -= 1;
1027 aRect
.Bottom() -= 2;
1030 else if ( nStyle
& DrawButtonFlags::Checked
)
1035 aRect
.Bottom() -= 2;
1042 aRect
.Bottom() -= 3;
1047 mpOutDev
->EnableMapMode( bOldMap
);
1048 aRect
= mpOutDev
->PixelToLogic( aRect
);
1054 void DecorationView::DrawSeparator( const Point
& rStart
, const Point
& rStop
, bool bVertical
)
1056 Point
aStart( rStart
), aStop( rStop
);
1057 const StyleSettings
& rStyleSettings
= mpOutDev
->GetSettings().GetStyleSettings();
1058 vcl::Window
*const pWin
= (mpOutDev
->GetOutDevType()==OUTDEV_WINDOW
) ? static_cast<vcl::Window
*>(mpOutDev
.get()) : nullptr;
1061 ControlPart nPart
= ( bVertical
? ControlPart::SeparatorVert
: ControlPart::SeparatorHorz
);
1062 bool nativeSupported
= pWin
->IsNativeControlSupported( ControlType::Fixedline
, nPart
);
1063 ImplControlValue aValue
;
1064 ControlState nState
= ControlState::NONE
;
1065 Rectangle
aRect(rStart
,rStop
);
1066 if(nativeSupported
&& pWin
->DrawNativeControl(ControlType::Fixedline
,nPart
,aRect
,nState
,aValue
,OUString()))
1070 mpOutDev
->Push( PushFlags::LINECOLOR
);
1071 if ( rStyleSettings
.GetOptions() & StyleSettingsOptions::Mono
)
1072 mpOutDev
->SetLineColor( Color( COL_BLACK
) );
1074 mpOutDev
->SetLineColor( rStyleSettings
.GetShadowColor() );
1076 mpOutDev
->DrawLine( aStart
, aStop
);
1077 if ( !(rStyleSettings
.GetOptions() & StyleSettingsOptions::Mono
) )
1079 mpOutDev
->SetLineColor( rStyleSettings
.GetLightColor() );
1090 mpOutDev
->DrawLine( aStart
, aStop
);
1095 void DecorationView::DrawHandle(const Rectangle
& rRect
)
1097 const StyleSettings
& rStyleSettings
= mpOutDev
->GetSettings().GetStyleSettings();
1099 Size aOutputSize
= rRect
.GetSize();
1101 mpOutDev
->SetLineColor(rStyleSettings
.GetDarkShadowColor());
1102 mpOutDev
->SetFillColor(rStyleSettings
.GetDarkShadowColor());
1104 const sal_Int32 nNumberOfPoints
= 3;
1106 long nHalfWidth
= aOutputSize
.Width() / 2.0f
;
1108 float fDistance
= aOutputSize
.Height();
1109 fDistance
/= (nNumberOfPoints
+ 1);
1111 long nRadius
= aOutputSize
.Width();
1112 nRadius
/= (nNumberOfPoints
+ 2);
1114 for (long i
= 1; i
<= nNumberOfPoints
; i
++)
1116 Rectangle aLocation
;
1117 aLocation
= Rectangle(nHalfWidth
- nRadius
,
1118 round(fDistance
* i
) - nRadius
,
1119 nHalfWidth
+ nRadius
,
1120 round(fDistance
* i
) + nRadius
);
1121 mpOutDev
->DrawEllipse(aLocation
);
1125 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */