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