bump product version to 4.1.6.2
[LibreOffice.git] / vcl / source / window / decoview.cxx
blob1c5c42dde8bdaf3112857f38372f385bd1764c28
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 // =======================================================================
28 #define BUTTON_DRAW_FLATTEST (BUTTON_DRAW_FLAT | \
29 BUTTON_DRAW_PRESSED | \
30 BUTTON_DRAW_CHECKED | \
31 BUTTON_DRAW_HIGHLIGHT)
33 // =======================================================================
35 namespace {
37 long AdjustRectToSquare( Rectangle &rRect )
39 const long nWidth = rRect.GetWidth();
40 const long nHeight = rRect.GetHeight();
41 long nSide = std::min( nWidth, nHeight );
43 if ( nSide && !(nSide & 1) )
45 // we prefer an odd size
46 --nSide;
49 // Make the rectangle a square
50 rRect.SetSize( Size( nSide, nSide ) );
52 // and place it at the center of the original rectangle
53 rRect.Move( (nWidth-nSide)/2, (nHeight-nSide)/2 );
55 return nSide;
58 void ImplDrawSymbol( OutputDevice* pDev, Rectangle nRect, const SymbolType eType )
60 const long nSide = AdjustRectToSquare( nRect );
62 if ( !nSide ) return;
63 if ( nSide==1 )
65 pDev->DrawPixel( Point( nRect.Left(), nRect.Top() ) );
66 return;
69 // Precalculate some values
70 const long n2 = nSide/2;
71 const long n4 = (n2+1)/2;
72 const long n8 = (n4+1)/2;
73 const Point aCenter = nRect.Center();
75 switch ( eType )
77 case SYMBOL_ARROW_UP:
78 pDev->DrawPixel( Point( aCenter.X(), nRect.Top() ) );
79 for ( long i=1; i <= n2; ++i )
81 ++nRect.Top();
82 pDev->DrawLine( Point( aCenter.X()-i, nRect.Top() ),
83 Point( aCenter.X()+i, nRect.Top() ) );
85 pDev->DrawRect( Rectangle( aCenter.X()-n8, nRect.Top()+1,
86 aCenter.X()+n8, nRect.Bottom() ) );
87 break;
89 case SYMBOL_ARROW_DOWN:
90 pDev->DrawPixel( Point( aCenter.X(), nRect.Bottom() ) );
91 for ( long i=1; i <= n2; ++i )
93 --nRect.Bottom();
94 pDev->DrawLine( Point( aCenter.X()-i, nRect.Bottom() ),
95 Point( aCenter.X()+i, nRect.Bottom() ) );
97 pDev->DrawRect( Rectangle( aCenter.X()-n8, nRect.Top(),
98 aCenter.X()+n8, nRect.Bottom()-1 ) );
99 break;
101 case SYMBOL_ARROW_LEFT:
102 pDev->DrawPixel( Point( nRect.Left(), aCenter.Y() ) );
103 for ( long i=1; i <= n2; ++i )
105 ++nRect.Left();
106 pDev->DrawLine( Point( nRect.Left(), aCenter.Y()-i ),
107 Point( nRect.Left(), aCenter.Y()+i ) );
109 pDev->DrawRect( Rectangle( nRect.Left()+1, aCenter.Y()-n8,
110 nRect.Right(), aCenter.Y()+n8 ) );
111 break;
113 case SYMBOL_ARROW_RIGHT:
114 pDev->DrawPixel( Point( nRect.Right(), aCenter.Y() ) );
115 for ( long i=1; i <= n2; ++i )
117 --nRect.Right();
118 pDev->DrawLine( Point( nRect.Right(), aCenter.Y()-i ),
119 Point( nRect.Right(), aCenter.Y()+i ) );
121 pDev->DrawRect( Rectangle( nRect.Left(), aCenter.Y()-n8,
122 nRect.Right()-1, aCenter.Y()+n8 ) );
123 break;
126 case SYMBOL_SPIN_UP:
127 nRect.Top() += n4;
128 pDev->DrawPixel( Point( aCenter.X(), nRect.Top() ) );
129 for ( long i=1; i <= n2; ++i )
131 ++nRect.Top();
132 pDev->DrawLine( Point( aCenter.X()-i, nRect.Top() ),
133 Point( aCenter.X()+i, nRect.Top() ) );
135 break;
137 case SYMBOL_SPIN_DOWN:
138 nRect.Bottom() -= n4;
139 pDev->DrawPixel( Point( aCenter.X(), nRect.Bottom() ) );
140 for ( long i=1; i <= n2; ++i )
142 --nRect.Bottom();
143 pDev->DrawLine( Point( aCenter.X()-i, nRect.Bottom() ),
144 Point( aCenter.X()+i, nRect.Bottom() ) );
146 break;
148 case SYMBOL_SPIN_LEFT:
149 case SYMBOL_FIRST:
150 case SYMBOL_PREV:
151 case SYMBOL_REVERSEPLAY:
152 nRect.Left() += n4;
153 if ( eType==SYMBOL_FIRST )
155 pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
156 Point( nRect.Left(), nRect.Bottom() ) );
157 ++nRect.Left();
159 pDev->DrawPixel( Point( nRect.Left(), aCenter.Y() ) );
160 for ( long i=1; i <= n2; ++i )
162 ++nRect.Left();
163 pDev->DrawLine( Point( nRect.Left(), aCenter.Y()-i ),
164 Point( nRect.Left(), aCenter.Y()+i ) );
166 break;
168 case SYMBOL_SPIN_RIGHT:
169 case SYMBOL_LAST:
170 case SYMBOL_NEXT:
171 case SYMBOL_PLAY:
172 nRect.Right() -= n4;
173 if ( eType==SYMBOL_LAST )
175 pDev->DrawLine( Point( nRect.Right(), nRect.Top() ),
176 Point( nRect.Right(), nRect.Bottom() ) );
177 --nRect.Right();
179 pDev->DrawPixel( Point( nRect.Right(), aCenter.Y() ) );
180 for ( long i=1; i <= n2; ++i )
182 --nRect.Right();
183 pDev->DrawLine( Point( nRect.Right(), aCenter.Y()-i ),
184 Point( nRect.Right(), aCenter.Y()+i ) );
186 break;
188 case SYMBOL_PAGEUP:
189 pDev->DrawPixel( Point( aCenter.X(), nRect.Top() ) );
190 pDev->DrawPixel( Point( aCenter.X(), nRect.Top()+n2 ) );
191 for ( long i=1; i < n2; ++i )
193 ++nRect.Top();
194 pDev->DrawLine( Point( aCenter.X()-i, nRect.Top() ),
195 Point( aCenter.X()+i, nRect.Top() ) );
196 pDev->DrawLine( Point( aCenter.X()-i, nRect.Top()+n2 ),
197 Point( aCenter.X()+i, nRect.Top()+n2 ) );
199 break;
201 case SYMBOL_PAGEDOWN:
202 pDev->DrawPixel( Point( aCenter.X(), nRect.Bottom() ) );
203 pDev->DrawPixel( Point( aCenter.X(), nRect.Bottom()-n2 ) );
204 for ( long i=1; i < n2; ++i )
206 --nRect.Bottom();
207 pDev->DrawLine( Point( aCenter.X()-i, nRect.Bottom() ),
208 Point( aCenter.X()+i, nRect.Bottom() ) );
209 pDev->DrawLine( Point( aCenter.X()-i, nRect.Bottom()-n2 ),
210 Point( aCenter.X()+i, nRect.Bottom()-n2 ) );
212 break;
214 case SYMBOL_RADIOCHECKMARK:
215 case SYMBOL_RECORD:
217 // Midpoint circle algorithm
218 long x = 0;
219 long y = n2;
220 long p = 1 - n2;
221 // Draw central line
222 pDev->DrawLine( Point( aCenter.X(), aCenter.Y()-y ),
223 Point( aCenter.X(), aCenter.Y()+y ) );
224 while ( x<y )
226 if ( p>=0 )
228 // Draw vertical lines close to sides
229 pDev->DrawLine( Point( aCenter.X()+y, aCenter.Y()-x ),
230 Point( aCenter.X()+y, aCenter.Y()+x ) );
231 pDev->DrawLine( Point( aCenter.X()-y, aCenter.Y()-x ),
232 Point( aCenter.X()-y, aCenter.Y()+x ) );
233 --y;
234 p -= 2*y;
236 ++x;
237 p += 2*x+1;
238 // Draw vertical lines close to center
239 pDev->DrawLine( Point( aCenter.X()-x, aCenter.Y()-y ),
240 Point( aCenter.X()-x, aCenter.Y()+y ) );
241 pDev->DrawLine( Point( aCenter.X()+x, aCenter.Y()-y ),
242 Point( aCenter.X()+x, aCenter.Y()+y ) );
245 break;
247 case SYMBOL_STOP:
248 pDev->DrawRect( nRect );
249 break;
251 case SYMBOL_PAUSE:
252 pDev->DrawRect( Rectangle ( nRect.Left(), nRect.Top(),
253 aCenter.X()-n8, nRect.Bottom() ) );
254 pDev->DrawRect( Rectangle ( aCenter.X()+n8, nRect.Top(),
255 nRect.Right(), nRect.Bottom() ) );
256 break;
258 case SYMBOL_WINDSTART:
259 pDev->DrawLine( Point( nRect.Left(), aCenter.Y()-n2+1 ),
260 Point( nRect.Left(), aCenter.Y()+n2-1 ) );
261 ++nRect.Left();
262 // Intentional fall-through
263 case SYMBOL_WINDBACKWARD:
264 pDev->DrawPixel( Point( nRect.Left(), aCenter.Y() ) );
265 pDev->DrawPixel( Point( nRect.Left()+n2, aCenter.Y() ) );
266 for ( long i=1; i < n2; ++i )
268 ++nRect.Left();
269 pDev->DrawLine( Point( nRect.Left(), aCenter.Y()-i ),
270 Point( nRect.Left(), aCenter.Y()+i ) );
271 pDev->DrawLine( Point( nRect.Left()+n2, aCenter.Y()-i ),
272 Point( nRect.Left()+n2, aCenter.Y()+i ) );
274 break;
276 case SYMBOL_WINDEND:
277 pDev->DrawLine( Point( nRect.Right(), aCenter.Y()-n2+1 ),
278 Point( nRect.Right(), aCenter.Y()+n2-1 ) );
279 --nRect.Right();
280 // Intentional fall-through
281 case SYMBOL_WINDFORWARD:
282 pDev->DrawPixel( Point( nRect.Right(), aCenter.Y() ) );
283 pDev->DrawPixel( Point( nRect.Right()-n2, aCenter.Y() ) );
284 for ( long i=1; i < n2; ++i )
286 --nRect.Right();
287 pDev->DrawLine( Point( nRect.Right(), aCenter.Y()-i ),
288 Point( nRect.Right(), aCenter.Y()+i ) );
289 pDev->DrawLine( Point( nRect.Right()-n2, aCenter.Y()-i ),
290 Point( nRect.Right()-n2, aCenter.Y()+i ) );
292 break;
294 case SYMBOL_CLOSE:
295 pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
296 Point( nRect.Right(), nRect.Bottom() ) );
297 pDev->DrawLine( Point( nRect.Left(), nRect.Bottom() ),
298 Point( nRect.Right(), nRect.Top() ) );
299 for ( long i=1; i<n8; ++i )
301 pDev->DrawLine( Point( nRect.Left()+i, nRect.Top() ),
302 Point( nRect.Right(), nRect.Bottom()-i ) );
303 pDev->DrawLine( Point( nRect.Left(), nRect.Top()+i ),
304 Point( nRect.Right()-i, nRect.Bottom() ) );
305 pDev->DrawLine( Point( nRect.Left()+i, nRect.Bottom() ),
306 Point( nRect.Right(), nRect.Top()+i ) );
307 pDev->DrawLine( Point( nRect.Left(), nRect.Bottom()-i ),
308 Point( nRect.Right()-i, nRect.Top() ) );
310 break;
312 case SYMBOL_ROLLDOWN:
313 pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
314 Point( nRect.Left(), nRect.Bottom() ) );
315 pDev->DrawLine( Point( nRect.Right(), nRect.Top() ),
316 Point( nRect.Right(), nRect.Bottom() ) );
317 pDev->DrawLine( Point( nRect.Left(), nRect.Bottom() ),
318 Point( nRect.Right(), nRect.Bottom() ) );
319 // Intentional fall-through
320 case SYMBOL_ROLLUP:
321 pDev->DrawRect( Rectangle( nRect.Left(), nRect.Top(),
322 nRect.Right(), nRect.Top()+n8 ) );
323 break;
325 case SYMBOL_CHECKMARK:
327 long n3 = nSide/3;
328 nRect.Top() -= n3/2;
329 nRect.Bottom() -= n3/2;
330 // #106953# never mirror checkmarks
331 if ( pDev->ImplHasMirroredGraphics() && pDev->IsRTLEnabled() )
333 // Draw a mirrored checkmark so that it looks "normal" in a
334 // mirrored graphics device (double mirroring!)
335 pDev->DrawLine( Point( nRect.Right(), nRect.Bottom()-n3 ),
336 Point( nRect.Right()-n3, nRect.Bottom() ) );
337 pDev->DrawLine( Point( nRect.Right()-n3, nRect.Bottom() ),
338 Point( nRect.Left(), nRect.Top()+n3 ) );
339 ++nRect.Top();
340 ++nRect.Bottom();
341 pDev->DrawLine( Point( nRect.Right(), nRect.Bottom()-n3 ),
342 Point( nRect.Right()-n3, nRect.Bottom() ) );
343 pDev->DrawLine( Point( nRect.Right()-n3, nRect.Bottom() ),
344 Point( nRect.Left(), nRect.Top()+n3 ) );
346 else
348 pDev->DrawLine( Point( nRect.Left(), nRect.Bottom()-n3 ),
349 Point( nRect.Left()+n3, nRect.Bottom() ) );
350 pDev->DrawLine( Point( nRect.Left()+n3, nRect.Bottom() ),
351 Point( nRect.Right(), nRect.Top()+n3 ) );
352 ++nRect.Top();
353 ++nRect.Bottom();
354 pDev->DrawLine( Point( nRect.Left(), nRect.Bottom()-n3 ),
355 Point( nRect.Left()+n3, nRect.Bottom() ) );
356 pDev->DrawLine( Point( nRect.Left()+n3, nRect.Bottom() ),
357 Point( nRect.Right(), nRect.Top()+n3 ) );
360 break;
362 case SYMBOL_SPIN_UPDOWN:
363 pDev->DrawPixel( Point( aCenter.X(), nRect.Top() ) );
364 pDev->DrawPixel( Point( aCenter.X(), nRect.Bottom() ) );
365 for ( long i=1; i < n2; ++i )
367 ++nRect.Top();
368 --nRect.Bottom();
369 pDev->DrawLine( Point( aCenter.X()-i, nRect.Top() ),
370 Point( aCenter.X()+i, nRect.Top() ) );
371 pDev->DrawLine( Point( aCenter.X()-i, nRect.Bottom() ),
372 Point( aCenter.X()+i, nRect.Bottom() ) );
374 break;
376 case SYMBOL_FLOAT:
377 nRect.Right() -= n4;
378 nRect.Top() += n4+1;
379 pDev->DrawRect( Rectangle( nRect.Left(), nRect.Top(),
380 nRect.Right(), nRect.Top()+n8 ) );
381 pDev->DrawLine( Point( nRect.Left(), nRect.Top()+n8 ),
382 Point( nRect.Left(), nRect.Bottom() ) );
383 pDev->DrawLine( Point( nRect.Left(), nRect.Bottom() ),
384 Point( nRect.Right(), nRect.Bottom() ) );
385 pDev->DrawLine( Point( nRect.Right(), nRect.Top()+n8 ),
386 Point( nRect.Right(), nRect.Bottom() ) );
387 nRect.Right() += n4;
388 nRect.Top() -= n4+1;
389 nRect.Left() += n4;
390 nRect.Bottom() -= n4+1;
391 pDev->DrawRect( Rectangle( nRect.Left(), nRect.Top(),
392 nRect.Right(), nRect.Top()+n8 ) );
393 pDev->DrawLine( Point( nRect.Left(), nRect.Top()+n8 ),
394 Point( nRect.Left(), nRect.Bottom() ) );
395 pDev->DrawLine( Point( nRect.Left(), nRect.Bottom() ),
396 Point( nRect.Right(), nRect.Bottom() ) );
397 pDev->DrawLine( Point( nRect.Right(), nRect.Top()+n8 ),
398 Point( nRect.Right(), nRect.Bottom() ) );
399 break;
401 case SYMBOL_DOCK:
402 pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
403 Point( nRect.Right(), nRect.Top() ) );
404 pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
405 Point( nRect.Left(), nRect.Bottom() ) );
406 pDev->DrawLine( Point( nRect.Left(), nRect.Bottom() ),
407 Point( nRect.Right(), nRect.Bottom() ) );
408 pDev->DrawLine( Point( nRect.Right(), nRect.Top() ),
409 Point( nRect.Right(), nRect.Bottom() ) );
410 break;
412 case SYMBOL_HIDE:
413 pDev->DrawRect( Rectangle( nRect.Left()+n8, nRect.Bottom()-n8,
414 nRect.Right()-n8, nRect.Bottom() ) );
415 break;
417 case SYMBOL_PLUS:
418 pDev->DrawRect( Rectangle( nRect.Left(), aCenter.Y()-n8,
419 nRect.Right(), aCenter.Y()+n8 ) );
420 pDev->DrawRect( Rectangle( aCenter.X()-n8, nRect.Top(),
421 aCenter.X()+n8, nRect.Bottom() ) );
422 break;
427 void ImplDrawDPILineRect( OutputDevice *const pDev, Rectangle& rRect,
428 const Color *const pColor, const bool bRound = false )
430 long nLineWidth = pDev->ImplGetDPIX()/300;
431 long nLineHeight = pDev->ImplGetDPIY()/300;
432 if ( !nLineWidth )
433 nLineWidth = 1;
434 if ( !nLineHeight )
435 nLineHeight = 1;
437 if ( pColor )
439 if ( (nLineWidth == 1) && (nLineHeight == 1) )
441 pDev->SetLineColor( *pColor );
442 if( bRound )
444 pDev->DrawLine( Point( rRect.Left()+1, rRect.Top()), Point( rRect.Right()-1, rRect.Top()) );
445 pDev->DrawLine( Point( rRect.Left()+1, rRect.Bottom()), Point( rRect.Right()-1, rRect.Bottom()) );
446 pDev->DrawLine( Point( rRect.Left(), rRect.Top()+1), Point( rRect.Left(), rRect.Bottom()-1) );
447 pDev->DrawLine( Point( rRect.Right(), rRect.Top()+1), Point( rRect.Right(), rRect.Bottom()-1) );
449 else
451 pDev->SetFillColor();
452 pDev->DrawRect( rRect );
455 else
457 const long nWidth = rRect.GetWidth();
458 const long nHeight = rRect.GetHeight();
459 pDev->SetLineColor();
460 pDev->SetFillColor( *pColor );
461 pDev->DrawRect( Rectangle( rRect.TopLeft(), Size( nWidth, nLineHeight ) ) );
462 pDev->DrawRect( Rectangle( rRect.TopLeft(), Size( nLineWidth, nHeight ) ) );
463 pDev->DrawRect( Rectangle( Point( rRect.Left(), rRect.Bottom()-nLineHeight ),
464 Size( nWidth, nLineHeight ) ) );
465 pDev->DrawRect( Rectangle( Point( rRect.Right()-nLineWidth, rRect.Top() ),
466 Size( nLineWidth, nHeight ) ) );
470 rRect.Left() += nLineWidth;
471 rRect.Top() += nLineHeight;
472 rRect.Right() -= nLineWidth;
473 rRect.Bottom() -= nLineHeight;
477 void ImplDraw2ColorFrame( OutputDevice *const pDev, Rectangle& rRect,
478 const Color& rLeftTopColor, const Color& rRightBottomColor )
480 pDev->SetLineColor( rLeftTopColor );
481 pDev->DrawLine( rRect.TopLeft(), rRect.BottomLeft() );
482 pDev->DrawLine( rRect.TopLeft(), rRect.TopRight() );
483 pDev->SetLineColor( rRightBottomColor );
484 pDev->DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
485 pDev->DrawLine( rRect.TopRight(), rRect.BottomRight() );
487 // reduce drawing area
488 ++rRect.Left();
489 ++rRect.Top();
490 --rRect.Right();
491 --rRect.Bottom();
495 void ImplDrawButton( OutputDevice *const pDev, Rectangle aFillRect,
496 const sal_uInt16 nStyle )
498 const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
500 if ( (nStyle & BUTTON_DRAW_MONO) ||
501 (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
503 const Color aBlackColor( COL_BLACK );
505 if ( nStyle & BUTTON_DRAW_DEFAULT )
507 // default selection shows a wider border
508 ImplDrawDPILineRect( pDev, aFillRect, &aBlackColor );
511 ImplDrawDPILineRect( pDev, aFillRect, &aBlackColor );
513 Size aBrdSize( 1, 1 );
514 if ( pDev->GetOutDevType() == OUTDEV_PRINTER )
516 aBrdSize = pDev->LogicToPixel( Size( 20, 20 ), MapMode(MAP_100TH_MM) );
517 if ( !aBrdSize.Width() )
518 aBrdSize.Width() = 1;
519 if ( !aBrdSize.Height() )
520 aBrdSize.Height() = 1;
523 pDev->SetLineColor();
524 pDev->SetFillColor( aBlackColor );
525 const Rectangle aOrigFillRect(aFillRect);
526 if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
528 // shrink fill rect
529 aFillRect.Left() += aBrdSize.Width();
530 aFillRect.Top() += aBrdSize.Height();
531 // draw top and left borders (aOrigFillRect-aFillRect)
532 pDev->DrawRect( Rectangle( aOrigFillRect.Left(), aOrigFillRect.Top(),
533 aOrigFillRect.Right(), aFillRect.Top()-1 ) );
534 pDev->DrawRect( Rectangle( aOrigFillRect.Left(), aOrigFillRect.Top(),
535 aFillRect.Left()-1, aOrigFillRect.Bottom() ) );
537 else
539 // shrink fill rect
540 aFillRect.Right() -= aBrdSize.Width();
541 aFillRect.Bottom() -= aBrdSize.Height();
542 // draw bottom and right borders (aOrigFillRect-aFillRect)
543 pDev->DrawRect( Rectangle( aOrigFillRect.Left(), aFillRect.Bottom()+1,
544 aOrigFillRect.Right(), aOrigFillRect.Bottom() ) );
545 pDev->DrawRect( Rectangle( aFillRect.Right()+1, aOrigFillRect.Top(),
546 aOrigFillRect.Right(), aOrigFillRect.Bottom() ) );
549 if ( !(nStyle & BUTTON_DRAW_NOFILL) )
551 // Hack: Auf Druckern wollen wir im MonoChrom-Modus trotzdem
552 // erstmal graue Buttons haben
553 if ( pDev->GetOutDevType() == OUTDEV_PRINTER )
554 pDev->SetFillColor( Color( COL_LIGHTGRAY ) );
555 else
556 pDev->SetFillColor( Color( COL_WHITE ) );
557 pDev->DrawRect( aFillRect );
560 else
562 if ( nStyle & BUTTON_DRAW_DEFAULT )
564 const Color aDefBtnColor = rStyleSettings.GetDarkShadowColor();
565 ImplDrawDPILineRect( pDev, aFillRect, &aDefBtnColor );
568 if ( nStyle & BUTTON_DRAW_NOLEFTLIGHTBORDER )
570 pDev->SetLineColor( rStyleSettings.GetLightBorderColor() );
571 pDev->DrawLine( Point( aFillRect.Left(), aFillRect.Top() ),
572 Point( aFillRect.Left(), aFillRect.Bottom() ) );
573 ++aFillRect.Left();
576 Color aColor1;
577 Color aColor2;
578 if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
580 aColor1 = rStyleSettings.GetDarkShadowColor();
581 aColor2 = rStyleSettings.GetLightColor();
583 else
585 if ( nStyle & BUTTON_DRAW_NOLIGHTBORDER )
586 aColor1 = rStyleSettings.GetLightBorderColor();
587 else
588 aColor1 = rStyleSettings.GetLightColor();
589 if ( (nStyle & BUTTON_DRAW_FLATTEST) == BUTTON_DRAW_FLAT )
590 aColor2 = rStyleSettings.GetShadowColor();
591 else
592 aColor2 = rStyleSettings.GetDarkShadowColor();
595 ImplDraw2ColorFrame( pDev, aFillRect, aColor1, aColor2 );
597 if ( !((nStyle & BUTTON_DRAW_FLATTEST) == BUTTON_DRAW_FLAT) )
599 if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
601 aColor1 = rStyleSettings.GetShadowColor();
602 aColor2 = rStyleSettings.GetLightBorderColor();
604 else
606 if ( nStyle & BUTTON_DRAW_NOLIGHTBORDER )
607 aColor1 = rStyleSettings.GetLightColor();
608 else
609 aColor1 = rStyleSettings.GetLightBorderColor();
610 aColor2 = rStyleSettings.GetShadowColor();
612 ImplDraw2ColorFrame( pDev, aFillRect, aColor1, aColor2 );
615 if ( !(nStyle & BUTTON_DRAW_NOFILL) )
617 pDev->SetLineColor();
618 if ( nStyle & (BUTTON_DRAW_CHECKED | BUTTON_DRAW_DONTKNOW) )
619 pDev->SetFillColor( rStyleSettings.GetCheckedColor() );
620 else
621 pDev->SetFillColor( rStyleSettings.GetFaceColor() );
622 pDev->DrawRect( aFillRect );
627 void ImplDrawFrame( OutputDevice *const pDev, Rectangle& rRect,
628 const StyleSettings& rStyleSettings, sal_uInt16 nStyle )
630 Window *const pWin = (pDev->GetOutDevType()==OUTDEV_WINDOW) ? (Window*) pDev : NULL;
632 const bool bMenuStyle = nStyle & FRAME_DRAW_MENU;
634 // UseFlatBorders disables 3D style for all frames except menus
635 // menus may use different border colors (eg on XP)
636 // normal frames will be drawn using the shadow color
637 // whereas window frame borders will use black
638 bool bFlatBorders = !bMenuStyle && rStyleSettings.GetUseFlatBorders();
640 // no flat borders for standard VCL controls (ie formcontrols that keep their classic look)
641 // will not affect frame windows (like dropdowns)
642 if( bFlatBorders && pWin && pWin->GetType() == WINDOW_BORDERWINDOW && (pWin != pWin->ImplGetFrameWindow()) )
644 // check for formcontrol, i.e., a control without NWF enabled
645 Control *const pControl = dynamic_cast< Control* >( pWin->GetWindow( WINDOW_CLIENT ) );
646 if( !pControl || !pControl->IsNativeWidgetEnabled() )
647 bFlatBorders = false;
650 const bool bNoDraw = nStyle & FRAME_DRAW_NODRAW;
652 if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
653 (pDev->GetOutDevType() == OUTDEV_PRINTER) ||
654 bFlatBorders )
655 nStyle |= FRAME_DRAW_MONO;
657 if( (nStyle & FRAME_DRAW_STYLE) != FRAME_DRAW_NWF &&
658 pWin && pWin->IsNativeControlSupported(CTRL_FRAME, PART_BORDER) )
660 ImplControlValue aControlValue( nStyle |
661 (pWin->GetType()==WINDOW_BORDERWINDOW ?
662 FRAME_DRAW_BORDERWINDOWBORDER : 0) );
663 Rectangle aBound, aContent;
664 Rectangle aNatRgn( rRect );
665 if( pWin->GetNativeControlRegion(CTRL_FRAME, PART_BORDER,
666 aNatRgn, 0, aControlValue, OUString(), aBound, aContent) )
668 // if bNoDraw is true then don't call the drawing routine
669 // but just update the target rectangle
670 if( bNoDraw ||
671 pWin->DrawNativeControl( CTRL_FRAME, PART_BORDER, aContent, CTRL_STATE_ENABLED,
672 aControlValue, OUString()) )
674 rRect = aContent;
675 return;
680 if ( nStyle & FRAME_DRAW_MONO )
682 // no round corners for window frame borders
683 const bool bRound = bFlatBorders && !(nStyle & FRAME_DRAW_WINDOWBORDER);
685 if ( bNoDraw )
687 ImplDrawDPILineRect( pDev, rRect, NULL, bRound );
689 else
691 Color aColor = bRound ? rStyleSettings.GetShadowColor()
692 : pDev->GetSettings().GetStyleSettings().GetMonoColor();
693 // when the MonoColor wasn't set, check face color
694 if (
695 (bRound && aColor.IsDark()) ||
697 (aColor == Color(COL_BLACK)) &&
698 pDev->GetSettings().GetStyleSettings().GetFaceColor().IsDark()
702 aColor = Color( COL_WHITE );
704 ImplDrawDPILineRect( pDev, rRect, &aColor, bRound );
707 else
709 if ( bNoDraw )
711 switch ( nStyle & FRAME_DRAW_STYLE )
713 case FRAME_DRAW_IN:
714 case FRAME_DRAW_OUT:
715 ++rRect.Left();
716 ++rRect.Top();
717 --rRect.Right();
718 --rRect.Bottom();
719 break;
721 case FRAME_DRAW_GROUP:
722 case FRAME_DRAW_DOUBLEIN:
723 case FRAME_DRAW_DOUBLEOUT:
724 rRect.Left() += 2;
725 rRect.Top() += 2;
726 rRect.Right() -= 2;
727 rRect.Bottom() -= 2;
728 break;
730 case FRAME_DRAW_NWF:
731 // enough space for the native rendering
732 rRect.Left() += 4;
733 rRect.Top() += 4;
734 rRect.Right() -= 4;
735 rRect.Bottom() -= 4;
736 break;
739 else
741 switch ( nStyle & FRAME_DRAW_STYLE )
743 case FRAME_DRAW_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 FRAME_DRAW_IN:
760 ImplDraw2ColorFrame( pDev, rRect,
761 rStyleSettings.GetShadowColor(),
762 rStyleSettings.GetLightColor() );
763 break;
765 case FRAME_DRAW_OUT:
766 ImplDraw2ColorFrame( pDev, rRect,
767 rStyleSettings.GetLightColor(),
768 rStyleSettings.GetShadowColor() );
769 break;
771 case FRAME_DRAW_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 FRAME_DRAW_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 FRAME_DRAW_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;
834 // -----------------------------------------------------------------------
836 void DecorationView::DrawSymbol( const Rectangle& rRect, SymbolType eType,
837 const Color& rColor, sal_uInt16 nStyle )
839 const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
840 const Rectangle aRect = mpOutDev->LogicToPixel( rRect );
841 const Color aOldLineColor = mpOutDev->GetLineColor();
842 const Color aOldFillColor = mpOutDev->GetFillColor();
843 const bool bOldMapMode = mpOutDev->IsMapModeEnabled();
844 Color nColor(rColor);
845 mpOutDev->EnableMapMode( sal_False );
847 if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
848 (mpOutDev->GetOutDevType() == OUTDEV_PRINTER) )
849 nStyle |= BUTTON_DRAW_MONO;
851 if ( nStyle & SYMBOL_DRAW_MONO )
853 // Monochrome: set color to black if enabled, to gray if disabled
854 nColor = Color( ( nStyle & SYMBOL_DRAW_DISABLE ) ? COL_GRAY : COL_BLACK );
856 else
858 if ( nStyle & SYMBOL_DRAW_DISABLE )
860 // Draw shifted and brighter symbol for embossed look
861 mpOutDev->SetLineColor( rStyleSettings.GetLightColor() );
862 mpOutDev->SetFillColor( rStyleSettings.GetLightColor() );
863 ImplDrawSymbol( mpOutDev, aRect + Point(1, 1) , eType );
864 nColor = rStyleSettings.GetShadowColor();
868 // Set selected color and draw the symbol
869 mpOutDev->SetLineColor( nColor );
870 mpOutDev->SetFillColor( nColor );
871 ImplDrawSymbol( mpOutDev, aRect, eType );
873 // Restore previous settings
874 mpOutDev->SetLineColor( aOldLineColor );
875 mpOutDev->SetFillColor( aOldFillColor );
876 mpOutDev->EnableMapMode( bOldMapMode );
879 // =======================================================================
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 // =======================================================================
896 void DecorationView::DrawHighlightFrame( const Rectangle& rRect,
897 sal_uInt16 nStyle )
899 const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
900 Color aLightColor = rStyleSettings.GetLightColor();
901 Color aShadowColor = rStyleSettings.GetShadowColor();
903 if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
904 (mpOutDev->GetOutDevType() == OUTDEV_PRINTER) )
906 aLightColor = Color( COL_BLACK );
907 aShadowColor = Color( COL_BLACK );
909 else if ( nStyle & FRAME_HIGHLIGHT_TESTBACKGROUND )
911 Wallpaper aBackground = mpOutDev->GetBackground();
912 if ( aBackground.IsBitmap() || aBackground.IsGradient() )
914 aLightColor = rStyleSettings.GetFaceColor();
915 aShadowColor = Color( COL_BLACK );
917 else
919 Color aBackColor = aBackground.GetColor();
920 if ( (aLightColor.GetColorError( aBackColor ) < 32) ||
921 (aShadowColor.GetColorError( aBackColor ) < 32) )
923 aLightColor = Color( COL_WHITE );
924 aShadowColor = Color( COL_BLACK );
926 if ( aLightColor.GetColorError( aBackColor ) < 32 )
927 aLightColor.DecreaseLuminance( 64 );
928 if ( aShadowColor.GetColorError( aBackColor ) < 32 )
929 aShadowColor.IncreaseLuminance( 64 );
934 if ( (nStyle & FRAME_HIGHLIGHT_STYLE) == FRAME_HIGHLIGHT_IN )
936 Color aTempColor = aLightColor;
937 aLightColor = aShadowColor;
938 aShadowColor = aTempColor;
941 DrawFrame( rRect, aLightColor, aShadowColor );
944 // =======================================================================
946 Rectangle DecorationView::DrawFrame( const Rectangle& rRect, sal_uInt16 nStyle )
948 Rectangle aRect = rRect;
949 sal_Bool bOldMap = mpOutDev->IsMapModeEnabled();
950 if ( bOldMap )
952 aRect = mpOutDev->LogicToPixel( aRect );
953 mpOutDev->EnableMapMode( sal_False );
956 if ( !rRect.IsEmpty() )
958 if ( nStyle & FRAME_DRAW_NODRAW )
959 ImplDrawFrame( mpOutDev, aRect, mpOutDev->GetSettings().GetStyleSettings(), nStyle );
960 else
962 Color maOldLineColor = mpOutDev->GetLineColor();
963 Color maOldFillColor = mpOutDev->GetFillColor();
964 ImplDrawFrame( mpOutDev, aRect, mpOutDev->GetSettings().GetStyleSettings(), nStyle );
965 mpOutDev->SetLineColor( maOldLineColor );
966 mpOutDev->SetFillColor( maOldFillColor );
970 if ( bOldMap )
972 mpOutDev->EnableMapMode( bOldMap );
973 aRect = mpOutDev->PixelToLogic( aRect );
976 return aRect;
979 // =======================================================================
981 Rectangle DecorationView::DrawButton( const Rectangle& rRect, sal_uInt16 nStyle )
983 if ( rRect.IsEmpty() )
985 return rRect;
988 Rectangle aRect = rRect;
989 const bool bOldMap = mpOutDev->IsMapModeEnabled();
991 if ( bOldMap )
993 aRect = mpOutDev->LogicToPixel( aRect );
994 mpOutDev->EnableMapMode( false );
997 const Color maOldLineColor = mpOutDev->GetLineColor();
998 const Color maOldFillColor = mpOutDev->GetFillColor();
999 ImplDrawButton( mpOutDev, aRect, nStyle );
1000 mpOutDev->SetLineColor( maOldLineColor );
1001 mpOutDev->SetFillColor( maOldFillColor );
1003 // Ein Border freilassen, der jedoch bei Default-Darstellung
1004 // mitbenutzt wird
1005 ++aRect.Left();
1006 ++aRect.Top();
1007 --aRect.Right();
1008 --aRect.Bottom();
1010 if ( nStyle & BUTTON_DRAW_NOLIGHTBORDER )
1012 ++aRect.Left();
1013 ++aRect.Top();
1015 else if ( nStyle & BUTTON_DRAW_NOLEFTLIGHTBORDER )
1017 ++aRect.Left();
1020 if ( nStyle & BUTTON_DRAW_PRESSED )
1022 if ( (aRect.GetHeight() > 10) && (aRect.GetWidth() > 10) )
1024 aRect.Left() += 4;
1025 aRect.Top() += 4;
1026 aRect.Right() -= 1;
1027 aRect.Bottom() -= 1;
1029 else
1031 aRect.Left() += 3;
1032 aRect.Top() += 3;
1033 aRect.Right() -= 2;
1034 aRect.Bottom() -= 2;
1037 else if ( nStyle & BUTTON_DRAW_CHECKED )
1039 aRect.Left() += 3;
1040 aRect.Top() += 3;
1041 aRect.Right() -= 2;
1042 aRect.Bottom() -= 2;
1044 else
1046 aRect.Left() += 2;
1047 aRect.Top() += 2;
1048 aRect.Right() -= 3;
1049 aRect.Bottom() -= 3;
1052 if ( bOldMap )
1054 mpOutDev->EnableMapMode( bOldMap );
1055 aRect = mpOutDev->PixelToLogic( aRect );
1058 return aRect;
1061 // -----------------------------------------------------------------------
1063 void DecorationView::DrawSeparator( const Point& rStart, const Point& rStop, bool bVertical )
1065 Point aStart( rStart ), aStop( rStop );
1066 const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
1067 Window *const pWin = (mpOutDev->GetOutDevType()==OUTDEV_WINDOW) ? (Window*) mpOutDev: NULL;
1068 if(pWin)
1070 ControlPart nPart = ( bVertical ? PART_SEPARATOR_VERT : PART_SEPARATOR_HORZ );
1071 bool nativeSupported = pWin->IsNativeControlSupported( CTRL_FIXEDLINE, nPart );
1072 ImplControlValue aValue;
1073 ControlState nState = 0;
1074 Rectangle aRect(rStart,rStop);
1075 if(nativeSupported && pWin->DrawNativeControl(CTRL_FIXEDLINE,nPart,aRect,nState,aValue,OUString()))
1076 return;
1079 mpOutDev->Push( PUSH_LINECOLOR );
1080 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
1081 mpOutDev->SetLineColor( Color( COL_BLACK ) );
1082 else
1083 mpOutDev->SetLineColor( rStyleSettings.GetShadowColor() );
1085 mpOutDev->DrawLine( aStart, aStop );
1086 if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
1088 mpOutDev->SetLineColor( rStyleSettings.GetLightColor() );
1089 if( bVertical )
1091 aStart.X()++;
1092 aStop.X()++;
1094 else
1096 aStart.Y()++;
1097 aStop.Y()++;
1099 mpOutDev->DrawLine( aStart, aStop );
1101 mpOutDev->Pop();
1104 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */