build fix: no comphelper/profilezone.hxx in this branch
[LibreOffice.git] / vcl / source / window / decoview.cxx
blobe40d3b56cbae1f61541ab30e70a8e5d23009eea8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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)
31 using namespace std;
33 namespace {
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
44 --nSide;
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 );
53 return nSide;
56 void ImplDrawSymbol( OutputDevice* pDev, Rectangle nRect, const SymbolType eType )
58 const long nSide = AdjustRectToSquare( nRect );
60 if ( !nSide ) return;
61 if ( nSide==1 )
63 pDev->DrawPixel( Point( nRect.Left(), nRect.Top() ) );
64 return;
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();
73 switch ( eType )
75 case SymbolType::ARROW_UP:
76 pDev->DrawPixel( Point( aCenter.X(), nRect.Top() ) );
77 for ( long i=1; i <= n2; ++i )
79 ++nRect.Top();
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() ) );
85 break;
87 case SymbolType::ARROW_DOWN:
88 pDev->DrawPixel( Point( aCenter.X(), nRect.Bottom() ) );
89 for ( long i=1; i <= n2; ++i )
91 --nRect.Bottom();
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 ) );
97 break;
99 case SymbolType::ARROW_LEFT:
100 pDev->DrawPixel( Point( nRect.Left(), aCenter.Y() ) );
101 for ( long i=1; i <= n2; ++i )
103 ++nRect.Left();
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 ) );
109 break;
111 case SymbolType::ARROW_RIGHT:
112 pDev->DrawPixel( Point( nRect.Right(), aCenter.Y() ) );
113 for ( long i=1; i <= n2; ++i )
115 --nRect.Right();
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 ) );
121 break;
123 case SymbolType::SPIN_UP:
124 nRect.Top() += n4;
125 pDev->DrawPixel( Point( aCenter.X(), nRect.Top() ) );
126 for ( long i=1; i <= n2; ++i )
128 ++nRect.Top();
129 pDev->DrawLine( Point( aCenter.X()-i, nRect.Top() ),
130 Point( aCenter.X()+i, nRect.Top() ) );
132 break;
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 )
139 --nRect.Bottom();
140 pDev->DrawLine( Point( aCenter.X()-i, nRect.Bottom() ),
141 Point( aCenter.X()+i, nRect.Bottom() ) );
143 break;
145 case SymbolType::SPIN_LEFT:
146 case SymbolType::FIRST:
147 case SymbolType::PREV:
148 case SymbolType::REVERSEPLAY:
149 nRect.Left() += n4;
150 if ( eType==SymbolType::FIRST )
152 pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
153 Point( nRect.Left(), nRect.Bottom() ) );
154 ++nRect.Left();
156 pDev->DrawPixel( Point( nRect.Left(), aCenter.Y() ) );
157 for ( long i=1; i <= n2; ++i )
159 ++nRect.Left();
160 pDev->DrawLine( Point( nRect.Left(), aCenter.Y()-i ),
161 Point( nRect.Left(), aCenter.Y()+i ) );
163 break;
165 case SymbolType::SPIN_RIGHT:
166 case SymbolType::LAST:
167 case SymbolType::NEXT:
168 case SymbolType::PLAY:
169 nRect.Right() -= n4;
170 if ( eType==SymbolType::LAST )
172 pDev->DrawLine( Point( nRect.Right(), nRect.Top() ),
173 Point( nRect.Right(), nRect.Bottom() ) );
174 --nRect.Right();
176 pDev->DrawPixel( Point( nRect.Right(), aCenter.Y() ) );
177 for ( long i=1; i <= n2; ++i )
179 --nRect.Right();
180 pDev->DrawLine( Point( nRect.Right(), aCenter.Y()-i ),
181 Point( nRect.Right(), aCenter.Y()+i ) );
183 break;
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 )
190 ++nRect.Top();
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 ) );
196 break;
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 )
203 --nRect.Bottom();
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 ) );
209 break;
211 case SymbolType::RADIOCHECKMARK:
212 case SymbolType::RECORD:
214 // Midpoint circle algorithm
215 long x = 0;
216 long y = n2;
217 long p = 1 - n2;
218 // Draw central line
219 pDev->DrawLine( Point( aCenter.X(), aCenter.Y()-y ),
220 Point( aCenter.X(), aCenter.Y()+y ) );
221 while ( x<y )
223 if ( p>=0 )
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 ) );
230 --y;
231 p -= 2*y;
233 ++x;
234 p += 2*x+1;
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 ) );
242 break;
244 case SymbolType::STOP:
245 pDev->DrawRect( nRect );
246 break;
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() ) );
253 break;
255 case SymbolType::WINDSTART:
256 pDev->DrawLine( Point( nRect.Left(), aCenter.Y()-n2+1 ),
257 Point( nRect.Left(), aCenter.Y()+n2-1 ) );
258 ++nRect.Left();
259 SAL_FALLTHROUGH;
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 )
265 ++nRect.Left();
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 ) );
271 break;
273 case SymbolType::WINDEND:
274 pDev->DrawLine( Point( nRect.Right(), aCenter.Y()-n2+1 ),
275 Point( nRect.Right(), aCenter.Y()+n2-1 ) );
276 --nRect.Right();
277 SAL_FALLTHROUGH;
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 )
283 --nRect.Right();
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 ) );
289 break;
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() ) );
307 break;
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() ) );
316 SAL_FALLTHROUGH;
317 case SymbolType::ROLLUP:
318 pDev->DrawRect( Rectangle( nRect.Left(), nRect.Top(),
319 nRect.Right(), nRect.Top()+n8 ) );
320 break;
322 case SymbolType::CHECKMARK:
324 long n3 = nSide/3;
325 nRect.Top() -= n3/2;
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 ) );
336 ++nRect.Top();
337 ++nRect.Bottom();
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 ) );
343 else
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 ) );
349 ++nRect.Top();
350 ++nRect.Bottom();
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 ) );
357 break;
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 )
364 ++nRect.Top();
365 --nRect.Bottom();
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() ) );
371 break;
373 case SymbolType::FLOAT:
374 nRect.Right() -= n4;
375 nRect.Top() += n4+1;
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() ) );
384 nRect.Right() += n4;
385 nRect.Top() -= n4+1;
386 nRect.Left() += n4;
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() ) );
396 break;
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() ) );
407 break;
409 case SymbolType::HIDE:
410 pDev->DrawRect( Rectangle( nRect.Left()+n8, nRect.Bottom()-n8,
411 nRect.Right()-n8, nRect.Bottom() ) );
412 break;
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 ) );
419 break;
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;
431 if ( !nLineWidth )
432 nLineWidth = 1;
433 if ( !nLineHeight )
434 nLineHeight = 1;
436 if ( pColor )
438 if ( (nLineWidth == 1) && (nLineHeight == 1) )
440 pDev->SetLineColor( *pColor );
441 if( bRound )
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) );
448 else
450 pDev->SetFillColor();
451 pDev->DrawRect( rRect );
454 else
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
486 ++rRect.Left();
487 ++rRect.Top();
488 --rRect.Right();
489 --rRect.Bottom();
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) )
525 // shrink fill rect
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() ) );
534 else
536 // shrink fill rect
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 ) );
551 else
552 pDev->SetFillColor( Color( COL_WHITE ) );
553 pDev->DrawRect( aFillRect );
556 else
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() ) );
569 ++aFillRect.Left();
572 Color aColor1;
573 Color aColor2;
574 if ( nStyle & (DrawButtonFlags::Pressed | DrawButtonFlags::Checked) )
576 aColor1 = rStyleSettings.GetDarkShadowColor();
577 aColor2 = rStyleSettings.GetLightColor();
579 else
581 if ( nStyle & DrawButtonFlags::NoLightBorder )
582 aColor1 = rStyleSettings.GetLightBorderColor();
583 else
584 aColor1 = rStyleSettings.GetLightColor();
585 if ( (nStyle & BUTTON_DRAW_FLATTEST) == DrawButtonFlags::Flat )
586 aColor2 = rStyleSettings.GetShadowColor();
587 else
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();
600 else
602 if ( nStyle & DrawButtonFlags::NoLightBorder )
603 aColor1 = rStyleSettings.GetLightColor();
604 else
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() );
616 else
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) ||
650 bFlatBorders )
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
669 if( bNoDraw ||
670 pWin->DrawNativeControl( ControlType::Frame, ControlPart::Border, aContent, ControlState::ENABLED,
671 aControlValue, OUString()) )
673 rRect = aContent;
674 return;
679 if ( nFlags & DrawFrameFlags::Mono )
681 // no round corners for window frame borders
682 const bool bRound = bFlatBorders && !(nFlags & DrawFrameFlags::WindowBorder);
684 if ( bNoDraw )
686 ImplDrawDPILineRect( pDev, rRect, nullptr, bRound );
688 else
690 Color aColor = bRound ? rStyleSettings.GetShadowColor()
691 : pDev->GetSettings().GetStyleSettings().GetMonoColor();
692 // when the MonoColor wasn't set, check face color
693 if (
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 );
706 else
708 if ( bNoDraw )
710 switch ( nStyle )
712 case DrawFrameStyle::In:
713 case DrawFrameStyle::Out:
714 ++rRect.Left();
715 ++rRect.Top();
716 --rRect.Right();
717 --rRect.Bottom();
718 break;
720 case DrawFrameStyle::Group:
721 case DrawFrameStyle::DoubleIn:
722 case DrawFrameStyle::DoubleOut:
723 rRect.Left() += 2;
724 rRect.Top() += 2;
725 rRect.Right() -= 2;
726 rRect.Bottom() -= 2;
727 break;
729 case DrawFrameStyle::NWF:
730 // enough space for the native rendering
731 rRect.Left() += 4;
732 rRect.Top() += 4;
733 rRect.Right() -= 4;
734 rRect.Bottom() -= 4;
735 break;
736 default: break;
739 else
741 switch ( nStyle )
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
753 rRect.Left() += 2;
754 rRect.Top() += 2;
755 rRect.Right() -= 2;
756 rRect.Bottom() -= 2;
757 break;
759 case DrawFrameStyle::In:
760 ImplDraw2ColorFrame( pDev, rRect,
761 rStyleSettings.GetShadowColor(),
762 rStyleSettings.GetLightColor() );
763 break;
765 case DrawFrameStyle::Out:
766 ImplDraw2ColorFrame( pDev, rRect,
767 rStyleSettings.GetLightColor(),
768 rStyleSettings.GetShadowColor() );
769 break;
771 case DrawFrameStyle::DoubleIn:
772 if( bFlatBorders )
774 // no 3d effect
775 ImplDraw2ColorFrame( pDev, rRect,
776 rStyleSettings.GetShadowColor(),
777 rStyleSettings.GetShadowColor() );
778 ImplDraw2ColorFrame( pDev, rRect,
779 rStyleSettings.GetFaceColor(),
780 rStyleSettings.GetFaceColor() );
782 else
784 ImplDraw2ColorFrame( pDev, rRect,
785 rStyleSettings.GetShadowColor(),
786 rStyleSettings.GetLightColor() );
787 ImplDraw2ColorFrame( pDev, rRect,
788 rStyleSettings.GetDarkShadowColor(),
789 rStyleSettings.GetLightBorderColor() );
791 break;
793 case DrawFrameStyle::DoubleOut:
794 if( bMenuStyle )
796 ImplDraw2ColorFrame( pDev, rRect,
797 rStyleSettings.GetMenuBorderColor(),
798 rStyleSettings.GetDarkShadowColor() );
799 if ( !rStyleSettings.GetUseFlatMenus() )
801 ImplDraw2ColorFrame( pDev, rRect,
802 rStyleSettings.GetLightColor(),
803 rStyleSettings.GetShadowColor() );
806 else
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() );
817 break;
819 case DrawFrameStyle::NWF:
820 // no rendering, just enough space for the native rendering
821 rRect.Left() += 4;
822 rRect.Top() += 4;
823 rRect.Right() -= 4;
824 rRect.Bottom() -= 4;
825 break;
826 default: break;
832 } // end anonymous namespace
834 DecorationView::DecorationView(OutputDevice* pOutDev) :
835 mpOutDev(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 );
858 else
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 );
907 else
909 Wallpaper aBackground = mpOutDev->GetBackground();
910 if ( aBackground.IsBitmap() || aBackground.IsGradient() )
912 aLightColor = rStyleSettings.GetFaceColor();
913 aShadowColor = Color( COL_BLACK );
915 else
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();
946 if ( bOldMap )
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 );
956 else
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 );
966 if ( bOldMap )
968 mpOutDev->EnableMapMode( bOldMap );
969 aRect = mpOutDev->PixelToLogic( aRect );
972 return aRect;
975 Rectangle DecorationView::DrawButton( const Rectangle& rRect, DrawButtonFlags nStyle )
977 if ( rRect.IsEmpty() )
979 return rRect;
982 Rectangle aRect = rRect;
983 const bool bOldMap = mpOutDev->IsMapModeEnabled();
985 if ( bOldMap )
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
998 ++aRect.Left();
999 ++aRect.Top();
1000 --aRect.Right();
1001 --aRect.Bottom();
1003 if ( nStyle & DrawButtonFlags::NoLightBorder )
1005 ++aRect.Left();
1006 ++aRect.Top();
1008 else if ( nStyle & DrawButtonFlags::NoLeftLightBorder )
1010 ++aRect.Left();
1013 if ( nStyle & DrawButtonFlags::Pressed )
1015 if ( (aRect.GetHeight() > 10) && (aRect.GetWidth() > 10) )
1017 aRect.Left() += 4;
1018 aRect.Top() += 4;
1019 aRect.Right() -= 1;
1020 aRect.Bottom() -= 1;
1022 else
1024 aRect.Left() += 3;
1025 aRect.Top() += 3;
1026 aRect.Right() -= 2;
1027 aRect.Bottom() -= 2;
1030 else if ( nStyle & DrawButtonFlags::Checked )
1032 aRect.Left() += 3;
1033 aRect.Top() += 3;
1034 aRect.Right() -= 2;
1035 aRect.Bottom() -= 2;
1037 else
1039 aRect.Left() += 2;
1040 aRect.Top() += 2;
1041 aRect.Right() -= 3;
1042 aRect.Bottom() -= 3;
1045 if ( bOldMap )
1047 mpOutDev->EnableMapMode( bOldMap );
1048 aRect = mpOutDev->PixelToLogic( aRect );
1051 return 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;
1059 if(pWin)
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()))
1067 return;
1070 mpOutDev->Push( PushFlags::LINECOLOR );
1071 if ( rStyleSettings.GetOptions() & StyleSettingsOptions::Mono )
1072 mpOutDev->SetLineColor( Color( COL_BLACK ) );
1073 else
1074 mpOutDev->SetLineColor( rStyleSettings.GetShadowColor() );
1076 mpOutDev->DrawLine( aStart, aStop );
1077 if ( !(rStyleSettings.GetOptions() & StyleSettingsOptions::Mono) )
1079 mpOutDev->SetLineColor( rStyleSettings.GetLightColor() );
1080 if( bVertical )
1082 aStart.X()++;
1083 aStop.X()++;
1085 else
1087 aStart.Y()++;
1088 aStop.Y()++;
1090 mpOutDev->DrawLine( aStart, aStop );
1092 mpOutDev->Pop();
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: */