1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <vcl/headbar.hxx>
21 #include <tools/debug.hxx>
22
23 #include <vcl/svapp.hxx>
24 #include <vcl/help.hxx>
25 #include <vcl/image.hxx>
26 #include <vcl/salnativewidgets.hxx>
27 #include <vcl/settings.hxx>
28 #include <vcl/commandevent.hxx>
29 #include <vcl/event.hxx>
30 #include <vcl/ptrstyle.hxx>
31
32 #include <com/sun/star/accessibility/XAccessible.hpp>
33
34 class ImplHeadItem
35 {
36 public:
37 sal_uInt16 mnId;
38 HeaderBarItemBits mnBits;
39 long mnSize;
40 OString const maHelpId;
41 Image const maImage;
42 OUString maOutText;
43 OUString maText;
44 OUString maHelpText;
45 };
46
47 #define HEAD_ARROWSIZE1 4
48 #define HEAD_ARROWSIZE2 7
49
50 #define HEADERBAR_TEXTOFF 2
51 #define HEADERBAR_ARROWOFF 5
52 #define HEADERBAR_SPLITOFF 3
53
54 #define HEADERBAR_DRAGOUTOFF 15
55
56 #define HEAD_HITTEST_ITEM (sal_uInt16(0x0001))
57 #define HEAD_HITTEST_DIVIDER (sal_uInt16(0x0002))
58
ImplInit(WinBits nWinStyle)59 void HeaderBar::ImplInit( WinBits nWinStyle )
60 {
61 mnBorderOff1 = 0;
62 mnBorderOff2 = 0;
63 mnOffset = 0;
64 mnDX = 0;
65 mnDY = 0;
66 mnDragSize = 0;
67 mnStartPos = 0;
68 mnDragPos = 0;
69 mnMouseOff = 0;
70 mnCurItemId = 0;
71 mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
72 mbDrag = false;
73 mbItemDrag = false;
74 mbOutDrag = false;
75 mbItemMode = false;
76
77 // evaluate StyleBits
78 if ( nWinStyle & WB_DRAG )
79 mbDragable = true;
80 else
81 mbDragable = false;
82 if ( nWinStyle & WB_BUTTONSTYLE )
83 mbButtonStyle = true;
84 else
85 mbButtonStyle = false;
86 if ( nWinStyle & WB_BORDER )
87 {
88 mnBorderOff1 = 1;
89 mnBorderOff2 = 1;
90 }
91 else
92 {
93 if ( nWinStyle & WB_BOTTOMBORDER )
94 mnBorderOff2 = 1;
95 }
96
97 ImplInitSettings( true, true, true );
98 }
99
HeaderBar(vcl::Window * pParent,WinBits nWinStyle)100 HeaderBar::HeaderBar(vcl::Window* pParent, WinBits nWinStyle)
101 : Window(pParent, nWinStyle & WB_3DLOOK)
102 {
103 SetType(WindowType::HEADERBAR);
104 ImplInit(nWinStyle);
105 SetSizePixel( CalcWindowSizePixel() );
106 }
107
GetOptimalSize() const108 Size HeaderBar::GetOptimalSize() const
109 {
110 return CalcWindowSizePixel();
111 }
112
113 HeaderBar::~HeaderBar() = default;
114
ApplySettings(vcl::RenderContext & rRenderContext)115 void HeaderBar::ApplySettings(vcl::RenderContext& rRenderContext)
116 {
117 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
118
119 ApplyControlFont(rRenderContext, rStyleSettings.GetToolFont());
120
121 ApplyControlForeground(rRenderContext, rStyleSettings.GetButtonTextColor());
122 SetTextFillColor();
123
124 ApplyControlBackground(rRenderContext, rStyleSettings.GetFaceColor());
125 }
126
ImplInitSettings(bool bFont,bool bForeground,bool bBackground)127 void HeaderBar::ImplInitSettings(bool bFont, bool bForeground, bool bBackground)
128 {
129 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
130
131 if (bFont)
132 ApplyControlFont(*this, rStyleSettings.GetToolFont());
133
134 if (bForeground || bFont)
135 {
136 ApplyControlForeground(*this, rStyleSettings.GetButtonTextColor());
137 SetTextFillColor();
138 }
139
140 if (bBackground)
141 ApplyControlBackground(*this, rStyleSettings.GetFaceColor());
142 }
143
ImplGetItemPos(sal_uInt16 nPos) const144 long HeaderBar::ImplGetItemPos( sal_uInt16 nPos ) const
145 {
146 long nX = -mnOffset;
147 for ( size_t i = 0; i < nPos; i++ )
148 nX += mvItemList[ i ]->mnSize;
149 return nX;
150 }
151
ImplGetItemRect(sal_uInt16 nPos) const152 tools::Rectangle HeaderBar::ImplGetItemRect( sal_uInt16 nPos ) const
153 {
154 tools::Rectangle aRect( ImplGetItemPos( nPos ), 0, 0, mnDY-1 );
155 aRect.SetRight( aRect.Left() + mvItemList[ nPos ]->mnSize - 1 );
156 // check for overflow on various systems
157 if ( aRect.Right() > 16000 )
158 aRect.SetRight( 16000 );
159 return aRect;
160 }
161
ImplHitTest(const Point & rPos,long & nMouseOff,sal_uInt16 & nPos) const162 sal_uInt16 HeaderBar::ImplHitTest( const Point& rPos,
163 long& nMouseOff, sal_uInt16& nPos ) const
164 {
165 size_t nCount = static_cast<sal_uInt16>(mvItemList.size());
166 bool bLastFixed = true;
167 long nX = -mnOffset;
168
169 for ( size_t i = 0; i < nCount; i++ )
170 {
171 auto& pItem = mvItemList[ i ];
172
173 if ( rPos.X() < (nX+pItem->mnSize) )
174 {
175 sal_uInt16 nMode;
176
177 if ( !bLastFixed && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
178 {
179 nMode = HEAD_HITTEST_DIVIDER;
180 nPos = i-1;
181 nMouseOff = rPos.X()-nX+1;
182 }
183 else
184 {
185 nPos = i;
186
187 if ( rPos.X() >= (nX+pItem->mnSize-HEADERBAR_SPLITOFF) )
188 {
189 nMode = HEAD_HITTEST_DIVIDER;
190 nMouseOff = rPos.X()-(nX+pItem->mnSize);
191 }
192 else
193 {
194 nMode = HEAD_HITTEST_ITEM;
195 nMouseOff = rPos.X()-nX;
196 }
197 }
198
199 return nMode;
200 }
201
202 bLastFixed = false;
203
204 nX += pItem->mnSize;
205 }
206
207 if ( !bLastFixed )
208 {
209 auto& pItem = mvItemList[ nCount-1 ];
210 if ( (pItem->mnSize < 4) && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
211 {
212 nPos = nCount-1;
213 nMouseOff = rPos.X()-nX+1;
214 return HEAD_HITTEST_DIVIDER;
215 }
216 }
217
218 return 0;
219 }
220
ImplInvertDrag(sal_uInt16 nStartPos,sal_uInt16 nEndPos)221 void HeaderBar::ImplInvertDrag( sal_uInt16 nStartPos, sal_uInt16 nEndPos )
222 {
223 tools::Rectangle aRect1 = ImplGetItemRect( nStartPos );
224 tools::Rectangle aRect2 = ImplGetItemRect( nEndPos );
225 Point aStartPos = aRect1.Center();
226 Point aEndPos = aStartPos;
227 tools::Rectangle aStartRect( aStartPos.X()-2, aStartPos.Y()-2,
228 aStartPos.X()+2, aStartPos.Y()+2 );
229
230 if ( nEndPos > nStartPos )
231 {
232 aStartPos.AdjustX(3 );
233 aEndPos.setX( aRect2.Right()-6 );
234 }
235 else
236 {
237 aStartPos.AdjustX( -3 );
238 aEndPos.setX( aRect2.Left()+6 );
239 }
240
241 SetRasterOp( RasterOp::Invert );
242 DrawRect( aStartRect );
243 DrawLine( aStartPos, aEndPos );
244 if ( nEndPos > nStartPos )
245 {
246 DrawLine( Point( aEndPos.X()+1, aEndPos.Y()-3 ),
247 Point( aEndPos.X()+1, aEndPos.Y()+3 ) );
248 DrawLine( Point( aEndPos.X()+2, aEndPos.Y()-2 ),
249 Point( aEndPos.X()+2, aEndPos.Y()+2 ) );
250 DrawLine( Point( aEndPos.X()+3, aEndPos.Y()-1 ),
251 Point( aEndPos.X()+3, aEndPos.Y()+1 ) );
252 DrawPixel( Point( aEndPos.X()+4, aEndPos.Y() ) );
253 }
254 else
255 {
256 DrawLine( Point( aEndPos.X()-1, aEndPos.Y()-3 ),
257 Point( aEndPos.X()-1, aEndPos.Y()+3 ) );
258 DrawLine( Point( aEndPos.X()-2, aEndPos.Y()-2 ),
259 Point( aEndPos.X()-2, aEndPos.Y()+2 ) );
260 DrawLine( Point( aEndPos.X()-3, aEndPos.Y()-1 ),
261 Point( aEndPos.X()-3, aEndPos.Y()+1 ) );
262 DrawPixel( Point( aEndPos.X()-4, aEndPos.Y() ) );
263 }
264 SetRasterOp( RasterOp::OverPaint );
265 }
266
ImplDrawItem(vcl::RenderContext & rRenderContext,sal_uInt16 nPos,bool bHigh,const tools::Rectangle & rItemRect,const tools::Rectangle * pRect)267 void HeaderBar::ImplDrawItem(vcl::RenderContext& rRenderContext, sal_uInt16 nPos, bool bHigh,
268 const tools::Rectangle& rItemRect, const tools::Rectangle* pRect )
269 {
270 ImplControlValue aControlValue(0);
271 tools::Rectangle aCtrlRegion;
272 ControlState nState(ControlState::NONE);
273
274 tools::Rectangle aRect = rItemRect;
275
276 // do not display if there is no space
277 if (aRect.GetWidth() <= 1)
278 return;
279
280 // check of rectangle is visible
281 if (pRect)
282 {
283 if (aRect.Right() < pRect->Left())
284 return;
285 else if (aRect.Left() > pRect->Right())
286 return;
287 }
288 else
289 {
290 if (aRect.Right() < 0)
291 return;
292 else if (aRect.Left() > mnDX)
293 return;
294 }
295
296 auto& pItem = mvItemList[nPos];
297 HeaderBarItemBits nBits = pItem->mnBits;
298 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
299
300 if (rRenderContext.IsNativeControlSupported(ControlType::WindowBackground, ControlPart::Entire))
301 {
302 aCtrlRegion = aRect;
303 rRenderContext.DrawNativeControl(ControlType::WindowBackground, ControlPart::Entire,
304 aCtrlRegion, nState, aControlValue, OUString());
305
306 }
307 else
308 {
309 // do not draw border
310 aRect.AdjustTop(mnBorderOff1 );
311 aRect.AdjustBottom( -mnBorderOff2 );
312
313 // delete background
314 if ( !pRect )
315 {
316 rRenderContext.DrawWallpaper(aRect, rRenderContext.GetBackground());
317 }
318 }
319
320 Color aSelectionTextColor(COL_TRANSPARENT);
321
322 if (rRenderContext.IsNativeControlSupported(ControlType::ListHeader, ControlPart::Button))
323 {
324 aCtrlRegion = aRect;
325 aControlValue.setTristateVal(ButtonValue::On);
326 nState |= ControlState::ENABLED;
327 if (bHigh)
328 nState |= ControlState::PRESSED;
329 rRenderContext.DrawNativeControl(ControlType::ListHeader, ControlPart::Button,
330 aCtrlRegion, nState, aControlValue, OUString());
331 }
332 else
333 {
334 // draw separation line
335 rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
336 rRenderContext.DrawLine(Point(aRect.Right(), aRect.Top()), Point(aRect.Right(), aRect.Bottom()));
337
338 // draw ButtonStyle
339 // avoid 3D borders
340 if (bHigh)
341 vcl::RenderTools::DrawSelectionBackground(rRenderContext, *this, aRect, 1, true, false, false, &aSelectionTextColor);
342 else if (!mbButtonStyle || (nBits & HeaderBarItemBits::FLAT))
343 vcl::RenderTools::DrawSelectionBackground(rRenderContext, *this, aRect, 0, true, false, false, &aSelectionTextColor);
344 }
345
346 // do not draw if there is no space
347 if (aRect.GetWidth() < 1)
348 return;
349
350 // calculate size and position and draw content
351 pItem->maOutText = pItem->maText;
352 Size aImageSize = pItem->maImage.GetSizePixel();
353 Size aTxtSize(rRenderContext.GetTextWidth(pItem->maOutText), 0);
354 if (!pItem->maOutText.isEmpty())
355 aTxtSize.setHeight( rRenderContext.GetTextHeight() );
356 long nArrowWidth = 0;
357 if (nBits & (HeaderBarItemBits::UPARROW | HeaderBarItemBits::DOWNARROW))
358 nArrowWidth = HEAD_ARROWSIZE2 + HEADERBAR_ARROWOFF;
359
360 // do not draw if there is not enough space for the image
361 long nTestHeight = aImageSize.Height();
362 if (!(nBits & (HeaderBarItemBits::LEFTIMAGE | HeaderBarItemBits::RIGHTIMAGE)))
363 nTestHeight += aTxtSize.Height();
364 if ((aImageSize.Width() > aRect.GetWidth()) || (nTestHeight > aRect.GetHeight()))
365 {
366 aImageSize.setWidth( 0 );
367 aImageSize.setHeight( 0 );
368 }
369
370 // cut text to correct length
371 bool bLeftText = false;
372 long nMaxTxtWidth = aRect.GetWidth() - (HEADERBAR_TEXTOFF * 2) - nArrowWidth;
373 if (nBits & (HeaderBarItemBits::LEFTIMAGE | HeaderBarItemBits::RIGHTIMAGE))
374 nMaxTxtWidth -= aImageSize.Width();
375 long nTxtWidth = aTxtSize.Width();
376 if (nTxtWidth > nMaxTxtWidth)
377 {
378 bLeftText = true;
379 OUStringBuffer aBuf(pItem->maOutText);
380 aBuf.append("...");
381 do
382 {
383 aBuf.remove(aBuf.getLength() - 3 - 1, 1);
384 nTxtWidth = rRenderContext.GetTextWidth(aBuf.toString());
385 }
386 while ((nTxtWidth > nMaxTxtWidth) && (aBuf.getLength() > 3));
387 pItem->maOutText = aBuf.makeStringAndClear();
388 if (pItem->maOutText.getLength() == 3)
389 {
390 nTxtWidth = 0;
391 pItem->maOutText.clear();
392 }
393 }
394
395 // calculate text/imageposition
396 long nTxtPos;
397 if (!bLeftText && (nBits & HeaderBarItemBits::RIGHT))
398 {
399 nTxtPos = aRect.Right() - nTxtWidth - HEADERBAR_TEXTOFF;
400 if (nBits & HeaderBarItemBits::RIGHTIMAGE)
401 nTxtPos -= aImageSize.Width();
402 }
403 else if (!bLeftText && (nBits & HeaderBarItemBits::CENTER))
404 {
405 long nTempWidth = nTxtWidth;
406 if (nBits & (HeaderBarItemBits::LEFTIMAGE | HeaderBarItemBits::RIGHTIMAGE))
407 nTempWidth += aImageSize.Width();
408 nTxtPos = aRect.Left() + (aRect.GetWidth() - nTempWidth) / 2;
409 if (nBits & HeaderBarItemBits::LEFTIMAGE)
410 nTxtPos += aImageSize.Width();
411 if (nArrowWidth)
412 {
413 if (nTxtPos + nTxtWidth + nArrowWidth >= aRect.Right())
414 {
415 nTxtPos = aRect.Left() + HEADERBAR_TEXTOFF;
416 if (nBits & HeaderBarItemBits::LEFTIMAGE)
417 nTxtPos += aImageSize.Width();
418 }
419 }
420 }
421 else
422 {
423 nTxtPos = aRect.Left() + HEADERBAR_TEXTOFF;
424 if (nBits & HeaderBarItemBits::LEFTIMAGE)
425 nTxtPos += aImageSize.Width();
426 if (nBits & HeaderBarItemBits::RIGHT)
427 nTxtPos += nArrowWidth;
428 }
429
430 // calculate text/imageposition
431 long nTxtPosY = 0;
432 if (!pItem->maOutText.isEmpty() || (nArrowWidth && aTxtSize.Height()))
433 {
434 long nTempHeight = aTxtSize.Height();
435 nTempHeight += aImageSize.Height();
436 nTxtPosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
437 if (!(nBits & (HeaderBarItemBits::LEFTIMAGE | HeaderBarItemBits::RIGHTIMAGE)))
438 nTxtPosY += aImageSize.Height();
439 }
440
441 // display text
442 if (!pItem->maOutText.isEmpty())
443 {
444 if (aSelectionTextColor != COL_TRANSPARENT)
445 {
446 rRenderContext.Push(PushFlags::TEXTCOLOR);
447 rRenderContext.SetTextColor(aSelectionTextColor);
448 }
449 if (IsEnabled())
450 rRenderContext.DrawText(Point(nTxtPos, nTxtPosY), pItem->maOutText);
451 else
452 rRenderContext.DrawCtrlText(Point(nTxtPos, nTxtPosY), pItem->maOutText, 0, pItem->maOutText.getLength(), DrawTextFlags::Disable);
453 if (aSelectionTextColor != COL_TRANSPARENT)
454 rRenderContext.Pop();
455 }
456
457 // calculate the position and draw image if it is available
458 long nImagePosY = 0;
459 if (aImageSize.Width() && aImageSize.Height())
460 {
461 long nImagePos = nTxtPos;
462 if (nBits & HeaderBarItemBits::LEFTIMAGE)
463 {
464 nImagePos -= aImageSize.Width();
465 if (nBits & HeaderBarItemBits::RIGHT)
466 nImagePos -= nArrowWidth;
467 }
468 else if (nBits & HeaderBarItemBits::RIGHTIMAGE)
469 {
470 nImagePos += nTxtWidth;
471 if (!(nBits & HeaderBarItemBits::RIGHT))
472 nImagePos += nArrowWidth;
473 }
474 else
475 {
476 if (nBits & HeaderBarItemBits::RIGHT )
477 nImagePos = aRect.Right()-aImageSize.Width();
478 else if (nBits & HeaderBarItemBits::CENTER)
479 nImagePos = aRect.Left() + (aRect.GetWidth() - aImageSize.Width()) / 2;
480 else
481 nImagePos = aRect.Left() + HEADERBAR_TEXTOFF;
482 }
483
484 long nTempHeight = aImageSize.Height();
485 if (!(nBits & (HeaderBarItemBits::LEFTIMAGE | HeaderBarItemBits::RIGHTIMAGE)))
486 nTempHeight += aTxtSize.Height();
487 nImagePosY = aRect.Top() + ((aRect.GetHeight() - nTempHeight) / 2);
488
489 if (nImagePos + aImageSize.Width() <= aRect.Right())
490 {
491 DrawImageFlags nStyle = DrawImageFlags::NONE;
492 if (!IsEnabled())
493 nStyle |= DrawImageFlags::Disable;
494 rRenderContext.DrawImage(Point(nImagePos, nImagePosY), pItem->maImage, nStyle);
495 }
496 }
497
498 if (!(nBits & (HeaderBarItemBits::UPARROW | HeaderBarItemBits::DOWNARROW)))
499 return;
500
501 long nArrowX = nTxtPos;
502 if (nBits & HeaderBarItemBits::RIGHT)
503 nArrowX -= nArrowWidth;
504 else
505 nArrowX += nTxtWidth + HEADERBAR_ARROWOFF;
506 if (!(nBits & (HeaderBarItemBits::LEFTIMAGE | HeaderBarItemBits::RIGHTIMAGE)) && pItem->maText.isEmpty())
507 {
508 if (nBits & HeaderBarItemBits::RIGHT)
509 nArrowX -= aImageSize.Width();
510 else
511 nArrowX += aImageSize.Width();
512 }
513
514 // is there enough space to draw the item?
515 bool bDraw = true;
516 if (nArrowX < aRect.Left() + HEADERBAR_TEXTOFF)
517 bDraw = false;
518 else if (nArrowX + HEAD_ARROWSIZE2 > aRect.Right())
519 bDraw = false;
520
521 if (!bDraw)
522 return;
523
524 if (rRenderContext.IsNativeControlSupported(ControlType::ListHeader, ControlPart::Arrow))
525 {
526 aCtrlRegion = tools::Rectangle(Point(nArrowX, aRect.Top()), Size(nArrowWidth, aRect.GetHeight()));
527 // control value passes 1 if arrow points down, 0 otherwise
528 aControlValue.setNumericVal((nBits & HeaderBarItemBits::DOWNARROW) ? 1 : 0);
529 nState |= ControlState::ENABLED;
530 if (bHigh)
531 nState |= ControlState::PRESSED;
532 rRenderContext.DrawNativeControl(ControlType::ListHeader, ControlPart::Arrow, aCtrlRegion,
533 nState, aControlValue, OUString());
534 }
535 else
536 {
537 long nArrowY;
538 if (aTxtSize.Height())
539 nArrowY = nTxtPosY + (aTxtSize.Height() / 2);
540 else if (aImageSize.Width() && aImageSize.Height())
541 nArrowY = nImagePosY + (aImageSize.Height() / 2);
542 else
543 nArrowY = aRect.Top() + ((aRect.GetHeight() - HEAD_ARROWSIZE2) / 2);
544 nArrowY -= HEAD_ARROWSIZE1 - 1;
545 if (nBits & HeaderBarItemBits::DOWNARROW)
546 {
547 rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
548 rRenderContext.DrawLine(Point(nArrowX, nArrowY),
549 Point(nArrowX + HEAD_ARROWSIZE2, nArrowY));
550 rRenderContext.DrawLine(Point(nArrowX, nArrowY),
551 Point(nArrowX + HEAD_ARROWSIZE1, nArrowY + HEAD_ARROWSIZE2));
552 rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
553 rRenderContext.DrawLine(Point(nArrowX + HEAD_ARROWSIZE1, nArrowY + HEAD_ARROWSIZE2),
554 Point(nArrowX + HEAD_ARROWSIZE2, nArrowY));
555 }
556 else
557 {
558 rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
559 rRenderContext.DrawLine(Point(nArrowX, nArrowY + HEAD_ARROWSIZE2),
560 Point(nArrowX + HEAD_ARROWSIZE1, nArrowY));
561 rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
562 rRenderContext.DrawLine(Point(nArrowX, nArrowY + HEAD_ARROWSIZE2),
563 Point(nArrowX + HEAD_ARROWSIZE2, nArrowY + HEAD_ARROWSIZE2));
564 rRenderContext.DrawLine(Point(nArrowX + HEAD_ARROWSIZE2, nArrowY + HEAD_ARROWSIZE2),
565 Point(nArrowX + HEAD_ARROWSIZE1, nArrowY));
566 }
567 }
568 }
569
ImplDrawItem(vcl::RenderContext & rRenderContext,sal_uInt16 nPos,bool bHigh,const tools::Rectangle * pRect)570 void HeaderBar::ImplDrawItem(vcl::RenderContext& rRenderContext, sal_uInt16 nPos,
571 bool bHigh, const tools::Rectangle* pRect )
572 {
573 tools::Rectangle aRect = ImplGetItemRect(nPos);
574 ImplDrawItem(rRenderContext, nPos, bHigh, aRect, pRect );
575 }
576
ImplUpdate(sal_uInt16 nPos,bool bEnd)577 void HeaderBar::ImplUpdate(sal_uInt16 nPos, bool bEnd)
578 {
579 if (!(IsVisible() && IsUpdateMode()))
580 return;
581
582 tools::Rectangle aRect;
583 size_t nItemCount = mvItemList.size();
584 if (nPos < nItemCount)
585 aRect = ImplGetItemRect(nPos);
586 else
587 {
588 aRect.SetBottom( mnDY - 1 );
589 if (nItemCount)
590 aRect.SetLeft( ImplGetItemRect(nItemCount - 1).Right() );
591 }
592 if (bEnd)
593 aRect.SetRight( mnDX - 1 );
594 aRect.AdjustTop(mnBorderOff1 );
595 aRect.AdjustBottom( -mnBorderOff2 );
596 Invalidate(aRect);
597 }
598
ImplStartDrag(const Point & rMousePos,bool bCommand)599 void HeaderBar::ImplStartDrag( const Point& rMousePos, bool bCommand )
600 {
601 sal_uInt16 nPos;
602 sal_uInt16 nHitTest = ImplHitTest( rMousePos, mnMouseOff, nPos );
603 if ( !nHitTest )
604 return;
605
606 mbDrag = false;
607 auto& pItem = mvItemList[ nPos ];
608 if ( nHitTest & HEAD_HITTEST_DIVIDER )
609 mbDrag = true;
610 else
611 {
612 if ( ((pItem->mnBits & HeaderBarItemBits::CLICKABLE) && !(pItem->mnBits & HeaderBarItemBits::FLAT)) ||
613 mbDragable )
614 {
615 mbItemMode = true;
616 mbDrag = true;
617 if ( bCommand )
618 {
619 if ( mbDragable )
620 mbItemDrag = true;
621 else
622 {
623 mbItemMode = false;
624 mbDrag = false;
625 }
626 }
627 }
628 else
629 {
630 if ( !bCommand )
631 {
632 mnCurItemId = pItem->mnId;
633 Select();
634 mnCurItemId = 0;
635 }
636 }
637 }
638
639 if ( mbDrag )
640 {
641 mbOutDrag = false;
642 mnCurItemId = pItem->mnId;
643 mnItemDragPos = nPos;
644 StartTracking();
645 mnStartPos = rMousePos.X()-mnMouseOff;
646 mnDragPos = mnStartPos;
647 maStartDragHdl.Call( this );
648 if (mbItemMode)
649 Invalidate();
650 else
651 {
652 tools::Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
653 ShowTracking( aSizeRect, ShowTrackFlags::Split );
654 }
655 }
656 else
657 mnMouseOff = 0;
658 }
659
ImplDrag(const Point & rMousePos)660 void HeaderBar::ImplDrag( const Point& rMousePos )
661 {
662 sal_uInt16 nPos = GetItemPos( mnCurItemId );
663
664 mnDragPos = rMousePos.X()-mnMouseOff;
665 if ( mbItemMode )
666 {
667 bool bNewOutDrag;
668
669 tools::Rectangle aItemRect = ImplGetItemRect( nPos );
670 bNewOutDrag = !aItemRect.IsInside( rMousePos );
671
672 // if needed switch on ItemDrag
673 if ( bNewOutDrag && mbDragable && !mbItemDrag )
674 {
675 if ( (rMousePos.Y() >= aItemRect.Top()) && (rMousePos.Y() <= aItemRect.Bottom()) )
676 {
677 mbItemDrag = true;
678 Invalidate();
679 }
680 }
681
682 sal_uInt16 nOldItemDragPos = mnItemDragPos;
683 if ( mbItemDrag )
684 {
685 bNewOutDrag = (rMousePos.Y() < -HEADERBAR_DRAGOUTOFF) || (rMousePos.Y() > mnDY+HEADERBAR_DRAGOUTOFF);
686
687 if ( bNewOutDrag )
688 mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
689 else
690 {
691 sal_uInt16 nTempId = GetItemId( Point( rMousePos.X(), 2 ) );
692 if ( nTempId )
693 mnItemDragPos = GetItemPos( nTempId );
694 else
695 {
696 if ( rMousePos.X() <= 0 )
697 mnItemDragPos = 0;
698 else
699 mnItemDragPos = GetItemCount()-1;
700 }
701 }
702
703 if ( (mnItemDragPos != nOldItemDragPos) &&
704 (nOldItemDragPos != nPos) &&
705 (nOldItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
706 {
707 ImplInvertDrag( nPos, nOldItemDragPos );
708 Invalidate();
709 }
710 }
711
712 if ( bNewOutDrag != mbOutDrag )
713 Invalidate();
714
715 if ( mbItemDrag )
716 {
717 if ( (mnItemDragPos != nOldItemDragPos) &&
718 (mnItemDragPos != nPos) &&
719 (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
720 {
721 Invalidate();
722 ImplInvertDrag( nPos, mnItemDragPos );
723 }
724 }
725
726 mbOutDrag = bNewOutDrag;
727 }
728 else
729 {
730 tools::Rectangle aItemRect = ImplGetItemRect( nPos );
731 if ( mnDragPos < aItemRect.Left() )
732 mnDragPos = aItemRect.Left();
733 if ( (mnDragPos < 0) || (mnDragPos > mnDX-1) )
734 HideTracking();
735 else
736 {
737 tools::Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
738 ShowTracking( aSizeRect, ShowTrackFlags::Split );
739 }
740 }
741
742 maDragHdl.Call( this );
743 }
744
ImplEndDrag(bool bCancel)745 void HeaderBar::ImplEndDrag( bool bCancel )
746 {
747 HideTracking();
748
749 if ( bCancel || mbOutDrag )
750 {
751 if ( mbItemMode && (!mbOutDrag || mbItemDrag) )
752 {
753 Invalidate();
754 }
755
756 mnCurItemId = 0;
757 }
758 else
759 {
760 sal_uInt16 nPos = GetItemPos( mnCurItemId );
761 if ( mbItemMode )
762 {
763 if ( mbItemDrag )
764 {
765 SetPointer( PointerStyle::Arrow );
766 if ( (mnItemDragPos != nPos) &&
767 (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
768 {
769 ImplInvertDrag( nPos, mnItemDragPos );
770 MoveItem( mnCurItemId, mnItemDragPos );
771 }
772 else
773 Invalidate();
774 }
775 else
776 {
777 Select();
778 ImplUpdate( nPos );
779 }
780 }
781 else
782 {
783 long nDelta = mnDragPos - mnStartPos;
784 if ( nDelta )
785 {
786 auto& pItem = mvItemList[ nPos ];
787 pItem->mnSize += nDelta;
788 ImplUpdate( nPos, true );
789 }
790 }
791 }
792
793 mbDrag = false;
794 EndDrag();
795 mnCurItemId = 0;
796 mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
797 mbOutDrag = false;
798 mbItemMode = false;
799 mbItemDrag = false;
800 }
801
MouseButtonDown(const MouseEvent & rMEvt)802 void HeaderBar::MouseButtonDown( const MouseEvent& rMEvt )
803 {
804 if ( !rMEvt.IsLeft() )
805 return;
806
807 if ( rMEvt.GetClicks() == 2 )
808 {
809 long nTemp;
810 sal_uInt16 nPos;
811 sal_uInt16 nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp, nPos );
812 if ( nHitTest )
813 {
814 auto& pItem = mvItemList[ nPos ];
815 if ( nHitTest & HEAD_HITTEST_DIVIDER )
816 mbItemMode = false;
817 else
818 mbItemMode = true;
819 mnCurItemId = pItem->mnId;
820 DoubleClick();
821 mbItemMode = false;
822 mnCurItemId = 0;
823 }
824 }
825 else
826 ImplStartDrag( rMEvt.GetPosPixel(), false );
827 }
828
MouseMove(const MouseEvent & rMEvt)829 void HeaderBar::MouseMove( const MouseEvent& rMEvt )
830 {
831 long nTemp1;
832 sal_uInt16 nTemp2;
833 PointerStyle eStyle = PointerStyle::Arrow;
834 sal_uInt16 nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp1, nTemp2 );
835
836 if ( nHitTest & HEAD_HITTEST_DIVIDER )
837 eStyle = PointerStyle::HSizeBar;
838 SetPointer( eStyle );
839 }
840
Tracking(const TrackingEvent & rTEvt)841 void HeaderBar::Tracking( const TrackingEvent& rTEvt )
842 {
843 Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
844
845 if ( rTEvt.IsTrackingEnded() )
846 ImplEndDrag( rTEvt.IsTrackingCanceled() );
847 else
848 ImplDrag( aMousePos );
849 }
850
Paint(vcl::RenderContext & rRenderContext,const tools::Rectangle & rRect)851 void HeaderBar::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
852 {
853 if (mnBorderOff1 || mnBorderOff2)
854 {
855 rRenderContext.SetLineColor(rRenderContext.GetSettings().GetStyleSettings().GetDarkShadowColor());
856 if (mnBorderOff1)
857 rRenderContext.DrawLine(Point(0, 0), Point(mnDX - 1, 0));
858 if (mnBorderOff2)
859 rRenderContext.DrawLine(Point(0, mnDY - 1), Point(mnDX - 1, mnDY - 1));
860 // #i40393# draw left and right border, if WB_BORDER was set in ImplInit()
861 if (mnBorderOff1 && mnBorderOff2)
862 {
863 rRenderContext.DrawLine(Point(0, 0), Point(0, mnDY - 1));
864 rRenderContext.DrawLine(Point(mnDX - 1, 0), Point(mnDX - 1, mnDY - 1));
865 }
866 }
867
868 sal_uInt16 nCurItemPos;
869 if (mbDrag)
870 nCurItemPos = GetItemPos(mnCurItemId);
871 else
872 nCurItemPos = HEADERBAR_ITEM_NOTFOUND;
873 sal_uInt16 nItemCount = static_cast<sal_uInt16>(mvItemList.size());
874 for (sal_uInt16 i = 0; i < nItemCount; i++)
875 ImplDrawItem(rRenderContext, i, (i == nCurItemPos), &rRect);
876 }
877
Draw(OutputDevice * pDev,const Point & rPos,const Size & rSize,DrawFlags nFlags)878 void HeaderBar::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
879 DrawFlags nFlags )
880 {
881 Point aPos = pDev->LogicToPixel( rPos );
882 Size aSize = pDev->LogicToPixel( rSize );
883 tools::Rectangle aRect( aPos, aSize );
884 vcl::Font aFont = GetDrawPixelFont( pDev );
885
886 pDev->Push();
887 pDev->SetMapMode();
888 pDev->SetFont( aFont );
889 if ( nFlags & DrawFlags::Mono )
890 pDev->SetTextColor( COL_BLACK );
891 else
892 pDev->SetTextColor( GetTextColor() );
893 pDev->SetTextFillColor();
894
895 // draw background
896 {
897 pDev->DrawWallpaper( aRect, GetBackground() );
898 if ( mnBorderOff1 || mnBorderOff2 )
899 {
900 pDev->SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
901 if ( mnBorderOff1 )
902 pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) );
903 if ( mnBorderOff2 )
904 pDev->DrawLine( Point( aRect.Left(), aRect.Bottom() ), Point( aRect.Right(), aRect.Bottom() ) );
905 // #i40393# draw left and right border, if WB_BORDER was set in ImplInit()
906 if ( mnBorderOff1 && mnBorderOff2 )
907 {
908 pDev->DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() ) );
909 pDev->DrawLine( Point( aRect.Right(), aRect.Top() ), Point( aRect.Right(), aRect.Bottom() ) );
910 }
911 }
912 }
913
914 tools::Rectangle aItemRect( aRect );
915 size_t nItemCount = mvItemList.size();
916 for ( size_t i = 0; i < nItemCount; i++ )
917 {
918 aItemRect.SetLeft( aRect.Left()+ImplGetItemPos( i ) );
919 aItemRect.SetRight( aItemRect.Left() + mvItemList[ i ]->mnSize - 1 );
920 // check for overflow on some systems
921 if ( aItemRect.Right() > 16000 )
922 aItemRect.SetRight( 16000 );
923 vcl::Region aRegion( aRect );
924 pDev->SetClipRegion( aRegion );
925 ImplDrawItem(*pDev, i, false, aItemRect, &aRect );
926 pDev->SetClipRegion();
927 }
928
929 pDev->Pop();
930 }
931
Resize()932 void HeaderBar::Resize()
933 {
934 Size aSize = GetOutputSizePixel();
935 if ( IsVisible() && (mnDY != aSize.Height()) )
936 Invalidate();
937 mnDX = aSize.Width();
938 mnDY = aSize.Height();
939 }
940
Command(const CommandEvent & rCEvt)941 void HeaderBar::Command( const CommandEvent& rCEvt )
942 {
943 if ( rCEvt.IsMouseEvent() && (rCEvt.GetCommand() == CommandEventId::StartDrag) && !mbDrag )
944 {
945 ImplStartDrag( rCEvt.GetMousePosPixel(), true );
946 return;
947 }
948
949 Window::Command( rCEvt );
950 }
951
RequestHelp(const HelpEvent & rHEvt)952 void HeaderBar::RequestHelp( const HelpEvent& rHEvt )
953 {
954 sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
955 if ( nItemId )
956 {
957 if ( rHEvt.GetMode() & (HelpEventMode::QUICK | HelpEventMode::BALLOON) )
958 {
959 tools::Rectangle aItemRect = GetItemRect( nItemId );
960 Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
961 aItemRect.SetLeft( aPt.X() );
962 aItemRect.SetTop( aPt.Y() );
963 aPt = OutputToScreenPixel( aItemRect.BottomRight() );
964 aItemRect.SetRight( aPt.X() );
965 aItemRect.SetBottom( aPt.Y() );
966
967 OUString aStr = GetHelpText( nItemId );
968 if ( aStr.isEmpty() || !(rHEvt.GetMode() & HelpEventMode::BALLOON) )
969 {
970 auto& pItem = mvItemList[ GetItemPos( nItemId ) ];
971 // Quick-help is only displayed if the text is not fully visible.
972 // Otherwise we display Helptext only if the items do not contain text
973 if ( pItem->maOutText != pItem->maText )
974 aStr = pItem->maText;
975 else if (!pItem->maText.isEmpty())
976 aStr.clear();
977 }
978
979 if (!aStr.isEmpty())
980 {
981 if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
982 Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
983 else
984 Help::ShowQuickHelp( this, aItemRect, aStr );
985 return;
986 }
987 }
988 }
989
990 Window::RequestHelp( rHEvt );
991 }
992
StateChanged(StateChangedType nType)993 void HeaderBar::StateChanged( StateChangedType nType )
994 {
995 Window::StateChanged( nType );
996
997 if ( nType == StateChangedType::Enable )
998 Invalidate();
999 else if ( (nType == StateChangedType::Zoom) ||
1000 (nType == StateChangedType::ControlFont) )
1001 {
1002 ImplInitSettings( true, false, false );
1003 Invalidate();
1004 }
1005 else if ( nType == StateChangedType::ControlForeground )
1006 {
1007 ImplInitSettings( false, true, false );
1008 Invalidate();
1009 }
1010 else if ( nType == StateChangedType::ControlBackground )
1011 {
1012 ImplInitSettings( false, false, true );
1013 Invalidate();
1014 }
1015 }
1016
DataChanged(const DataChangedEvent & rDCEvt)1017 void HeaderBar::DataChanged( const DataChangedEvent& rDCEvt )
1018 {
1019 Window::DataChanged( rDCEvt );
1020
1021 if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
1022 (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
1023 ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1024 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
1025 {
1026 ImplInitSettings( true, true, true );
1027 Invalidate();
1028 }
1029 }
1030
EndDrag()1031 void HeaderBar::EndDrag()
1032 {
1033 maEndDragHdl.Call( this );
1034 }
1035
Select()1036 void HeaderBar::Select()
1037 {
1038 maSelectHdl.Call( this );
1039 }
1040
DoubleClick()1041 void HeaderBar::DoubleClick()
1042 {
1043 }
1044
InsertItem(sal_uInt16 nItemId,const OUString & rText,long nSize,HeaderBarItemBits nBits,sal_uInt16 nPos)1045 void HeaderBar::InsertItem( sal_uInt16 nItemId, const OUString& rText,
1046 long nSize, HeaderBarItemBits nBits, sal_uInt16 nPos )
1047 {
1048 DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
1049 DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
1050 "HeaderBar::InsertItem(): ItemId already exists" );
1051
1052 // create item and insert in the list
1053 std::unique_ptr<ImplHeadItem> pItem(new ImplHeadItem);
1054 pItem->mnId = nItemId;
1055 pItem->mnBits = nBits;
1056 pItem->mnSize = nSize;
1057 pItem->maText = rText;
1058 if ( nPos < mvItemList.size() ) {
1059 auto it = mvItemList.begin();
1060 it += nPos;
1061 mvItemList.insert( it, std::move(pItem) );
1062 } else {
1063 mvItemList.push_back( std::move(pItem) );
1064 }
1065
1066 // update display
1067 ImplUpdate( nPos, true );
1068 }
1069
RemoveItem(sal_uInt16 nItemId)1070 void HeaderBar::RemoveItem( sal_uInt16 nItemId )
1071 {
1072 sal_uInt16 nPos = GetItemPos( nItemId );
1073 if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1074 {
1075 if ( nPos < mvItemList.size() ) {
1076 auto it = mvItemList.begin();
1077 it += nPos;
1078 mvItemList.erase( it );
1079 }
1080 }
1081 }
1082
MoveItem(sal_uInt16 nItemId,sal_uInt16 nNewPos)1083 void HeaderBar::MoveItem( sal_uInt16 nItemId, sal_uInt16 nNewPos )
1084 {
1085 sal_uInt16 nPos = GetItemPos( nItemId );
1086 if ( nPos == HEADERBAR_ITEM_NOTFOUND )
1087 return;
1088
1089 if ( nPos == nNewPos )
1090 return;
1091
1092 auto it = mvItemList.begin();
1093 it += nPos;
1094 std::unique_ptr<ImplHeadItem> pItem = std::move(*it);
1095 mvItemList.erase( it );
1096 if ( nNewPos < nPos )
1097 nPos = nNewPos;
1098 it = mvItemList.begin();
1099 it += nNewPos;
1100 mvItemList.insert( it, std::move(pItem) );
1101 ImplUpdate( nPos, true);
1102 }
1103
Clear()1104 void HeaderBar::Clear()
1105 {
1106 // delete all items
1107 mvItemList.clear();
1108
1109 ImplUpdate( 0, true );
1110 }
1111
SetOffset(long nNewOffset)1112 void HeaderBar::SetOffset( long nNewOffset )
1113 {
1114 // move area
1115 tools::Rectangle aRect( 0, mnBorderOff1, mnDX-1, mnDY-mnBorderOff1-mnBorderOff2-1 );
1116 long nDelta = mnOffset-nNewOffset;
1117 mnOffset = nNewOffset;
1118 Scroll( nDelta, 0, aRect );
1119 }
1120
GetItemCount() const1121 sal_uInt16 HeaderBar::GetItemCount() const
1122 {
1123 return static_cast<sal_uInt16>(mvItemList.size());
1124 }
1125
GetItemPos(sal_uInt16 nItemId) const1126 sal_uInt16 HeaderBar::GetItemPos( sal_uInt16 nItemId ) const
1127 {
1128 for ( size_t i = 0, n = mvItemList.size(); i < n; ++i ) {
1129 auto& pItem = mvItemList[ i ];
1130 if ( pItem->mnId == nItemId )
1131 return static_cast<sal_uInt16>(i);
1132 }
1133 return HEADERBAR_ITEM_NOTFOUND;
1134 }
1135
GetItemId(sal_uInt16 nPos) const1136 sal_uInt16 HeaderBar::GetItemId( sal_uInt16 nPos ) const
1137 {
1138 ImplHeadItem* pItem = (nPos < mvItemList.size() ) ? mvItemList[ nPos ].get() : nullptr;
1139 if ( pItem )
1140 return pItem->mnId;
1141 else
1142 return 0;
1143 }
1144
GetItemId(const Point & rPos) const1145 sal_uInt16 HeaderBar::GetItemId( const Point& rPos ) const
1146 {
1147 for ( size_t i = 0, n = mvItemList.size(); i < n; ++i ) {
1148 if ( ImplGetItemRect( i ).IsInside( rPos ) ) {
1149 return GetItemId( i );
1150 }
1151 }
1152 return 0;
1153 }
1154
GetItemRect(sal_uInt16 nItemId) const1155 tools::Rectangle HeaderBar::GetItemRect( sal_uInt16 nItemId ) const
1156 {
1157 tools::Rectangle aRect;
1158 sal_uInt16 nPos = GetItemPos( nItemId );
1159 if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1160 aRect = ImplGetItemRect( nPos );
1161 return aRect;
1162 }
1163
SetItemSize(sal_uInt16 nItemId,long nNewSize)1164 void HeaderBar::SetItemSize( sal_uInt16 nItemId, long nNewSize )
1165 {
1166 sal_uInt16 nPos = GetItemPos( nItemId );
1167 if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1168 {
1169 auto& pItem = mvItemList[ nPos ];
1170 if ( pItem->mnSize != nNewSize )
1171 {
1172 pItem->mnSize = nNewSize;
1173 ImplUpdate( nPos, true );
1174 }
1175 }
1176 }
1177
GetItemSize(sal_uInt16 nItemId) const1178 long HeaderBar::GetItemSize( sal_uInt16 nItemId ) const
1179 {
1180 sal_uInt16 nPos = GetItemPos( nItemId );
1181 if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1182 return mvItemList[ nPos ]->mnSize;
1183 else
1184 return 0;
1185 }
1186
SetItemBits(sal_uInt16 nItemId,HeaderBarItemBits nNewBits)1187 void HeaderBar::SetItemBits( sal_uInt16 nItemId, HeaderBarItemBits nNewBits )
1188 {
1189 sal_uInt16 nPos = GetItemPos( nItemId );
1190 if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1191 {
1192 auto& pItem = mvItemList[ nPos ];
1193 if ( pItem->mnBits != nNewBits )
1194 {
1195 pItem->mnBits = nNewBits;
1196 ImplUpdate( nPos );
1197 }
1198 }
1199 }
1200
GetItemBits(sal_uInt16 nItemId) const1201 HeaderBarItemBits HeaderBar::GetItemBits( sal_uInt16 nItemId ) const
1202 {
1203 sal_uInt16 nPos = GetItemPos( nItemId );
1204 if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1205 return mvItemList[ nPos ]->mnBits;
1206 else
1207 return HeaderBarItemBits::NONE;
1208 }
1209
SetItemText(sal_uInt16 nItemId,const OUString & rText)1210 void HeaderBar::SetItemText( sal_uInt16 nItemId, const OUString& rText )
1211 {
1212 sal_uInt16 nPos = GetItemPos( nItemId );
1213 if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1214 {
1215 mvItemList[ nPos ]->maText = rText;
1216 ImplUpdate( nPos );
1217 }
1218 }
1219
GetItemText(sal_uInt16 nItemId) const1220 OUString HeaderBar::GetItemText( sal_uInt16 nItemId ) const
1221 {
1222 sal_uInt16 nPos = GetItemPos( nItemId );
1223 if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1224 return mvItemList[ nPos ]->maText;
1225 return OUString();
1226 }
1227
GetHelpText(sal_uInt16 nItemId) const1228 OUString HeaderBar::GetHelpText( sal_uInt16 nItemId ) const
1229 {
1230 sal_uInt16 nPos = GetItemPos( nItemId );
1231 if ( nPos != HEADERBAR_ITEM_NOTFOUND )
1232 {
1233 auto& pItem = mvItemList[ nPos ];
1234 if ( pItem->maHelpText.isEmpty() && !pItem->maHelpId.isEmpty() )
1235 {
1236 Help* pHelp = Application::GetHelp();
1237 if ( pHelp )
1238 pItem->maHelpText = pHelp->GetHelpText( OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
1239 }
1240
1241 return pItem->maHelpText;
1242 }
1243
1244 return OUString();
1245 }
1246
CalcWindowSizePixel() const1247 Size HeaderBar::CalcWindowSizePixel() const
1248 {
1249 long nMaxImageSize = 0;
1250 Size aSize( 0, GetTextHeight() );
1251
1252 for (auto& pItem : mvItemList)
1253 {
1254 // take image size into account
1255 long nImageHeight = pItem->maImage.GetSizePixel().Height();
1256 if ( !(pItem->mnBits & (HeaderBarItemBits::LEFTIMAGE | HeaderBarItemBits::RIGHTIMAGE)) && !pItem->maText.isEmpty() )
1257 nImageHeight += aSize.Height();
1258 if ( nImageHeight > nMaxImageSize )
1259 nMaxImageSize = nImageHeight;
1260
1261 // add width
1262 aSize.AdjustWidth(pItem->mnSize );
1263 }
1264
1265 if ( nMaxImageSize > aSize.Height() )
1266 aSize.setHeight( nMaxImageSize );
1267
1268 // add border
1269 if ( mbButtonStyle )
1270 aSize.AdjustHeight(4 );
1271 else
1272 aSize.AdjustHeight(2 );
1273 aSize.AdjustHeight(mnBorderOff1+mnBorderOff2 );
1274
1275 return aSize;
1276 }
1277
CreateAccessible()1278 css::uno::Reference< css::accessibility::XAccessible > HeaderBar::CreateAccessible()
1279 {
1280 if ( !mxAccessible.is() )
1281 {
1282 maCreateAccessibleHdl.Call( this );
1283
1284 if ( !mxAccessible.is() )
1285 mxAccessible = Window::CreateAccessible();
1286 }
1287
1288 return mxAccessible;
1289 }
1290
SetAccessible(const css::uno::Reference<css::accessibility::XAccessible> & _xAccessible)1291 void HeaderBar::SetAccessible( const css::uno::Reference< css::accessibility::XAccessible >& _xAccessible )
1292 {
1293 mxAccessible = _xAccessible;
1294 }
1295
1296 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1297