bump product version to 7.6.3.2-android
[LibreOffice.git] / vcl / source / window / decoview.cxx
blobe9000090086c431d2f9f0120831c22b6ed653c29
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 namespace {
28 tools::Long AdjustRectToSquare( tools::Rectangle &rRect )
30 const tools::Long nWidth = rRect.GetWidth();
31 const tools::Long nHeight = rRect.GetHeight();
32 tools::Long nSide = std::min( nWidth, nHeight );
34 if ( nSide && !(nSide & 1) )
36 // we prefer an odd size
37 --nSide;
40 // Make the rectangle a square
41 rRect.SetSize( Size( nSide, nSide ) );
43 // and place it at the center of the original rectangle
44 rRect.Move( (nWidth-nSide)/2, (nHeight-nSide)/2 );
46 return nSide;
49 void ImplDrawSymbol( OutputDevice* pDev, tools::Rectangle nRect, const SymbolType eType )
51 const tools::Long nSide = AdjustRectToSquare( nRect );
53 if ( !nSide ) return;
54 if ( nSide==1 )
56 pDev->DrawPixel( Point( nRect.Left(), nRect.Top() ) );
57 return;
60 // Precalculate some values
61 const tools::Long n2 = nSide/2;
62 const tools::Long n4 = (n2+1)/2;
63 const tools::Long n8 = (n4+1)/2;
64 const tools::Long n16 = (n8+1)/2;
65 const Point aCenter = nRect.Center();
67 switch ( eType )
69 case SymbolType::ARROW_UP:
71 tools::Polygon arrow(7);
72 arrow.SetPoint( Point( aCenter.X(), nRect.Top()), 0 );
73 arrow.SetPoint( Point( aCenter.X() - n2, nRect.Top() + n2 ), 1 );
74 arrow.SetPoint( Point( aCenter.X() - n8, nRect.Top() + n2 ), 2 );
75 arrow.SetPoint( Point( aCenter.X() - n8, nRect.Bottom()), 3 );
76 arrow.SetPoint( Point( aCenter.X() + n8, nRect.Bottom()), 4 );
77 arrow.SetPoint( Point( aCenter.X() + n8, nRect.Top() + n2 ), 5 );
78 arrow.SetPoint( Point( aCenter.X() + n2, nRect.Top() + n2 ), 6 );
79 pDev->Push(vcl::PushFlags::LINECOLOR);
80 pDev->SetLineColor();
81 pDev->DrawPolygon( arrow );
82 pDev->Pop();
83 break;
86 case SymbolType::ARROW_DOWN:
88 tools::Polygon arrow(7);
89 arrow.SetPoint( Point( aCenter.X(), nRect.Bottom()), 0 );
90 arrow.SetPoint( Point( aCenter.X() - n2, nRect.Bottom() - n2 ), 1 );
91 arrow.SetPoint( Point( aCenter.X() - n8, nRect.Bottom() - n2 ), 2 );
92 arrow.SetPoint( Point( aCenter.X() - n8, nRect.Top()), 3 );
93 arrow.SetPoint( Point( aCenter.X() + n8, nRect.Top()), 4 );
94 arrow.SetPoint( Point( aCenter.X() + n8, nRect.Bottom() - n2 ), 5 );
95 arrow.SetPoint( Point( aCenter.X() + n2, nRect.Bottom() - n2 ), 6 );
96 pDev->Push(vcl::PushFlags::LINECOLOR);
97 pDev->SetLineColor();
98 pDev->DrawPolygon( arrow );
99 pDev->Pop();
100 break;
103 case SymbolType::ARROW_LEFT:
105 tools::Polygon arrow(7);
106 arrow.SetPoint( Point( nRect.Left(), aCenter.Y()), 0 );
107 arrow.SetPoint( Point( nRect.Left() + n2, aCenter.Y() - n2 ), 1 );
108 arrow.SetPoint( Point( nRect.Left() + n2, aCenter.Y() - n8 ), 2 );
109 arrow.SetPoint( Point( nRect.Right(), aCenter.Y() - n8 ), 3 );
110 arrow.SetPoint( Point( nRect.Right(), aCenter.Y() + n8 ), 4 );
111 arrow.SetPoint( Point( nRect.Left() + n2, aCenter.Y() + n8 ), 5 );
112 arrow.SetPoint( Point( nRect.Left() + n2, aCenter.Y() + n2 ), 6 );
113 pDev->Push(vcl::PushFlags::LINECOLOR);
114 pDev->SetLineColor();
115 pDev->DrawPolygon( arrow );
116 pDev->Pop();
117 break;
120 case SymbolType::ARROW_RIGHT:
122 tools::Polygon arrow(7);
123 arrow.SetPoint( Point( nRect.Right(), aCenter.Y()), 0 );
124 arrow.SetPoint( Point( nRect.Right() - n2, aCenter.Y() - n2 ), 1 );
125 arrow.SetPoint( Point( nRect.Right() - n2, aCenter.Y() - n8 ), 2 );
126 arrow.SetPoint( Point( nRect.Left(), aCenter.Y() - n8 ), 3 );
127 arrow.SetPoint( Point( nRect.Left(), aCenter.Y() + n8 ), 4 );
128 arrow.SetPoint( Point( nRect.Right() - n2, aCenter.Y() + n8 ), 5 );
129 arrow.SetPoint( Point( nRect.Right() - n2, aCenter.Y() + n2 ), 6 );
130 pDev->Push(vcl::PushFlags::LINECOLOR);
131 pDev->SetLineColor();
132 pDev->DrawPolygon( arrow );
133 pDev->Pop();
134 break;
137 case SymbolType::SPIN_UP:
139 tools::Polygon triangle( 3 );
140 triangle.SetPoint( Point( aCenter.X(), nRect.Top() + n4 ), 0 );
141 triangle.SetPoint( Point( aCenter.X() - n2, nRect.Top() + n4 + n2 ), 1 );
142 triangle.SetPoint( Point( aCenter.X() + n2, nRect.Top() + n4 + n2 ), 2 );
143 pDev->Push(vcl::PushFlags::LINECOLOR);
144 pDev->SetLineColor();
145 pDev->DrawPolygon( triangle );
146 pDev->Pop();
147 break;
150 case SymbolType::SPIN_DOWN:
152 tools::Polygon triangle( 3 );
153 triangle.SetPoint( Point( aCenter.X(), nRect.Bottom() - n4 ), 0 );
154 triangle.SetPoint( Point( aCenter.X() - n2, nRect.Bottom() - n4 - n2 ), 1 );
155 triangle.SetPoint( Point( aCenter.X() + n2, nRect.Bottom() - n4 - n2 ), 2 );
156 pDev->Push(vcl::PushFlags::LINECOLOR);
157 pDev->SetLineColor();
158 pDev->DrawPolygon( triangle );
159 pDev->Pop();
160 break;
163 case SymbolType::SPIN_LEFT:
164 case SymbolType::FIRST:
165 case SymbolType::PREV:
167 nRect.AdjustLeft(n4 );
168 if ( eType==SymbolType::FIRST )
170 pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
171 Point( nRect.Left(), nRect.Bottom() ) );
172 nRect.AdjustLeft( 1 );
175 tools::Polygon aTriangle(3);
176 aTriangle.SetPoint(Point(nRect.Left() + n2, aCenter.Y() - n2), 0);
177 aTriangle.SetPoint(Point(nRect.Left(), aCenter.Y()), 1);
178 aTriangle.SetPoint(Point(nRect.Left() + n2, aCenter.Y() + n2), 2);
180 pDev->Push(vcl::PushFlags::LINECOLOR);
181 pDev->SetLineColor();
182 pDev->DrawPolygon(aTriangle);
183 pDev->Pop();
185 break;
188 case SymbolType::SPIN_RIGHT:
189 case SymbolType::LAST:
190 case SymbolType::NEXT:
191 case SymbolType::PLAY:
193 nRect.AdjustRight( -n4 );
194 if ( eType==SymbolType::LAST )
196 pDev->DrawLine( Point( nRect.Right(), nRect.Top() ),
197 Point( nRect.Right(), nRect.Bottom() ) );
198 nRect.AdjustRight( -1 );
201 tools::Polygon aTriangle(3);
202 aTriangle.SetPoint(Point(nRect.Right() - n2, aCenter.Y() - n2), 0);
203 aTriangle.SetPoint(Point(nRect.Right(), aCenter.Y()), 1);
204 aTriangle.SetPoint(Point(nRect.Right() - n2, aCenter.Y() + n2), 2);
206 pDev->Push(vcl::PushFlags::LINECOLOR);
207 pDev->SetLineColor();
208 pDev->DrawPolygon(aTriangle);
209 pDev->Pop();
210 break;
213 case SymbolType::PAGEUP:
215 tools::Polygon triangle( 3 );
216 triangle.SetPoint( Point( aCenter.X(), nRect.Top()), 0 );
217 triangle.SetPoint( Point( aCenter.X() - n2, nRect.Top() + n2 ), 1 );
218 triangle.SetPoint( Point( aCenter.X() + n2, nRect.Top() + n2 ), 2 );
219 pDev->Push(vcl::PushFlags::LINECOLOR);
220 pDev->SetLineColor();
221 pDev->DrawPolygon( triangle );
222 triangle.Move( 0, n2 );
223 pDev->DrawPolygon( triangle );
224 pDev->Pop();
225 break;
228 case SymbolType::PAGEDOWN:
230 tools::Polygon triangle( 3 );
231 triangle.SetPoint( Point( aCenter.X(), nRect.Bottom()), 0 );
232 triangle.SetPoint( Point( aCenter.X() - n2, nRect.Bottom() - n2 ), 1 );
233 triangle.SetPoint( Point( aCenter.X() + n2, nRect.Bottom() - n2 ), 2 );
234 pDev->Push(vcl::PushFlags::LINECOLOR);
235 pDev->SetLineColor();
236 pDev->DrawPolygon( triangle );
237 triangle.Move( 0, -n2 );
238 pDev->DrawPolygon( triangle );
239 pDev->Pop();
240 break;
243 case SymbolType::RADIOCHECKMARK:
245 pDev->DrawEllipse(nRect);
246 break;
249 case SymbolType::STOP:
250 pDev->DrawRect( nRect );
251 break;
253 case SymbolType::CLOSE:
255 const tools::Long diff = std::max<tools::Long>( 0, n8 - 1 );
256 tools::Polygon cross( 16 );
257 cross.SetPoint( Point( nRect.Left(), nRect.Top()), 0 );
258 cross.SetPoint( Point( nRect.Left(), nRect.Top() + diff ), 1 );
259 cross.SetPoint( Point( aCenter.X() - diff, aCenter.Y()), 2 );
260 cross.SetPoint( Point( nRect.Left(), nRect.Bottom() - diff ), 3 );
261 cross.SetPoint( Point( nRect.Left(), nRect.Bottom()), 4 );
262 cross.SetPoint( Point( nRect.Left() + diff, nRect.Bottom()), 5 );
263 cross.SetPoint( Point( aCenter.X(), aCenter.Y() + diff ), 6 );
264 cross.SetPoint( Point( nRect.Right() - diff, nRect.Bottom()), 7 );
265 cross.SetPoint( Point( nRect.Right(), nRect.Bottom()), 8 );
266 cross.SetPoint( Point( nRect.Right(), nRect.Bottom() - diff ), 9 );
267 cross.SetPoint( Point( aCenter.X() + diff, aCenter.Y()), 10 );
268 cross.SetPoint( Point( nRect.Right(), nRect.Top() + diff ), 11 );
269 cross.SetPoint( Point( nRect.Right(), nRect.Top()), 12 );
270 cross.SetPoint( Point( nRect.Right() - diff, nRect.Top()), 13 );
271 cross.SetPoint( Point( aCenter.X(), aCenter.Y() - diff ), 14 );
272 cross.SetPoint( Point( nRect.Left() + diff, nRect.Top()), 15 );
273 pDev->DrawPolygon( cross );
274 break;
277 case SymbolType::CHECKMARK:
279 tools::Long n3 = nSide/3;
280 nRect.AdjustTop( -(n3/2) );
281 nRect.AdjustBottom( -(n3/2) );
282 tools::Polygon checkmark(6);
283 // #106953# never mirror checkmarks
284 if ( pDev->HasMirroredGraphics() && pDev->IsRTLEnabled() )
286 // Draw a mirrored checkmark so that it looks "normal" in a
287 // mirrored graphics device (double mirroring!)
288 checkmark.SetPoint( Point( nRect.Right(), nRect.Bottom()-n3 ), 0 );
289 checkmark.SetPoint( Point( nRect.Right()-n3, nRect.Bottom()), 1 );
290 checkmark.SetPoint( Point( nRect.Left(), nRect.Top()+n3 ), 2 );
291 checkmark.SetPoint( Point( nRect.Left(), nRect.Top()+n3 + 1 ), 3 );
292 checkmark.SetPoint( Point( nRect.Right()-n3, nRect.Bottom() + 1 ), 4 );
293 checkmark.SetPoint( Point( nRect.Right(), nRect.Bottom()-n3 + 1 ), 5 );
295 else
297 checkmark.SetPoint( Point( nRect.Left(), nRect.Bottom()-n3 ), 0 );
298 checkmark.SetPoint( Point( nRect.Left()+n3, nRect.Bottom()), 1 );
299 checkmark.SetPoint( Point( nRect.Right(), nRect.Top()+n3 ), 2 );
300 checkmark.SetPoint( Point( nRect.Right(), nRect.Top()+n3 + 1 ), 3 );
301 checkmark.SetPoint( Point( nRect.Left()+n3, nRect.Bottom() + 1 ), 4 );
302 checkmark.SetPoint( Point( nRect.Left(), nRect.Bottom()-n3 + 1 ), 5 );
304 pDev->DrawPolygon( checkmark );
306 break;
308 case SymbolType::FLOAT:
309 nRect.AdjustRight( -n4 );
310 nRect.AdjustTop(n4+1 );
311 pDev->DrawRect( tools::Rectangle( nRect.Left(), nRect.Top(),
312 nRect.Right(), nRect.Top()+n8 ) );
313 pDev->DrawLine( Point( nRect.Left(), nRect.Top()+n8 ),
314 Point( nRect.Left(), nRect.Bottom() ) );
315 pDev->DrawLine( Point( nRect.Left(), nRect.Bottom() ),
316 Point( nRect.Right(), nRect.Bottom() ) );
317 pDev->DrawLine( Point( nRect.Right(), nRect.Top()+n8 ),
318 Point( nRect.Right(), nRect.Bottom() ) );
319 nRect.AdjustRight(n4 );
320 nRect.AdjustTop( -(n4+1) );
321 nRect.AdjustLeft(n4 );
322 nRect.AdjustBottom( -(n4+1) );
323 pDev->DrawRect( tools::Rectangle( nRect.Left(), nRect.Top(),
324 nRect.Right(), nRect.Top()+n8 ) );
325 pDev->DrawLine( Point( nRect.Left(), nRect.Top()+n8 ),
326 Point( nRect.Left(), nRect.Bottom() ) );
327 pDev->DrawLine( Point( nRect.Left(), nRect.Bottom() ),
328 Point( nRect.Right(), nRect.Bottom() ) );
329 pDev->DrawLine( Point( nRect.Right(), nRect.Top()+n8 ),
330 Point( nRect.Right(), nRect.Bottom() ) );
331 break;
333 case SymbolType::DOCK:
334 pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
335 Point( nRect.Right(), nRect.Top() ) );
336 pDev->DrawLine( Point( nRect.Left(), nRect.Top() ),
337 Point( nRect.Left(), nRect.Bottom() ) );
338 pDev->DrawLine( Point( nRect.Left(), nRect.Bottom() ),
339 Point( nRect.Right(), nRect.Bottom() ) );
340 pDev->DrawLine( Point( nRect.Right(), nRect.Top() ),
341 Point( nRect.Right(), nRect.Bottom() ) );
342 break;
344 case SymbolType::HIDE:
345 pDev->DrawRect( tools::Rectangle( nRect.Left()+n8, nRect.Bottom()-n8,
346 nRect.Right()-n8, nRect.Bottom() ) );
347 break;
349 case SymbolType::PLUS:
350 pDev->DrawRect( tools::Rectangle( nRect.Left(), aCenter.Y()-n16,
351 nRect.Right(), aCenter.Y()+n16 ) );
352 pDev->DrawRect( tools::Rectangle( aCenter.X()-n16, nRect.Top(),
353 aCenter.X()+n16, nRect.Bottom() ) );
354 break;
355 case SymbolType::DONTKNOW:
356 case SymbolType::IMAGE:
357 case SymbolType::HELP: break;
361 void ImplDrawDPILineRect( OutputDevice *const pDev, tools::Rectangle& rRect,
362 const Color *const pColor, const bool bRound = false )
364 tools::Long nLineWidth = pDev->GetDPIX()/300;
365 tools::Long nLineHeight = pDev->GetDPIY()/300;
366 if ( !nLineWidth )
367 nLineWidth = 1;
368 if ( !nLineHeight )
369 nLineHeight = 1;
371 if ( pColor )
373 if ( (nLineWidth == 1) && (nLineHeight == 1) )
375 pDev->SetLineColor( *pColor );
376 if( bRound )
378 pDev->DrawLine( Point( rRect.Left()+1, rRect.Top()), Point( rRect.Right()-1, rRect.Top()) );
379 pDev->DrawLine( Point( rRect.Left()+1, rRect.Bottom()), Point( rRect.Right()-1, rRect.Bottom()) );
380 pDev->DrawLine( Point( rRect.Left(), rRect.Top()+1), Point( rRect.Left(), rRect.Bottom()-1) );
381 pDev->DrawLine( Point( rRect.Right(), rRect.Top()+1), Point( rRect.Right(), rRect.Bottom()-1) );
383 else
385 pDev->SetFillColor();
386 pDev->DrawRect( rRect );
389 else
391 const tools::Long nWidth = rRect.GetWidth();
392 const tools::Long nHeight = rRect.GetHeight();
393 pDev->SetLineColor();
394 pDev->SetFillColor( *pColor );
395 pDev->DrawRect( tools::Rectangle( rRect.TopLeft(), Size( nWidth, nLineHeight ) ) );
396 pDev->DrawRect( tools::Rectangle( rRect.TopLeft(), Size( nLineWidth, nHeight ) ) );
397 pDev->DrawRect( tools::Rectangle( Point( rRect.Left(), rRect.Bottom()-nLineHeight ),
398 Size( nWidth, nLineHeight ) ) );
399 pDev->DrawRect( tools::Rectangle( Point( rRect.Right()-nLineWidth, rRect.Top() ),
400 Size( nLineWidth, nHeight ) ) );
404 rRect.AdjustLeft(nLineWidth );
405 rRect.AdjustTop(nLineHeight );
406 rRect.AdjustRight( -nLineWidth );
407 rRect.AdjustBottom( -nLineHeight );
410 void ImplDraw2ColorFrame( OutputDevice *const pDev, tools::Rectangle& rRect,
411 const Color& rLeftTopColor, const Color& rRightBottomColor )
413 pDev->SetLineColor( rLeftTopColor );
414 pDev->DrawLine( rRect.TopLeft(), rRect.BottomLeft() );
415 pDev->DrawLine( rRect.TopLeft(), rRect.TopRight() );
416 pDev->SetLineColor( rRightBottomColor );
417 pDev->DrawLine( rRect.BottomLeft(), rRect.BottomRight() );
418 pDev->DrawLine( rRect.TopRight(), rRect.BottomRight() );
420 // reduce drawing area
421 rRect.AdjustLeft( 1 );
422 rRect.AdjustTop( 1 );
423 rRect.AdjustRight( -1 );
424 rRect.AdjustBottom( -1 );
427 void ImplDrawButton( OutputDevice *const pDev, tools::Rectangle aFillRect,
428 const DrawButtonFlags nStyle )
430 const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
432 if ( (nStyle & DrawButtonFlags::Mono) ||
433 (rStyleSettings.GetOptions() & StyleSettingsOptions::Mono) )
435 const Color aBlackColor(COL_BLACK);
437 if ( nStyle & DrawButtonFlags::Default )
439 // default selection shows a wider border
440 ImplDrawDPILineRect( pDev, aFillRect, &aBlackColor );
443 ImplDrawDPILineRect( pDev, aFillRect, &aBlackColor );
445 Size aBrdSize(pDev->GetButtonBorderSize());
447 pDev->SetLineColor();
448 pDev->SetFillColor( aBlackColor );
449 const tools::Rectangle aOrigFillRect(aFillRect);
450 if ( nStyle & (DrawButtonFlags::Pressed | DrawButtonFlags::Checked) )
452 // shrink fill rect
453 aFillRect.AdjustLeft(aBrdSize.Width() );
454 aFillRect.AdjustTop(aBrdSize.Height() );
455 // draw top and left borders (aOrigFillRect-aFillRect)
456 pDev->DrawRect( tools::Rectangle( aOrigFillRect.Left(), aOrigFillRect.Top(),
457 aOrigFillRect.Right(), aFillRect.Top()-1 ) );
458 pDev->DrawRect( tools::Rectangle( aOrigFillRect.Left(), aOrigFillRect.Top(),
459 aFillRect.Left()-1, aOrigFillRect.Bottom() ) );
461 else
463 // shrink fill rect
464 aFillRect.AdjustRight( -(aBrdSize.Width()) );
465 aFillRect.AdjustBottom( -(aBrdSize.Height()) );
466 // draw bottom and right borders (aOrigFillRect-aFillRect)
467 pDev->DrawRect( tools::Rectangle( aOrigFillRect.Left(), aFillRect.Bottom()+1,
468 aOrigFillRect.Right(), aOrigFillRect.Bottom() ) );
469 pDev->DrawRect( tools::Rectangle( aFillRect.Right()+1, aOrigFillRect.Top(),
470 aOrigFillRect.Right(), aOrigFillRect.Bottom() ) );
473 // Hack: in monochrome mode on printers we like to have grey buttons
474 pDev->SetFillColor(pDev->GetMonochromeButtonColor());
475 pDev->DrawRect( aFillRect );
477 else
479 const bool bFlat(nStyle & DrawButtonFlags::Flat);
480 const bool bDepressed(nStyle & (DrawButtonFlags::Pressed | DrawButtonFlags::Checked));
482 if ( nStyle & DrawButtonFlags::Default )
484 const Color aDefBtnColor = rStyleSettings.GetDarkShadowColor();
485 ImplDrawDPILineRect( pDev, aFillRect, &aDefBtnColor );
488 if ( nStyle & DrawButtonFlags::NoLeftLightBorder )
490 pDev->SetLineColor( rStyleSettings.GetLightBorderColor() );
491 pDev->DrawLine( Point( aFillRect.Left(), aFillRect.Top() ),
492 Point( aFillRect.Left(), aFillRect.Bottom() ) );
493 aFillRect.AdjustLeft( 1 );
496 bool bNoFace = false;
497 Color aColor1;
498 Color aColor2;
499 if (!bFlat)
501 if (bDepressed)
503 aColor1 = rStyleSettings.GetDarkShadowColor();
504 aColor2 = rStyleSettings.GetLightColor();
506 else
508 if ( nStyle & DrawButtonFlags::NoLightBorder )
509 aColor1 = rStyleSettings.GetLightBorderColor();
510 else
511 aColor1 = rStyleSettings.GetLightColor();
512 aColor2 = rStyleSettings.GetDarkShadowColor();
515 ImplDraw2ColorFrame( pDev, aFillRect, aColor1, aColor2 );
517 if (bDepressed)
519 aColor1 = rStyleSettings.GetShadowColor();
520 aColor2 = rStyleSettings.GetLightBorderColor();
522 else
524 if ( nStyle & DrawButtonFlags::NoLightBorder )
525 aColor1 = rStyleSettings.GetLightColor();
526 else
527 aColor1 = rStyleSettings.GetLightBorderColor();
528 aColor2 = rStyleSettings.GetShadowColor();
530 ImplDraw2ColorFrame( pDev, aFillRect, aColor1, aColor2 );
532 else // flat buttons
534 // draw a border if the flat button is highlighted
535 if (nStyle & DrawButtonFlags::Highlight)
537 aColor1 = rStyleSettings.GetShadowColor();
538 ImplDraw2ColorFrame(pDev, aFillRect, aColor1, aColor1);
540 // fill in the button if it is pressed in
541 bNoFace = !bDepressed;
544 pDev->SetLineColor();
545 if ( nStyle & (DrawButtonFlags::Checked | DrawButtonFlags::DontKnow) )
546 pDev->SetFillColor( rStyleSettings.GetCheckedColor() );
547 else if (!bNoFace)
548 pDev->SetFillColor( rStyleSettings.GetFaceColor() );
549 pDev->DrawRect( aFillRect );
553 void ImplDrawFrame( OutputDevice *const pDev, tools::Rectangle& rRect,
554 const StyleSettings& rStyleSettings, DrawFrameStyle nStyle, DrawFrameFlags nFlags )
556 vcl::Window * pWin = pDev->GetOwnerWindow();
558 const bool bMenuStyle(nFlags & DrawFrameFlags::Menu);
560 // UseFlatBorders disables 3D style for all frames except menus
561 // menus may use different border colors (eg on XP)
562 // normal frames will be drawn using the shadow color
563 // whereas window frame borders will use black
564 bool bFlatBorders = !bMenuStyle && rStyleSettings.GetUseFlatBorders();
566 // no flat borders for standard VCL controls (ie formcontrols that keep their classic look)
567 // will not affect frame windows (like dropdowns)
568 if( bFlatBorders && pWin && pWin->GetType() == WindowType::BORDERWINDOW && (pWin != pWin->ImplGetFrameWindow()) )
570 // check for formcontrol, i.e., a control without NWF enabled
571 Control *const pControl = dynamic_cast< Control* >( pWin->GetWindow( GetWindowType::Client ) );
572 if( !pControl || !pControl->IsNativeWidgetEnabled() )
573 bFlatBorders = false;
576 const bool bNoDraw(nFlags & DrawFrameFlags::NoDraw);
578 if ( (rStyleSettings.GetOptions() & StyleSettingsOptions::Mono) ||
579 (pDev->GetOutDevType() == OUTDEV_PRINTER) ||
580 bFlatBorders )
581 nFlags |= DrawFrameFlags::Mono;
583 if( nStyle != DrawFrameStyle::NWF &&
584 pWin && pWin->IsNativeControlSupported(ControlType::Frame, ControlPart::Border) )
586 tools::Long nControlFlags = static_cast<tools::Long>(nStyle);
587 nControlFlags |= static_cast<tools::Long>(nFlags);
588 nControlFlags |= static_cast<tools::Long>(pWin->GetType() == WindowType::BORDERWINDOW ?
589 DrawFrameFlags::BorderWindowBorder : DrawFrameFlags::NONE);
590 ImplControlValue aControlValue( nControlFlags );
592 tools::Rectangle aBound, aContent;
593 tools::Rectangle aNatRgn( rRect );
594 if( pWin->GetNativeControlRegion(ControlType::Frame, ControlPart::Border,
595 aNatRgn, ControlState::NONE, aControlValue, aBound, aContent) )
597 // if bNoDraw is true then don't call the drawing routine
598 // but just update the target rectangle
599 if( bNoDraw ||
600 pWin->GetOutDev()->DrawNativeControl( ControlType::Frame, ControlPart::Border, aBound, ControlState::ENABLED,
601 aControlValue, OUString()) )
603 rRect = aContent;
604 return;
609 if ( nFlags & DrawFrameFlags::Mono )
611 // no round corners for window frame borders
612 const bool bRound = bFlatBorders && !(nFlags & DrawFrameFlags::WindowBorder);
614 if ( bNoDraw )
616 ImplDrawDPILineRect( pDev, rRect, nullptr, bRound );
618 else
620 Color aColor = bRound ? rStyleSettings.GetShadowColor()
621 : pDev->GetSettings().GetStyleSettings().GetMonoColor();
622 // when the MonoColor wasn't set, check face color
623 if (
624 (bRound && aColor.IsDark()) ||
626 (aColor == COL_BLACK) &&
627 pDev->GetSettings().GetStyleSettings().GetFaceColor().IsDark()
631 aColor = COL_WHITE;
633 ImplDrawDPILineRect( pDev, rRect, &aColor, bRound );
636 else
638 if ( bNoDraw )
640 switch ( nStyle )
642 case DrawFrameStyle::In:
643 case DrawFrameStyle::Out:
644 rRect.AdjustLeft( 1 );
645 rRect.AdjustTop( 1 );
646 rRect.AdjustRight( -1 );
647 rRect.AdjustBottom( -1 );
648 break;
650 case DrawFrameStyle::Group:
651 case DrawFrameStyle::DoubleIn:
652 case DrawFrameStyle::DoubleOut:
653 rRect.AdjustLeft(2 );
654 rRect.AdjustTop(2 );
655 rRect.AdjustRight( -2 );
656 rRect.AdjustBottom( -2 );
657 break;
659 case DrawFrameStyle::NWF:
660 // enough space for the native rendering
661 rRect.AdjustLeft(4 );
662 rRect.AdjustTop(4 );
663 rRect.AdjustRight( -4 );
664 rRect.AdjustBottom( -4 );
665 break;
666 default: break;
669 else
671 switch ( nStyle )
673 case DrawFrameStyle::Group:
674 pDev->SetFillColor();
675 pDev->SetLineColor( rStyleSettings.GetLightColor() );
676 pDev->DrawRect( tools::Rectangle( rRect.Left()+1, rRect.Top()+1,
677 rRect.Right(), rRect.Bottom() ) );
678 pDev->SetLineColor( rStyleSettings.GetShadowColor() );
679 pDev->DrawRect( tools::Rectangle( rRect.Left(), rRect.Top(),
680 rRect.Right()-1, rRect.Bottom()-1 ) );
682 // adjust target rectangle
683 rRect.AdjustLeft(2 );
684 rRect.AdjustTop(2 );
685 rRect.AdjustRight( -2 );
686 rRect.AdjustBottom( -2 );
687 break;
689 case DrawFrameStyle::In:
690 ImplDraw2ColorFrame( pDev, rRect,
691 rStyleSettings.GetShadowColor(),
692 rStyleSettings.GetLightColor() );
693 break;
695 case DrawFrameStyle::Out:
696 ImplDraw2ColorFrame( pDev, rRect,
697 rStyleSettings.GetLightColor(),
698 rStyleSettings.GetShadowColor() );
699 break;
701 case DrawFrameStyle::DoubleIn:
702 if( bFlatBorders )
704 // no 3d effect
705 ImplDraw2ColorFrame( pDev, rRect,
706 rStyleSettings.GetShadowColor(),
707 rStyleSettings.GetShadowColor() );
708 ImplDraw2ColorFrame( pDev, rRect,
709 rStyleSettings.GetFaceColor(),
710 rStyleSettings.GetFaceColor() );
712 else
714 ImplDraw2ColorFrame( pDev, rRect,
715 rStyleSettings.GetShadowColor(),
716 rStyleSettings.GetLightColor() );
717 ImplDraw2ColorFrame( pDev, rRect,
718 rStyleSettings.GetDarkShadowColor(),
719 rStyleSettings.GetLightBorderColor() );
721 break;
723 case DrawFrameStyle::DoubleOut:
724 if( bMenuStyle )
726 ImplDraw2ColorFrame( pDev, rRect,
727 rStyleSettings.GetMenuBorderColor(),
728 rStyleSettings.GetDarkShadowColor() );
729 if ( !rStyleSettings.GetUseFlatMenus() )
731 ImplDraw2ColorFrame( pDev, rRect,
732 rStyleSettings.GetLightColor(),
733 rStyleSettings.GetShadowColor() );
736 else
738 ImplDraw2ColorFrame( pDev, rRect,
739 bFlatBorders ? // no 3d effect
740 rStyleSettings.GetDarkShadowColor() :
741 rStyleSettings.GetLightBorderColor(),
742 rStyleSettings.GetDarkShadowColor() );
743 ImplDraw2ColorFrame( pDev, rRect,
744 rStyleSettings.GetLightColor(),
745 rStyleSettings.GetShadowColor() );
747 break;
749 case DrawFrameStyle::NWF:
750 // no rendering, just enough space for the native rendering
751 rRect.AdjustLeft(4 );
752 rRect.AdjustTop(4 );
753 rRect.AdjustRight( -4 );
754 rRect.AdjustBottom( -4 );
755 break;
756 default: break;
762 } // end anonymous namespace
764 DecorationView::DecorationView(OutputDevice* pOutDev) :
765 mpOutDev(pOutDev)
768 void DecorationView::DrawSymbol( const tools::Rectangle& rRect, SymbolType eType,
769 const Color& rColor, DrawSymbolFlags nStyle )
771 const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
772 const tools::Rectangle aRect = mpOutDev->LogicToPixel( rRect );
773 const Color aOldLineColor = mpOutDev->GetLineColor();
774 const Color aOldFillColor = mpOutDev->GetFillColor();
775 const bool bOldMapMode = mpOutDev->IsMapModeEnabled();
776 Color nColor(rColor);
777 mpOutDev->EnableMapMode( false );
779 if ( (rStyleSettings.GetOptions() & StyleSettingsOptions::Mono) ||
780 (mpOutDev->GetOutDevType() == OUTDEV_PRINTER) )
781 nStyle |= DrawSymbolFlags::Mono;
783 if ( nStyle & DrawSymbolFlags::Mono )
785 // Monochrome: set color to black if enabled, to gray if disabled
786 nColor = ( nStyle & DrawSymbolFlags::Disable ) ? COL_GRAY : COL_BLACK;
788 else
790 if ( nStyle & DrawSymbolFlags::Disable )
792 // Draw shifted and brighter symbol for embossed look
793 mpOutDev->SetLineColor( rStyleSettings.GetLightColor() );
794 mpOutDev->SetFillColor( rStyleSettings.GetLightColor() );
795 ImplDrawSymbol( mpOutDev, aRect + Point(1, 1) , eType );
796 nColor = rStyleSettings.GetShadowColor();
800 // Set selected color and draw the symbol
801 mpOutDev->SetLineColor( nColor );
802 mpOutDev->SetFillColor( nColor );
803 ImplDrawSymbol( mpOutDev, aRect, eType );
805 // Restore previous settings
806 mpOutDev->SetLineColor( aOldLineColor );
807 mpOutDev->SetFillColor( aOldFillColor );
808 mpOutDev->EnableMapMode( bOldMapMode );
811 void DecorationView::DrawFrame( const tools::Rectangle& rRect,
812 const Color& rLeftTopColor,
813 const Color& rRightBottomColor )
815 tools::Rectangle aRect = mpOutDev->LogicToPixel( rRect );
816 const Color aOldLineColor = mpOutDev->GetLineColor();
817 const bool bOldMapMode = mpOutDev->IsMapModeEnabled();
818 mpOutDev->EnableMapMode( false );
819 ImplDraw2ColorFrame( mpOutDev, aRect, rLeftTopColor, rRightBottomColor );
820 mpOutDev->SetLineColor( aOldLineColor );
821 mpOutDev->EnableMapMode( bOldMapMode );
824 void DecorationView::DrawHighlightFrame( const tools::Rectangle& rRect,
825 DrawHighlightFrameStyle nStyle )
827 const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
828 Color aLightColor = rStyleSettings.GetLightColor();
829 Color aShadowColor = rStyleSettings.GetShadowColor();
831 if ( (rStyleSettings.GetOptions() & StyleSettingsOptions::Mono) ||
832 (mpOutDev->GetOutDevType() == OUTDEV_PRINTER) )
834 aLightColor = COL_BLACK;
835 aShadowColor = COL_BLACK;
837 else
839 Wallpaper aBackground = mpOutDev->GetBackground();
840 if ( aBackground.IsBitmap() || aBackground.IsGradient() )
842 aLightColor = rStyleSettings.GetFaceColor();
843 aShadowColor = COL_BLACK;
845 else
847 Color aBackColor = aBackground.GetColor();
848 if ( (aLightColor.GetColorError( aBackColor ) < 96) ||
849 (aShadowColor.GetColorError( aBackColor ) < 96) )
851 aLightColor = COL_WHITE;
852 aShadowColor = COL_BLACK;
854 if ( aLightColor.GetColorError( aBackColor ) < 96 )
855 aLightColor.DecreaseLuminance( 64 );
856 if ( aShadowColor.GetColorError( aBackColor ) < 96 )
857 aShadowColor.IncreaseLuminance( 64 );
862 if ( nStyle == DrawHighlightFrameStyle::In )
863 std::swap( aLightColor, aShadowColor );
865 DrawFrame( rRect, aLightColor, aShadowColor );
868 tools::Rectangle DecorationView::DrawFrame( const tools::Rectangle& rRect, DrawFrameStyle nStyle, DrawFrameFlags nFlags )
870 tools::Rectangle aRect = rRect;
871 bool bOldMap = mpOutDev->IsMapModeEnabled();
872 if ( bOldMap )
874 aRect = mpOutDev->LogicToPixel( aRect );
875 mpOutDev->EnableMapMode( false );
878 if ( !rRect.IsEmpty() )
880 if ( nFlags & DrawFrameFlags::NoDraw )
881 ImplDrawFrame( mpOutDev, aRect, mpOutDev->GetSettings().GetStyleSettings(), nStyle, nFlags );
882 else
884 Color aOldLineColor = mpOutDev->GetLineColor();
885 Color aOldFillColor = mpOutDev->GetFillColor();
886 ImplDrawFrame( mpOutDev, aRect, mpOutDev->GetSettings().GetStyleSettings(), nStyle, nFlags );
887 mpOutDev->SetLineColor( aOldLineColor );
888 mpOutDev->SetFillColor( aOldFillColor );
892 if ( bOldMap )
894 mpOutDev->EnableMapMode( bOldMap );
895 aRect = mpOutDev->PixelToLogic( aRect );
898 return aRect;
901 tools::Rectangle DecorationView::DrawButton( const tools::Rectangle& rRect, DrawButtonFlags nStyle )
903 if ( rRect.IsEmpty() )
905 return rRect;
908 tools::Rectangle aRect = rRect;
909 const bool bOldMap = mpOutDev->IsMapModeEnabled();
911 if ( bOldMap )
913 aRect = mpOutDev->LogicToPixel( aRect );
914 mpOutDev->EnableMapMode( false );
917 const Color aOldLineColor = mpOutDev->GetLineColor();
918 const Color aOldFillColor = mpOutDev->GetFillColor();
919 ImplDrawButton( mpOutDev, aRect, nStyle );
920 mpOutDev->SetLineColor( aOldLineColor );
921 mpOutDev->SetFillColor( aOldFillColor );
923 // keep border free, although it is used at default representation
924 aRect.AdjustLeft( 1 );
925 aRect.AdjustTop( 1 );
926 aRect.AdjustRight( -1 );
927 aRect.AdjustBottom( -1 );
929 if ( nStyle & DrawButtonFlags::NoLightBorder )
931 aRect.AdjustLeft( 1 );
932 aRect.AdjustTop( 1 );
934 else if ( nStyle & DrawButtonFlags::NoLeftLightBorder )
936 aRect.AdjustLeft( 1 );
939 if ( nStyle & DrawButtonFlags::Pressed )
941 if ( (aRect.GetHeight() > 10) && (aRect.GetWidth() > 10) )
943 aRect.AdjustLeft(4 );
944 aRect.AdjustTop(4 );
945 aRect.AdjustRight( -1 );
946 aRect.AdjustBottom( -1 );
948 else
950 aRect.AdjustLeft(3 );
951 aRect.AdjustTop(3 );
952 aRect.AdjustRight( -2 );
953 aRect.AdjustBottom( -2 );
956 else if ( nStyle & DrawButtonFlags::Checked )
958 aRect.AdjustLeft(3 );
959 aRect.AdjustTop(3 );
960 aRect.AdjustRight( -2 );
961 aRect.AdjustBottom( -2 );
963 else
965 aRect.AdjustLeft(2 );
966 aRect.AdjustTop(2 );
967 aRect.AdjustRight( -3 );
968 aRect.AdjustBottom( -3 );
971 if ( bOldMap )
973 mpOutDev->EnableMapMode( bOldMap );
974 aRect = mpOutDev->PixelToLogic( aRect );
977 return aRect;
980 void DecorationView::DrawSeparator( const Point& rStart, const Point& rStop, bool bVertical )
982 Point aStart( rStart ), aStop( rStop );
983 const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
984 vcl::Window *const pWin = mpOutDev->GetOwnerWindow();
985 if(pWin)
987 ControlPart nPart = ( bVertical ? ControlPart::SeparatorVert : ControlPart::SeparatorHorz );
988 bool nativeSupported = pWin->IsNativeControlSupported( ControlType::Fixedline, nPart );
989 ImplControlValue aValue;
990 tools::Rectangle aRect(rStart,rStop);
991 if(nativeSupported && pWin->GetOutDev()->DrawNativeControl(ControlType::Fixedline,nPart,aRect,ControlState::NONE,aValue,OUString()))
992 return;
995 mpOutDev->Push( vcl::PushFlags::LINECOLOR );
996 if ( rStyleSettings.GetOptions() & StyleSettingsOptions::Mono )
997 mpOutDev->SetLineColor( COL_BLACK );
998 else
999 mpOutDev->SetLineColor( rStyleSettings.GetSeparatorColor() );
1001 mpOutDev->DrawLine( aStart, aStop );
1003 mpOutDev->Pop();
1006 void DecorationView::DrawHandle(const tools::Rectangle& rRect)
1008 const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
1010 Size aOutputSize = rRect.GetSize();
1012 mpOutDev->SetLineColor(rStyleSettings.GetDarkShadowColor());
1013 mpOutDev->SetFillColor(rStyleSettings.GetDarkShadowColor());
1015 const sal_Int32 nNumberOfPoints = 3;
1017 tools::Long nHalfWidth = aOutputSize.Width() / 2.0f;
1019 float fDistance = aOutputSize.Height();
1020 fDistance /= (nNumberOfPoints + 1);
1022 tools::Long nRadius = aOutputSize.Width();
1023 nRadius /= (nNumberOfPoints + 2);
1025 for (tools::Long i = 1; i <= nNumberOfPoints; i++)
1027 tools::Rectangle aLocation(nHalfWidth - nRadius,
1028 round(fDistance * i) - nRadius,
1029 nHalfWidth + nRadius,
1030 round(fDistance * i) + nRadius);
1031 mpOutDev->DrawEllipse(aLocation);
1035 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */