xref: /trunk/main/vcl/source/window/brdwin.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <svids.hrc>
32 #include <svdata.hxx>
33 #include <brdwin.hxx>
34 #include <window.h>
35 
36 #include <vcl/event.hxx>
37 #include <vcl/decoview.hxx>
38 #include <vcl/syswin.hxx>
39 #include <vcl/dockwin.hxx>
40 #include <vcl/floatwin.hxx>
41 #include <vcl/bitmap.hxx>
42 #include <vcl/gradient.hxx>
43 #include <vcl/image.hxx>
44 #include <vcl/virdev.hxx>
45 #include <vcl/help.hxx>
46 #include <vcl/edit.hxx>
47 #include <vcl/metric.hxx>
48 
49 #include <tools/debug.hxx>
50 
51 using namespace ::com::sun::star::uno;
52 
53 // useful caption height for title bar buttons
54 #define MIN_CAPTION_HEIGHT 18
55 
56 // =======================================================================
57 
58 static void ImplGetPinImage( sal_uInt16 nStyle, sal_Bool bPinIn, Image& rImage )
59 {
60     // ImageListe laden, wenn noch nicht vorhanden
61     ImplSVData* pSVData = ImplGetSVData();
62     if ( !pSVData->maCtrlData.mpPinImgList )
63     {
64         ResMgr* pResMgr = ImplGetResMgr();
65         pSVData->maCtrlData.mpPinImgList = new ImageList();
66         if( pResMgr )
67         {
68             Color aMaskColor( 0x00, 0x00, 0xFF );
69             pSVData->maCtrlData.mpPinImgList->InsertFromHorizontalBitmap
70                 ( ResId( SV_RESID_BITMAP_PIN, *pResMgr ), 4,
71                   &aMaskColor, NULL, NULL, 0);
72         }
73     }
74 
75     // Image ermitteln und zurueckgeben
76     sal_uInt16 nId;
77     if ( nStyle & BUTTON_DRAW_PRESSED )
78     {
79         if ( bPinIn )
80             nId = 4;
81         else
82             nId = 3;
83     }
84     else
85     {
86         if ( bPinIn )
87             nId = 2;
88         else
89             nId = 1;
90     }
91     rImage = pSVData->maCtrlData.mpPinImgList->GetImage( nId );
92 }
93 
94 // -----------------------------------------------------------------------
95 
96 void Window::ImplCalcSymbolRect( Rectangle& rRect )
97 {
98     // Den Rand den der Button in der nicht Default-Darstellung freilaesst,
99     // dazuaddieren, da wir diesen bei kleinen Buttons mit ausnutzen wollen
100     rRect.Left()--;
101     rRect.Top()--;
102     rRect.Right()++;
103     rRect.Bottom()++;
104 
105     // Zwischen dem Symbol und dem Button-Rand lassen wir 5% Platz
106     long nExtraWidth = ((rRect.GetWidth()*50)+500)/1000;
107     long nExtraHeight = ((rRect.GetHeight()*50)+500)/1000;
108     rRect.Left()    += nExtraWidth;
109     rRect.Right()   -= nExtraWidth;
110     rRect.Top()     += nExtraHeight;
111     rRect.Bottom()  -= nExtraHeight;
112 }
113 
114 // -----------------------------------------------------------------------
115 
116 static void ImplDrawBrdWinSymbol( OutputDevice* pDev,
117                                   const Rectangle& rRect, SymbolType eSymbol )
118 {
119     // Zwischen dem Symbol und dem Button lassen wir 5% Platz
120     DecorationView  aDecoView( pDev );
121     Rectangle       aTempRect = rRect;
122     Window::ImplCalcSymbolRect( aTempRect );
123     aDecoView.DrawSymbol( aTempRect, eSymbol,
124                           pDev->GetSettings().GetStyleSettings().GetButtonTextColor(), 0 );
125 }
126 
127 // -----------------------------------------------------------------------
128 
129 static void ImplDrawBrdWinSymbolButton( OutputDevice* pDev,
130                                         const Rectangle& rRect,
131                                         SymbolType eSymbol, sal_uInt16 nState )
132 {
133     sal_Bool bMouseOver = (nState & BUTTON_DRAW_HIGHLIGHT) != 0;
134     nState &= ~BUTTON_DRAW_HIGHLIGHT;
135 
136     Rectangle aTempRect;
137     Window *pWin = dynamic_cast< Window* >(pDev);
138     if( pWin )
139     {
140         if( bMouseOver )
141         {
142             // provide a bright background for selection effect
143             pWin->SetFillColor( pDev->GetSettings().GetStyleSettings().GetWindowColor() );
144             pWin->SetLineColor();
145             pWin->DrawRect( rRect );
146             pWin->DrawSelectionBackground( rRect, 2, (nState & BUTTON_DRAW_PRESSED) ? sal_True : sal_False,
147                                             sal_True, sal_False );
148         }
149         aTempRect = rRect;
150         aTempRect.nLeft+=3;
151         aTempRect.nRight-=4;
152         aTempRect.nTop+=3;
153         aTempRect.nBottom-=4;
154     }
155     else
156     {
157         DecorationView aDecoView( pDev );
158         aTempRect = aDecoView.DrawButton( rRect, nState|BUTTON_DRAW_FLAT );
159     }
160     ImplDrawBrdWinSymbol( pDev, aTempRect, eSymbol );
161 }
162 
163 
164 // =======================================================================
165 
166 // ------------------------
167 // - ImplBorderWindowView -
168 // ------------------------
169 
170 ImplBorderWindowView::~ImplBorderWindowView()
171 {
172 }
173 
174 // -----------------------------------------------------------------------
175 
176 sal_Bool ImplBorderWindowView::MouseMove( const MouseEvent& )
177 {
178     return sal_False;
179 }
180 
181 // -----------------------------------------------------------------------
182 
183 sal_Bool ImplBorderWindowView::MouseButtonDown( const MouseEvent& )
184 {
185     return sal_False;
186 }
187 
188 // -----------------------------------------------------------------------
189 
190 sal_Bool ImplBorderWindowView::Tracking( const TrackingEvent& )
191 {
192     return sal_False;
193 }
194 
195 // -----------------------------------------------------------------------
196 
197 String ImplBorderWindowView::RequestHelp( const Point&, Rectangle& )
198 {
199     return String();
200 }
201 
202 // -----------------------------------------------------------------------
203 
204 Rectangle ImplBorderWindowView::GetMenuRect() const
205 {
206     return Rectangle();
207 }
208 
209 // -----------------------------------------------------------------------
210 
211 void ImplBorderWindowView::ImplInitTitle( ImplBorderFrameData* pData )
212 {
213     ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
214 
215     if ( !(pBorderWindow->GetStyle() & WB_MOVEABLE) ||
216           (pData->mnTitleType == BORDERWINDOW_TITLE_NONE) )
217     {
218         pData->mnTitleType   = BORDERWINDOW_TITLE_NONE;
219         pData->mnTitleHeight = 0;
220     }
221     else
222     {
223         const StyleSettings& rStyleSettings = pData->mpOutDev->GetSettings().GetStyleSettings();
224         if ( pData->mnTitleType == BORDERWINDOW_TITLE_TEAROFF )
225             pData->mnTitleHeight = rStyleSettings.GetTearOffTitleHeight();
226         else
227         {
228             if ( pData->mnTitleType == BORDERWINDOW_TITLE_SMALL )
229             {
230                 pBorderWindow->SetPointFont( rStyleSettings.GetFloatTitleFont() );
231                 pData->mnTitleHeight = rStyleSettings.GetFloatTitleHeight();
232             }
233             else // pData->mnTitleType == BORDERWINDOW_TITLE_NORMAL
234             {
235                 pBorderWindow->SetPointFont( rStyleSettings.GetTitleFont() );
236                 pData->mnTitleHeight = rStyleSettings.GetTitleHeight();
237             }
238             long nTextHeight = pBorderWindow->GetTextHeight();
239             if ( nTextHeight > pData->mnTitleHeight )
240                 pData->mnTitleHeight = nTextHeight;
241         }
242     }
243 }
244 
245 // -----------------------------------------------------------------------
246 
247 sal_uInt16 ImplBorderWindowView::ImplHitTest( ImplBorderFrameData* pData, const Point& rPos )
248 {
249     ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
250 
251     if ( pData->maTitleRect.IsInside( rPos ) )
252     {
253         if ( pData->maCloseRect.IsInside( rPos ) )
254             return BORDERWINDOW_HITTEST_CLOSE;
255         else if ( pData->maRollRect.IsInside( rPos ) )
256             return BORDERWINDOW_HITTEST_ROLL;
257         else if ( pData->maMenuRect.IsInside( rPos ) )
258             return BORDERWINDOW_HITTEST_MENU;
259         else if ( pData->maDockRect.IsInside( rPos ) )
260             return BORDERWINDOW_HITTEST_DOCK;
261         else if ( pData->maHideRect.IsInside( rPos ) )
262             return BORDERWINDOW_HITTEST_HIDE;
263         else if ( pData->maHelpRect.IsInside( rPos ) )
264             return BORDERWINDOW_HITTEST_HELP;
265         else if ( pData->maPinRect.IsInside( rPos ) )
266             return BORDERWINDOW_HITTEST_PIN;
267         else
268             return BORDERWINDOW_HITTEST_TITLE;
269     }
270 
271     if ( (pBorderWindow->GetStyle() & WB_SIZEABLE) &&
272          !pBorderWindow->mbRollUp )
273     {
274         long nSizeWidth = pData->mnNoTitleTop+pData->mnTitleHeight;
275         if ( nSizeWidth < 16 )
276             nSizeWidth = 16;
277 
278         // no corner resize for floating toolbars, which would lead to jumps while formatting
279         // setting nSizeWidth = 0 will only return pure left,top,right,bottom
280         if( pBorderWindow->GetStyle() & WB_OWNERDRAWDECORATION )
281             nSizeWidth = 0;
282 
283         if ( rPos.X() < pData->mnLeftBorder )
284         {
285             if ( rPos.Y() < nSizeWidth )
286                 return BORDERWINDOW_HITTEST_TOPLEFT;
287             else if ( rPos.Y() >= pData->mnHeight-nSizeWidth )
288                 return BORDERWINDOW_HITTEST_BOTTOMLEFT;
289             else
290                 return BORDERWINDOW_HITTEST_LEFT;
291         }
292         else if ( rPos.X() >= pData->mnWidth-pData->mnRightBorder )
293         {
294             if ( rPos.Y() < nSizeWidth )
295                 return BORDERWINDOW_HITTEST_TOPRIGHT;
296             else if ( rPos.Y() >= pData->mnHeight-nSizeWidth )
297                 return BORDERWINDOW_HITTEST_BOTTOMRIGHT;
298             else
299                 return BORDERWINDOW_HITTEST_RIGHT;
300         }
301         else if ( rPos.Y() < pData->mnNoTitleTop )
302         {
303             if ( rPos.X() < nSizeWidth )
304                 return BORDERWINDOW_HITTEST_TOPLEFT;
305             else if ( rPos.X() >= pData->mnWidth-nSizeWidth )
306                 return BORDERWINDOW_HITTEST_TOPRIGHT;
307             else
308                 return BORDERWINDOW_HITTEST_TOP;
309         }
310         else if ( rPos.Y() >= pData->mnHeight-pData->mnBottomBorder )
311         {
312             if ( rPos.X() < nSizeWidth )
313                 return BORDERWINDOW_HITTEST_BOTTOMLEFT;
314             else if ( rPos.X() >= pData->mnWidth-nSizeWidth )
315                 return BORDERWINDOW_HITTEST_BOTTOMRIGHT;
316             else
317                 return BORDERWINDOW_HITTEST_BOTTOM;
318         }
319     }
320 
321     return 0;
322 }
323 
324 // -----------------------------------------------------------------------
325 
326 sal_Bool ImplBorderWindowView::ImplMouseMove( ImplBorderFrameData* pData, const MouseEvent& rMEvt )
327 {
328     sal_uInt16 oldCloseState = pData->mnCloseState;
329     sal_uInt16 oldMenuState = pData->mnMenuState;
330     pData->mnCloseState &= ~BUTTON_DRAW_HIGHLIGHT;
331     pData->mnMenuState &= ~BUTTON_DRAW_HIGHLIGHT;
332 
333     Point aMousePos = rMEvt.GetPosPixel();
334     sal_uInt16 nHitTest = ImplHitTest( pData, aMousePos );
335     PointerStyle ePtrStyle = POINTER_ARROW;
336     if ( nHitTest & BORDERWINDOW_HITTEST_LEFT )
337         ePtrStyle = POINTER_WINDOW_WSIZE;
338     else if ( nHitTest & BORDERWINDOW_HITTEST_RIGHT )
339         ePtrStyle = POINTER_WINDOW_ESIZE;
340     else if ( nHitTest & BORDERWINDOW_HITTEST_TOP )
341         ePtrStyle = POINTER_WINDOW_NSIZE;
342     else if ( nHitTest & BORDERWINDOW_HITTEST_BOTTOM )
343         ePtrStyle = POINTER_WINDOW_SSIZE;
344     else if ( nHitTest & BORDERWINDOW_HITTEST_TOPLEFT )
345         ePtrStyle = POINTER_WINDOW_NWSIZE;
346     else if ( nHitTest & BORDERWINDOW_HITTEST_BOTTOMRIGHT )
347         ePtrStyle = POINTER_WINDOW_SESIZE;
348     else if ( nHitTest & BORDERWINDOW_HITTEST_TOPRIGHT )
349         ePtrStyle = POINTER_WINDOW_NESIZE;
350     else if ( nHitTest & BORDERWINDOW_HITTEST_BOTTOMLEFT )
351         ePtrStyle = POINTER_WINDOW_SWSIZE;
352     else if ( nHitTest & BORDERWINDOW_HITTEST_CLOSE )
353         pData->mnCloseState |= BUTTON_DRAW_HIGHLIGHT;
354     else if ( nHitTest & BORDERWINDOW_HITTEST_MENU )
355         pData->mnMenuState |= BUTTON_DRAW_HIGHLIGHT;
356     pData->mpBorderWindow->SetPointer( Pointer( ePtrStyle ) );
357 
358     if( pData->mnCloseState != oldCloseState )
359         pData->mpBorderWindow->Invalidate( pData->maCloseRect );
360     if( pData->mnMenuState != oldMenuState )
361         pData->mpBorderWindow->Invalidate( pData->maMenuRect );
362 
363     return sal_True;
364 }
365 
366 // -----------------------------------------------------------------------
367 
368 sal_Bool ImplBorderWindowView::ImplMouseButtonDown( ImplBorderFrameData* pData, const MouseEvent& rMEvt )
369 {
370     ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
371 
372     if ( rMEvt.IsLeft() || rMEvt.IsRight() )
373     {
374         pData->maMouseOff = rMEvt.GetPosPixel();
375         pData->mnHitTest = ImplHitTest( pData, pData->maMouseOff );
376         sal_uInt16 nDragFullTest = 0;
377         if ( pData->mnHitTest )
378         {
379             sal_Bool bTracking = sal_True;
380             sal_Bool bHitTest = sal_True;
381 
382             if ( pData->mnHitTest & BORDERWINDOW_HITTEST_CLOSE )
383             {
384                 pData->mnCloseState |= BUTTON_DRAW_PRESSED;
385                 DrawWindow( BORDERWINDOW_DRAW_CLOSE );
386             }
387             else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_ROLL )
388             {
389                 pData->mnRollState |= BUTTON_DRAW_PRESSED;
390                 DrawWindow( BORDERWINDOW_DRAW_ROLL );
391             }
392             else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_DOCK )
393             {
394                 pData->mnDockState |= BUTTON_DRAW_PRESSED;
395                 DrawWindow( BORDERWINDOW_DRAW_DOCK );
396             }
397             else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_MENU )
398             {
399                 pData->mnMenuState |= BUTTON_DRAW_PRESSED;
400                 DrawWindow( BORDERWINDOW_DRAW_MENU );
401 
402                 // call handler already on mouse down
403                 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
404                 {
405                     SystemWindow* pClientWindow = (SystemWindow*)(pBorderWindow->ImplGetClientWindow());
406                     pClientWindow->TitleButtonClick( TITLE_BUTTON_MENU );
407                 }
408             }
409             else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_HIDE )
410             {
411                 pData->mnHideState |= BUTTON_DRAW_PRESSED;
412                 DrawWindow( BORDERWINDOW_DRAW_HIDE );
413             }
414             else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_HELP )
415             {
416                 pData->mnHelpState |= BUTTON_DRAW_PRESSED;
417                 DrawWindow( BORDERWINDOW_DRAW_HELP );
418             }
419             else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_PIN )
420             {
421                 pData->mnPinState |= BUTTON_DRAW_PRESSED;
422                 DrawWindow( BORDERWINDOW_DRAW_PIN );
423             }
424             else
425             {
426                 if ( rMEvt.GetClicks() == 1 )
427                 {
428                     if ( bTracking )
429                     {
430                         Point   aPos         = pBorderWindow->GetPosPixel();
431                         Size    aSize        = pBorderWindow->GetOutputSizePixel();
432                         pData->mnTrackX      = aPos.X();
433                         pData->mnTrackY      = aPos.Y();
434                         pData->mnTrackWidth  = aSize.Width();
435                         pData->mnTrackHeight = aSize.Height();
436 
437                         if ( pData->mnHitTest & BORDERWINDOW_HITTEST_TITLE )
438                             nDragFullTest = DRAGFULL_OPTION_WINDOWMOVE;
439                         else
440                             nDragFullTest = DRAGFULL_OPTION_WINDOWSIZE;
441                     }
442                 }
443                 else
444                 {
445                     bTracking = sal_False;
446 
447                     if ( (pData->mnHitTest & BORDERWINDOW_DRAW_TITLE) &&
448                          ((rMEvt.GetClicks() % 2) == 0) )
449                     {
450                         pData->mnHitTest = 0;
451                         bHitTest = sal_False;
452 
453                         if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
454                         {
455                             SystemWindow* pClientWindow = (SystemWindow*)(pBorderWindow->ImplGetClientWindow());
456                             if ( sal_True /*pBorderWindow->mbDockBtn*/ )   // always perform docking on double click, no button required
457                                 pClientWindow->TitleButtonClick( TITLE_BUTTON_DOCKING );
458                             else if ( pBorderWindow->GetStyle() & WB_ROLLABLE )
459                             {
460                                 if ( pClientWindow->IsRollUp() )
461                                     pClientWindow->RollDown();
462                                 else
463                                     pClientWindow->RollUp();
464                                 pClientWindow->Roll();
465                             }
466                         }
467                     }
468                 }
469             }
470 
471             if ( bTracking )
472             {
473                 pData->mbDragFull = sal_False;
474                 if ( nDragFullTest )
475                     pData->mbDragFull = sal_True;   // always fulldrag for proper docking, ignore system settings
476                 pBorderWindow->StartTracking();
477             }
478             else if ( bHitTest )
479                 pData->mnHitTest = 0;
480         }
481     }
482 
483     return sal_True;
484 }
485 
486 // -----------------------------------------------------------------------
487 
488 sal_Bool ImplBorderWindowView::ImplTracking( ImplBorderFrameData* pData, const TrackingEvent& rTEvt )
489 {
490     ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
491 
492     if ( rTEvt.IsTrackingEnded() )
493     {
494         sal_uInt16 nHitTest = pData->mnHitTest;
495         pData->mnHitTest = 0;
496 
497         if ( nHitTest & BORDERWINDOW_HITTEST_CLOSE )
498         {
499             if ( pData->mnCloseState & BUTTON_DRAW_PRESSED )
500             {
501                 pData->mnCloseState &= ~BUTTON_DRAW_PRESSED;
502                 DrawWindow( BORDERWINDOW_DRAW_CLOSE );
503 
504                 // Bei Abbruch kein Click-Handler rufen
505                 if ( !rTEvt.IsTrackingCanceled() )
506                 {
507                     // dispatch to correct window type (why is Close() not virtual ??? )
508                     // TODO: make Close() virtual
509                     Window *pWin = pBorderWindow->ImplGetClientWindow()->ImplGetWindow();
510                     SystemWindow  *pSysWin  = dynamic_cast<SystemWindow* >(pWin);
511                     DockingWindow *pDockWin = dynamic_cast<DockingWindow*>(pWin);
512                     if ( pSysWin )
513                         pSysWin->Close();
514                     else if ( pDockWin )
515                         pDockWin->Close();
516                 }
517             }
518         }
519         else if ( nHitTest & BORDERWINDOW_HITTEST_ROLL )
520         {
521             if ( pData->mnRollState & BUTTON_DRAW_PRESSED )
522             {
523                 pData->mnRollState &= ~BUTTON_DRAW_PRESSED;
524                 DrawWindow( BORDERWINDOW_DRAW_ROLL );
525 
526                 // Bei Abbruch kein Click-Handler rufen
527                 if ( !rTEvt.IsTrackingCanceled() )
528                 {
529                     if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
530                     {
531                         SystemWindow* pClientWindow = (SystemWindow*)(pBorderWindow->ImplGetClientWindow());
532                         if ( pClientWindow->IsRollUp() )
533                             pClientWindow->RollDown();
534                         else
535                             pClientWindow->RollUp();
536                         pClientWindow->Roll();
537                     }
538                 }
539             }
540         }
541         else if ( nHitTest & BORDERWINDOW_HITTEST_DOCK )
542         {
543             if ( pData->mnDockState & BUTTON_DRAW_PRESSED )
544             {
545                 pData->mnDockState &= ~BUTTON_DRAW_PRESSED;
546                 DrawWindow( BORDERWINDOW_DRAW_DOCK );
547 
548                 // Bei Abbruch kein Click-Handler rufen
549                 if ( !rTEvt.IsTrackingCanceled() )
550                 {
551                     if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
552                     {
553                         SystemWindow* pClientWindow = (SystemWindow*)(pBorderWindow->ImplGetClientWindow());
554                         pClientWindow->TitleButtonClick( TITLE_BUTTON_DOCKING );
555                     }
556                 }
557             }
558         }
559         else if ( nHitTest & BORDERWINDOW_HITTEST_MENU )
560         {
561             if ( pData->mnMenuState & BUTTON_DRAW_PRESSED )
562             {
563                 pData->mnMenuState &= ~BUTTON_DRAW_PRESSED;
564                 DrawWindow( BORDERWINDOW_DRAW_MENU );
565 
566                 // handler already called on mouse down
567             }
568         }
569         else if ( nHitTest & BORDERWINDOW_HITTEST_HIDE )
570         {
571             if ( pData->mnHideState & BUTTON_DRAW_PRESSED )
572             {
573                 pData->mnHideState &= ~BUTTON_DRAW_PRESSED;
574                 DrawWindow( BORDERWINDOW_DRAW_HIDE );
575 
576                 // Bei Abbruch kein Click-Handler rufen
577                 if ( !rTEvt.IsTrackingCanceled() )
578                 {
579                     if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
580                     {
581                         SystemWindow* pClientWindow = (SystemWindow*)(pBorderWindow->ImplGetClientWindow());
582                         pClientWindow->TitleButtonClick( TITLE_BUTTON_HIDE );
583                     }
584                 }
585             }
586         }
587         else if ( nHitTest & BORDERWINDOW_HITTEST_HELP )
588         {
589             if ( pData->mnHelpState & BUTTON_DRAW_PRESSED )
590             {
591                 pData->mnHelpState &= ~BUTTON_DRAW_PRESSED;
592                 DrawWindow( BORDERWINDOW_DRAW_HELP );
593 
594                 // Bei Abbruch kein Click-Handler rufen
595                 if ( !rTEvt.IsTrackingCanceled() )
596                 {
597                 }
598             }
599         }
600         else if ( nHitTest & BORDERWINDOW_HITTEST_PIN )
601         {
602             if ( pData->mnPinState & BUTTON_DRAW_PRESSED )
603             {
604                 pData->mnPinState &= ~BUTTON_DRAW_PRESSED;
605                 DrawWindow( BORDERWINDOW_DRAW_PIN );
606 
607                 // Bei Abbruch kein Click-Handler rufen
608                 if ( !rTEvt.IsTrackingCanceled() )
609                 {
610                     if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
611                     {
612                         SystemWindow* pClientWindow = (SystemWindow*)(pBorderWindow->ImplGetClientWindow());
613                         pClientWindow->SetPin( !pClientWindow->IsPined() );
614                         pClientWindow->Pin();
615                     }
616                 }
617             }
618         }
619         else
620         {
621             if ( pData->mbDragFull )
622             {
623                 // Bei Abbruch alten Zustand wieder herstellen
624                 if ( rTEvt.IsTrackingCanceled() )
625                     pBorderWindow->SetPosSizePixel( Point( pData->mnTrackX, pData->mnTrackY ), Size( pData->mnTrackWidth, pData->mnTrackHeight ) );
626             }
627             else
628             {
629                 pBorderWindow->HideTracking();
630                 if ( !rTEvt.IsTrackingCanceled() )
631                     pBorderWindow->SetPosSizePixel( Point( pData->mnTrackX, pData->mnTrackY ), Size( pData->mnTrackWidth, pData->mnTrackHeight ) );
632             }
633 
634             if ( !rTEvt.IsTrackingCanceled() )
635             {
636                 if ( pBorderWindow->ImplGetClientWindow()->ImplIsFloatingWindow() )
637                 {
638                     if ( ((FloatingWindow*)pBorderWindow->ImplGetClientWindow())->IsInPopupMode() )
639                         ((FloatingWindow*)pBorderWindow->ImplGetClientWindow())->EndPopupMode( FLOATWIN_POPUPMODEEND_TEAROFF );
640                 }
641             }
642         }
643     }
644     else if ( !rTEvt.GetMouseEvent().IsSynthetic() )
645     {
646         Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
647 
648         if ( pData->mnHitTest & BORDERWINDOW_HITTEST_CLOSE )
649         {
650             if ( pData->maCloseRect.IsInside( aMousePos ) )
651             {
652                 if ( !(pData->mnCloseState & BUTTON_DRAW_PRESSED) )
653                 {
654                     pData->mnCloseState |= BUTTON_DRAW_PRESSED;
655                     DrawWindow( BORDERWINDOW_DRAW_CLOSE );
656                 }
657             }
658             else
659             {
660                 if ( pData->mnCloseState & BUTTON_DRAW_PRESSED )
661                 {
662                     pData->mnCloseState &= ~BUTTON_DRAW_PRESSED;
663                     DrawWindow( BORDERWINDOW_DRAW_CLOSE );
664                 }
665             }
666         }
667         else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_ROLL )
668         {
669             if ( pData->maRollRect.IsInside( aMousePos ) )
670             {
671                 if ( !(pData->mnRollState & BUTTON_DRAW_PRESSED) )
672                 {
673                     pData->mnRollState |= BUTTON_DRAW_PRESSED;
674                     DrawWindow( BORDERWINDOW_DRAW_ROLL );
675                 }
676             }
677             else
678             {
679                 if ( pData->mnRollState & BUTTON_DRAW_PRESSED )
680                 {
681                     pData->mnRollState &= ~BUTTON_DRAW_PRESSED;
682                     DrawWindow( BORDERWINDOW_DRAW_ROLL );
683                 }
684             }
685         }
686         else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_DOCK )
687         {
688             if ( pData->maDockRect.IsInside( aMousePos ) )
689             {
690                 if ( !(pData->mnDockState & BUTTON_DRAW_PRESSED) )
691                 {
692                     pData->mnDockState |= BUTTON_DRAW_PRESSED;
693                     DrawWindow( BORDERWINDOW_DRAW_DOCK );
694                 }
695             }
696             else
697             {
698                 if ( pData->mnDockState & BUTTON_DRAW_PRESSED )
699                 {
700                     pData->mnDockState &= ~BUTTON_DRAW_PRESSED;
701                     DrawWindow( BORDERWINDOW_DRAW_DOCK );
702                 }
703             }
704         }
705         else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_MENU )
706         {
707             if ( pData->maMenuRect.IsInside( aMousePos ) )
708             {
709                 if ( !(pData->mnMenuState & BUTTON_DRAW_PRESSED) )
710                 {
711                     pData->mnMenuState |= BUTTON_DRAW_PRESSED;
712                     DrawWindow( BORDERWINDOW_DRAW_MENU );
713 
714                 }
715             }
716             else
717             {
718                 if ( pData->mnMenuState & BUTTON_DRAW_PRESSED )
719                 {
720                     pData->mnMenuState &= ~BUTTON_DRAW_PRESSED;
721                     DrawWindow( BORDERWINDOW_DRAW_MENU );
722                 }
723             }
724         }
725         else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_HIDE )
726         {
727             if ( pData->maHideRect.IsInside( aMousePos ) )
728             {
729                 if ( !(pData->mnHideState & BUTTON_DRAW_PRESSED) )
730                 {
731                     pData->mnHideState |= BUTTON_DRAW_PRESSED;
732                     DrawWindow( BORDERWINDOW_DRAW_HIDE );
733                 }
734             }
735             else
736             {
737                 if ( pData->mnHideState & BUTTON_DRAW_PRESSED )
738                 {
739                     pData->mnHideState &= ~BUTTON_DRAW_PRESSED;
740                     DrawWindow( BORDERWINDOW_DRAW_HIDE );
741                 }
742             }
743         }
744         else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_HELP )
745         {
746             if ( pData->maHelpRect.IsInside( aMousePos ) )
747             {
748                 if ( !(pData->mnHelpState & BUTTON_DRAW_PRESSED) )
749                 {
750                     pData->mnHelpState |= BUTTON_DRAW_PRESSED;
751                     DrawWindow( BORDERWINDOW_DRAW_HELP );
752                 }
753             }
754             else
755             {
756                 if ( pData->mnHelpState & BUTTON_DRAW_PRESSED )
757                 {
758                     pData->mnHelpState &= ~BUTTON_DRAW_PRESSED;
759                     DrawWindow( BORDERWINDOW_DRAW_HELP );
760                 }
761             }
762         }
763         else if ( pData->mnHitTest & BORDERWINDOW_HITTEST_PIN )
764         {
765             if ( pData->maPinRect.IsInside( aMousePos ) )
766             {
767                 if ( !(pData->mnPinState & BUTTON_DRAW_PRESSED) )
768                 {
769                     pData->mnPinState |= BUTTON_DRAW_PRESSED;
770                     DrawWindow( BORDERWINDOW_DRAW_PIN );
771                 }
772             }
773             else
774             {
775                 if ( pData->mnPinState & BUTTON_DRAW_PRESSED )
776                 {
777                     pData->mnPinState &= ~BUTTON_DRAW_PRESSED;
778                     DrawWindow( BORDERWINDOW_DRAW_PIN );
779                 }
780             }
781         }
782         else
783         {
784             /*
785             // adjusting mousepos not required, we allow the whole screen (no desktop anymore...)
786             Point   aFrameMousePos = pBorderWindow->ImplOutputToFrame( aMousePos );
787             Size    aFrameSize = pBorderWindow->ImplGetFrameWindow()->GetOutputSizePixel();
788             if ( aFrameMousePos.X() < 0 )
789                 aFrameMousePos.X() = 0;
790             if ( aFrameMousePos.Y() < 0 )
791                 aFrameMousePos.Y() = 0;
792             if ( aFrameMousePos.X() > aFrameSize.Width()-1 )
793                 aFrameMousePos.X() = aFrameSize.Width()-1;
794             if ( aFrameMousePos.Y() > aFrameSize.Height()-1 )
795                 aFrameMousePos.Y() = aFrameSize.Height()-1;
796             aMousePos = pBorderWindow->ImplFrameToOutput( aFrameMousePos );
797             */
798 
799             aMousePos.X()    -= pData->maMouseOff.X();
800             aMousePos.Y()    -= pData->maMouseOff.Y();
801 
802             if ( pData->mnHitTest & BORDERWINDOW_HITTEST_TITLE )
803             {
804                 pData->mpBorderWindow->SetPointer( Pointer( POINTER_MOVE ) );
805 
806                 Point aPos = pBorderWindow->GetPosPixel();
807                 aPos.X() += aMousePos.X();
808                 aPos.Y() += aMousePos.Y();
809                 if ( pData->mbDragFull )
810                 {
811                     pBorderWindow->SetPosPixel( aPos );
812                     pBorderWindow->ImplUpdateAll();
813                     pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
814                 }
815                 else
816                 {
817                     pData->mnTrackX = aPos.X();
818                     pData->mnTrackY = aPos.Y();
819                     pBorderWindow->ShowTracking( Rectangle( pBorderWindow->ScreenToOutputPixel( aPos ), pBorderWindow->GetOutputSizePixel() ), SHOWTRACK_BIG );
820                 }
821             }
822             else
823             {
824                 Point       aOldPos         = pBorderWindow->GetPosPixel();
825                 Size        aSize           = pBorderWindow->GetSizePixel();
826                 Rectangle   aNewRect( aOldPos, aSize );
827                 long        nOldWidth       = aSize.Width();
828                 long        nOldHeight      = aSize.Height();
829                 long        nBorderWidth    = pData->mnLeftBorder+pData->mnRightBorder;
830                 long        nBorderHeight   = pData->mnTopBorder+pData->mnBottomBorder;
831                 long        nMinWidth       = pBorderWindow->mnMinWidth+nBorderWidth;
832                 long        nMinHeight      = pBorderWindow->mnMinHeight+nBorderHeight;
833                 long        nMinWidth2      = nBorderWidth;
834                 long        nMaxWidth       = pBorderWindow->mnMaxWidth+nBorderWidth;
835                 long        nMaxHeight      = pBorderWindow->mnMaxHeight+nBorderHeight;
836 
837                 if ( pData->mnTitleHeight )
838                 {
839                     nMinWidth2 += 4;
840 
841                     if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
842                         nMinWidth2 += pData->maCloseRect.GetWidth();
843                 }
844                 if ( nMinWidth2 > nMinWidth )
845                     nMinWidth = nMinWidth2;
846                 if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_LEFT | BORDERWINDOW_HITTEST_TOPLEFT | BORDERWINDOW_HITTEST_BOTTOMLEFT) )
847                 {
848                     aNewRect.Left() += aMousePos.X();
849                     if ( aNewRect.GetWidth() < nMinWidth )
850                         aNewRect.Left() = aNewRect.Right()-nMinWidth+1;
851                     else if ( aNewRect.GetWidth() > nMaxWidth )
852                         aNewRect.Left() = aNewRect.Right()-nMaxWidth+1;
853                 }
854                 else if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_RIGHT | BORDERWINDOW_HITTEST_TOPRIGHT | BORDERWINDOW_HITTEST_BOTTOMRIGHT) )
855                 {
856                     aNewRect.Right() += aMousePos.X();
857                     if ( aNewRect.GetWidth() < nMinWidth )
858                         aNewRect.Right() = aNewRect.Left()+nMinWidth+1;
859                     else if ( aNewRect.GetWidth() > nMaxWidth )
860                         aNewRect.Right() = aNewRect.Left()+nMaxWidth+1;
861                 }
862                 if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_TOP | BORDERWINDOW_HITTEST_TOPLEFT | BORDERWINDOW_HITTEST_TOPRIGHT) )
863                 {
864                     aNewRect.Top() += aMousePos.Y();
865                     if ( aNewRect.GetHeight() < nMinHeight )
866                         aNewRect.Top() = aNewRect.Bottom()-nMinHeight+1;
867                     else if ( aNewRect.GetHeight() > nMaxHeight )
868                         aNewRect.Top() = aNewRect.Bottom()-nMaxHeight+1;
869                 }
870                 else if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_BOTTOM | BORDERWINDOW_HITTEST_BOTTOMLEFT | BORDERWINDOW_HITTEST_BOTTOMRIGHT) )
871                 {
872                     aNewRect.Bottom() += aMousePos.Y();
873                     if ( aNewRect.GetHeight() < nMinHeight )
874                         aNewRect.Bottom() = aNewRect.Top()+nMinHeight+1;
875                     else if ( aNewRect.GetHeight() > nMaxHeight )
876                         aNewRect.Bottom() = aNewRect.Top()+nMaxHeight+1;
877                 }
878 
879                 // call Resizing-Handler for SystemWindows
880                 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
881                 {
882                     // adjust size for Resizing-call
883                     aSize = aNewRect.GetSize();
884                     aSize.Width()   -= nBorderWidth;
885                     aSize.Height()  -= nBorderHeight;
886                     ((SystemWindow*)pBorderWindow->ImplGetClientWindow())->Resizing( aSize );
887                     aSize.Width()   += nBorderWidth;
888                     aSize.Height()  += nBorderHeight;
889                     if ( aSize.Width() < nMinWidth )
890                         aSize.Width() = nMinWidth;
891                     if ( aSize.Height() < nMinHeight )
892                         aSize.Height() = nMinHeight;
893                     if ( aSize.Width() > nMaxWidth )
894                         aSize.Width() = nMaxWidth;
895                     if ( aSize.Height() > nMaxHeight )
896                         aSize.Height() = nMaxHeight;
897                     if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_LEFT | BORDERWINDOW_HITTEST_TOPLEFT | BORDERWINDOW_HITTEST_BOTTOMLEFT) )
898                         aNewRect.Left() = aNewRect.Right()-aSize.Width()+1;
899                     else
900                         aNewRect.Right() = aNewRect.Left()+aSize.Width()-1;
901                     if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_TOP | BORDERWINDOW_HITTEST_TOPLEFT | BORDERWINDOW_HITTEST_TOPRIGHT) )
902                         aNewRect.Top() = aNewRect.Bottom()-aSize.Height()+1;
903                     else
904                         aNewRect.Bottom() = aNewRect.Top()+aSize.Height()-1;
905                 }
906 
907                 if ( pData->mbDragFull )
908                 {
909                     // no move (only resize) if position did not change
910                     if( aOldPos != aNewRect.TopLeft() )
911                         pBorderWindow->SetPosSizePixel( aNewRect.Left(), aNewRect.Top(),
912                                                     aNewRect.GetWidth(), aNewRect.GetHeight(), WINDOW_POSSIZE_POSSIZE );
913                     else
914                         pBorderWindow->SetPosSizePixel( aNewRect.Left(), aNewRect.Top(),
915                                                     aNewRect.GetWidth(), aNewRect.GetHeight(), WINDOW_POSSIZE_SIZE );
916 
917                     pBorderWindow->ImplUpdateAll();
918                     pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
919                     if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_RIGHT | BORDERWINDOW_HITTEST_TOPRIGHT | BORDERWINDOW_HITTEST_BOTTOMRIGHT) )
920                         pData->maMouseOff.X() += aNewRect.GetWidth()-nOldWidth;
921                     if ( pData->mnHitTest & (BORDERWINDOW_HITTEST_BOTTOM | BORDERWINDOW_HITTEST_BOTTOMLEFT | BORDERWINDOW_HITTEST_BOTTOMRIGHT) )
922                         pData->maMouseOff.Y() += aNewRect.GetHeight()-nOldHeight;
923                 }
924                 else
925                 {
926                     pData->mnTrackX        = aNewRect.Left();
927                     pData->mnTrackY        = aNewRect.Top();
928                     pData->mnTrackWidth    = aNewRect.GetWidth();
929                     pData->mnTrackHeight   = aNewRect.GetHeight();
930                     pBorderWindow->ShowTracking( Rectangle( pBorderWindow->ScreenToOutputPixel( aNewRect.TopLeft() ), aNewRect.GetSize() ), SHOWTRACK_BIG );
931                 }
932             }
933         }
934     }
935 
936     return sal_True;
937 }
938 
939 // -----------------------------------------------------------------------
940 
941 String ImplBorderWindowView::ImplRequestHelp( ImplBorderFrameData* pData,
942                                               const Point& rPos,
943                                               Rectangle& rHelpRect )
944 {
945     sal_uInt16 nHelpId = 0;
946     String aHelpStr;
947     sal_uInt16 nHitTest = ImplHitTest( pData, rPos );
948     if ( nHitTest )
949     {
950         if ( nHitTest & BORDERWINDOW_HITTEST_CLOSE )
951         {
952             nHelpId     = SV_HELPTEXT_CLOSE;
953             rHelpRect   = pData->maCloseRect;
954         }
955         else if ( nHitTest & BORDERWINDOW_HITTEST_ROLL )
956         {
957             if ( pData->mpBorderWindow->mbRollUp )
958                 nHelpId = SV_HELPTEXT_ROLLDOWN;
959             else
960                 nHelpId = SV_HELPTEXT_ROLLUP;
961             rHelpRect   = pData->maRollRect;
962         }
963         else if ( nHitTest & BORDERWINDOW_HITTEST_DOCK )
964         {
965             nHelpId     = SV_HELPTEXT_MAXIMIZE;
966             rHelpRect   = pData->maDockRect;
967         }
968         /* no help string available
969         else if ( nHitTest & BORDERWINDOW_HITTEST_MENU )
970         {
971             nHelpId     = SV_HELPTEXT_MENU;
972             rHelpRect   = pData->maMenuRect;
973         }*/
974         else if ( nHitTest & BORDERWINDOW_HITTEST_HIDE )
975         {
976             nHelpId     = SV_HELPTEXT_MINIMIZE;
977             rHelpRect   = pData->maHideRect;
978         }
979         else if ( nHitTest & BORDERWINDOW_HITTEST_HELP )
980         {
981             nHelpId     = SV_HELPTEXT_HELP;
982             rHelpRect   = pData->maHelpRect;
983         }
984         else if ( nHitTest & BORDERWINDOW_HITTEST_PIN )
985         {
986             nHelpId     = SV_HELPTEXT_ALWAYSVISIBLE;
987             rHelpRect   = pData->maPinRect;
988         }
989         else if ( nHitTest & BORDERWINDOW_HITTEST_TITLE )
990         {
991             if( !pData->maTitleRect.IsEmpty() )
992             {
993                 // tooltip only if title truncated
994                 if( pData->mbTitleClipped )
995                 {
996                     rHelpRect   = pData->maTitleRect;
997                     // no help id, use window title as help string
998                     aHelpStr    = pData->mpBorderWindow->GetText();
999                 }
1000             }
1001         }
1002     }
1003 
1004     if( nHelpId && ImplGetResMgr() )
1005         aHelpStr = String( ResId( nHelpId, *ImplGetResMgr() ) );
1006 
1007     return aHelpStr;
1008 }
1009 
1010 // -----------------------------------------------------------------------
1011 
1012 long ImplBorderWindowView::ImplCalcTitleWidth( const ImplBorderFrameData* pData ) const
1013 {
1014     // kein sichtbarer Title, dann auch keine Breite
1015     if ( !pData->mnTitleHeight )
1016         return 0;
1017 
1018     ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
1019     long nTitleWidth = pBorderWindow->GetTextWidth( pBorderWindow->GetText() )+6;
1020     nTitleWidth += pData->maPinRect.GetWidth();
1021     nTitleWidth += pData->maCloseRect.GetWidth();
1022     nTitleWidth += pData->maRollRect.GetWidth();
1023     nTitleWidth += pData->maDockRect.GetWidth();
1024     nTitleWidth += pData->maMenuRect.GetWidth();
1025     nTitleWidth += pData->maHideRect.GetWidth();
1026     nTitleWidth += pData->maHelpRect.GetWidth();
1027     nTitleWidth += pData->mnLeftBorder+pData->mnRightBorder;
1028     return nTitleWidth;
1029 }
1030 
1031 // =======================================================================
1032 
1033 // --------------------------
1034 // - ImplNoBorderWindowView -
1035 // --------------------------
1036 
1037 ImplNoBorderWindowView::ImplNoBorderWindowView( ImplBorderWindow* )
1038 {
1039 }
1040 
1041 // -----------------------------------------------------------------------
1042 
1043 void ImplNoBorderWindowView::Init( OutputDevice*, long, long )
1044 {
1045 }
1046 
1047 // -----------------------------------------------------------------------
1048 
1049 void ImplNoBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
1050                                         sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
1051 {
1052     rLeftBorder     = 0;
1053     rTopBorder      = 0;
1054     rRightBorder    = 0;
1055     rBottomBorder   = 0;
1056 }
1057 
1058 // -----------------------------------------------------------------------
1059 
1060 long ImplNoBorderWindowView::CalcTitleWidth() const
1061 {
1062     return 0;
1063 }
1064 
1065 // -----------------------------------------------------------------------
1066 
1067 void ImplNoBorderWindowView::DrawWindow( sal_uInt16, OutputDevice*, const Point* )
1068 {
1069 }
1070 
1071 // =======================================================================
1072 
1073 // -----------------------------
1074 // - ImplSmallBorderWindowView -
1075 // -----------------------------
1076 
1077 // =======================================================================
1078 
1079 ImplSmallBorderWindowView::ImplSmallBorderWindowView( ImplBorderWindow* pBorderWindow )
1080 {
1081     mpBorderWindow = pBorderWindow;
1082 }
1083 
1084 // -----------------------------------------------------------------------
1085 
1086 void ImplSmallBorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHeight )
1087 {
1088     mpOutDev    = pDev;
1089     mnWidth     = nWidth;
1090     mnHeight    = nHeight;
1091     mbNWFBorder = false;
1092 
1093     sal_uInt16 nBorderStyle = mpBorderWindow->GetBorderStyle();
1094     if ( nBorderStyle & WINDOW_BORDER_NOBORDER )
1095     {
1096         mnLeftBorder    = 0;
1097         mnTopBorder     = 0;
1098         mnRightBorder   = 0;
1099         mnBottomBorder  = 0;
1100     }
1101     else
1102     {
1103         // FIXME: this is currently only on aqua, check with other
1104         // platforms
1105         if( ImplGetSVData()->maNWFData.mbNoFocusRects )
1106         {
1107             // for native widget drawing we must find out what
1108             // control this border belongs to
1109             Window *pWin = NULL, *pCtrl = NULL;
1110             if( mpOutDev->GetOutDevType() == OUTDEV_WINDOW )
1111                 pWin = (Window*) mpOutDev;
1112 
1113             ControlType aCtrlType = 0;
1114             if( pWin && (pCtrl = mpBorderWindow->GetWindow( WINDOW_CLIENT )) != NULL )
1115             {
1116                 switch( pCtrl->GetType() )
1117                 {
1118                     case WINDOW_LISTBOX:
1119                         if( pCtrl->GetStyle() & WB_DROPDOWN )
1120                         {
1121                             aCtrlType = CTRL_LISTBOX;
1122                             mbNWFBorder = true;
1123                         }
1124                         break;
1125                     case WINDOW_COMBOBOX:
1126                         if( pCtrl->GetStyle() & WB_DROPDOWN )
1127                         {
1128                             aCtrlType = CTRL_COMBOBOX;
1129                             mbNWFBorder = true;
1130                         }
1131                         break;
1132                     case WINDOW_MULTILINEEDIT:
1133                         aCtrlType = CTRL_MULTILINE_EDITBOX;
1134                         mbNWFBorder = true;
1135                         break;
1136                     case WINDOW_EDIT:
1137                     case WINDOW_PATTERNFIELD:
1138                     case WINDOW_METRICFIELD:
1139                     case WINDOW_CURRENCYFIELD:
1140                     case WINDOW_DATEFIELD:
1141                     case WINDOW_TIMEFIELD:
1142                     case WINDOW_LONGCURRENCYFIELD:
1143                     case WINDOW_NUMERICFIELD:
1144                     case WINDOW_SPINFIELD:
1145                         mbNWFBorder = true;
1146                         aCtrlType = (pCtrl->GetStyle() & WB_SPIN) ? CTRL_SPINBOX : CTRL_EDITBOX;
1147                         break;
1148                     default:
1149                         break;
1150                 }
1151             }
1152             if( mbNWFBorder )
1153             {
1154                 ImplControlValue aControlValue;
1155                 Rectangle aCtrlRegion( (const Point&)Point(), Size( mnWidth < 10 ? 10 : mnWidth, mnHeight < 10 ? 10 : mnHeight ) );
1156                 Rectangle aBounds( aCtrlRegion );
1157                 Rectangle aContent( aCtrlRegion );
1158                 if( pWin->GetNativeControlRegion( aCtrlType, PART_ENTIRE_CONTROL, aCtrlRegion,
1159                                                   CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
1160                                                   aBounds, aContent ) )
1161                 {
1162                     mnLeftBorder    = aContent.Left() - aBounds.Left();
1163                     mnRightBorder   = aBounds.Right() - aContent.Right();
1164                     mnTopBorder     = aContent.Top() - aBounds.Top();
1165                     mnBottomBorder  = aBounds.Bottom() - aContent.Bottom();
1166                     if( mnWidth && mnHeight )
1167                     {
1168 
1169                         mpBorderWindow->SetPaintTransparent( sal_True );
1170                         mpBorderWindow->SetBackground();
1171                         pCtrl->SetPaintTransparent( sal_True );
1172 
1173                         Window* pCompoundParent = NULL;
1174                         if( pWin->GetParent() && pWin->GetParent()->IsCompoundControl() )
1175                             pCompoundParent = pWin->GetParent();
1176 
1177                         if( pCompoundParent )
1178                             pCompoundParent->SetPaintTransparent( sal_True );
1179 
1180                         if( mnWidth < aBounds.GetWidth() || mnHeight < aBounds.GetHeight() )
1181                         {
1182                             if( ! pCompoundParent ) // compound controls have to fix themselves
1183                             {
1184                                 Point aPos( mpBorderWindow->GetPosPixel() );
1185                                 if( mnWidth < aBounds.GetWidth() )
1186                                     aPos.X() -= (aBounds.GetWidth() - mnWidth) / 2;
1187                                 if( mnHeight < aBounds.GetHeight() )
1188                                     aPos.Y() -= (aBounds.GetHeight() - mnHeight) / 2;
1189                                 mpBorderWindow->SetPosSizePixel( aPos, aBounds.GetSize() );
1190                             }
1191                         }
1192                     }
1193                 }
1194                 else
1195                     mbNWFBorder = false;
1196             }
1197         }
1198 
1199         if( ! mbNWFBorder )
1200         {
1201             sal_uInt16 nStyle = FRAME_DRAW_NODRAW;
1202             // Wenn Border umgesetzt wurde oder BorderWindow ein Frame-Fenster
1203             // ist, dann Border nach aussen
1204             if ( (nBorderStyle & WINDOW_BORDER_DOUBLEOUT) || mpBorderWindow->mbSmallOutBorder )
1205                 nStyle |= FRAME_DRAW_DOUBLEOUT;
1206             else
1207                 nStyle |= FRAME_DRAW_DOUBLEIN;
1208             if ( nBorderStyle & WINDOW_BORDER_MONO )
1209                 nStyle |= FRAME_DRAW_MONO;
1210 
1211             DecorationView  aDecoView( mpOutDev );
1212             Rectangle       aRect( 0, 0, 10, 10 );
1213             Rectangle       aCalcRect = aDecoView.DrawFrame( aRect, nStyle );
1214             mnLeftBorder    = aCalcRect.Left();
1215             mnTopBorder     = aCalcRect.Top();
1216             mnRightBorder   = aRect.Right()-aCalcRect.Right();
1217             mnBottomBorder  = aRect.Bottom()-aCalcRect.Bottom();
1218         }
1219     }
1220 }
1221 
1222 // -----------------------------------------------------------------------
1223 
1224 void ImplSmallBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
1225                                            sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
1226 {
1227     rLeftBorder     = mnLeftBorder;
1228     rTopBorder      = mnTopBorder;
1229     rRightBorder    = mnRightBorder;
1230     rBottomBorder   = mnBottomBorder;
1231 }
1232 
1233 // -----------------------------------------------------------------------
1234 
1235 long ImplSmallBorderWindowView::CalcTitleWidth() const
1236 {
1237     return 0;
1238 }
1239 
1240 // -----------------------------------------------------------------------
1241 
1242 void ImplSmallBorderWindowView::DrawWindow( sal_uInt16 nDrawFlags, OutputDevice*, const Point* )
1243 {
1244     sal_uInt16 nBorderStyle = mpBorderWindow->GetBorderStyle();
1245     if ( nBorderStyle & WINDOW_BORDER_NOBORDER )
1246         return;
1247 
1248     sal_Bool bNativeOK = sal_False;
1249     // for native widget drawing we must find out what
1250     // control this border belongs to
1251     Window *pWin = NULL, *pCtrl = NULL;
1252     if( mpOutDev->GetOutDevType() == OUTDEV_WINDOW )
1253         pWin = (Window*) mpOutDev;
1254 
1255     ControlType aCtrlType = 0;
1256     ControlPart aCtrlPart = PART_ENTIRE_CONTROL;
1257 
1258     if( pWin && (pCtrl = mpBorderWindow->GetWindow( WINDOW_CLIENT )) != NULL )
1259     {
1260         switch( pCtrl->GetType() )
1261         {
1262             case WINDOW_MULTILINEEDIT:
1263                 aCtrlType = CTRL_MULTILINE_EDITBOX;
1264                 break;
1265             case WINDOW_EDIT:
1266             case WINDOW_PATTERNFIELD:
1267             case WINDOW_METRICFIELD:
1268             case WINDOW_CURRENCYFIELD:
1269             case WINDOW_DATEFIELD:
1270             case WINDOW_TIMEFIELD:
1271             case WINDOW_LONGCURRENCYFIELD:
1272             case WINDOW_NUMERICFIELD:
1273             case WINDOW_SPINFIELD:
1274                 if( pCtrl->GetStyle() & WB_SPIN )
1275                     aCtrlType = CTRL_SPINBOX;
1276                 else
1277                     aCtrlType = CTRL_EDITBOX;
1278                 break;
1279 
1280             case WINDOW_LISTBOX:
1281             case WINDOW_MULTILISTBOX:
1282             case WINDOW_TREELISTBOX:
1283                 aCtrlType = CTRL_LISTBOX;
1284                 if( pCtrl->GetStyle() & WB_DROPDOWN )
1285                     aCtrlPart = PART_ENTIRE_CONTROL;
1286                 else
1287                     aCtrlPart = PART_WINDOW;
1288                 break;
1289 
1290             case WINDOW_LISTBOXWINDOW:
1291                 aCtrlType = CTRL_LISTBOX;
1292                 aCtrlPart = PART_WINDOW;
1293                 break;
1294 
1295             case WINDOW_COMBOBOX:
1296             case WINDOW_PATTERNBOX:
1297             case WINDOW_NUMERICBOX:
1298             case WINDOW_METRICBOX:
1299             case WINDOW_CURRENCYBOX:
1300             case WINDOW_DATEBOX:
1301             case WINDOW_TIMEBOX:
1302             case WINDOW_LONGCURRENCYBOX:
1303                 if( pCtrl->GetStyle() & WB_DROPDOWN )
1304                 {
1305                     aCtrlType = CTRL_COMBOBOX;
1306                     aCtrlPart = PART_ENTIRE_CONTROL;
1307                 }
1308                 else
1309                 {
1310                     aCtrlType = CTRL_LISTBOX;
1311                     aCtrlPart = PART_WINDOW;
1312                 }
1313                 break;
1314 
1315             default:
1316                 break;
1317         }
1318     }
1319 
1320     if ( aCtrlType && pCtrl->IsNativeControlSupported(aCtrlType, aCtrlPart) )
1321     {
1322         ImplControlValue aControlValue;
1323         ControlState     nState = CTRL_STATE_ENABLED;
1324 
1325         if ( !pWin->IsEnabled() )
1326             nState &= ~CTRL_STATE_ENABLED;
1327         if ( pWin->HasFocus() )
1328             nState |= CTRL_STATE_FOCUSED;
1329         else if( mbNWFBorder )
1330         {
1331             // FIXME: this is curently only on aqua, see if other platforms can profit
1332 
1333             // FIXME: for aqua focus rings all controls need to support GetNativeControlRegion
1334             // for the dropdown style
1335             if( pCtrl->HasFocus() || pCtrl->HasChildPathFocus() )
1336                 nState |= CTRL_STATE_FOCUSED;
1337         }
1338 
1339         sal_Bool bMouseOver = sal_False;
1340         Window *pCtrlChild = pCtrl->GetWindow( WINDOW_FIRSTCHILD );
1341         while( pCtrlChild && (bMouseOver = pCtrlChild->IsMouseOver()) == sal_False )
1342             pCtrlChild = pCtrlChild->GetWindow( WINDOW_NEXT );
1343 
1344         if( bMouseOver )
1345             nState |= CTRL_STATE_ROLLOVER;
1346 
1347         Point aPoint;
1348         Rectangle aCtrlRegion( aPoint, Size( mnWidth, mnHeight ) );
1349 
1350         Rectangle aBoundingRgn( aPoint, Size( mnWidth, mnHeight ) );
1351         Rectangle aContentRgn( aCtrlRegion );
1352         if( ! ImplGetSVData()->maNWFData.mbCanDrawWidgetAnySize &&
1353             pWin->GetNativeControlRegion( aCtrlType, aCtrlPart, aCtrlRegion,
1354                                           nState, aControlValue, rtl::OUString(),
1355                                           aBoundingRgn, aContentRgn ))
1356         {
1357             aCtrlRegion=aContentRgn;
1358         }
1359 
1360         bNativeOK = pWin->DrawNativeControl( aCtrlType, aCtrlPart, aCtrlRegion, nState,
1361                 aControlValue, rtl::OUString() );
1362 
1363         // if the native theme draws the spinbuttons in one call, make sure the proper settings
1364         // are passed, this might force a redraw though.... (TODO: improve)
1365         if ( (aCtrlType == CTRL_SPINBOX) && !pCtrl->IsNativeControlSupported( CTRL_SPINBOX, PART_BUTTON_UP ) )
1366         {
1367             Edit *pEdit = ((Edit*) pCtrl)->GetSubEdit();
1368             if ( pEdit )
1369                 pCtrl->Paint( Rectangle() );  // make sure the buttons are also drawn as they might overwrite the border
1370         }
1371     }
1372 
1373     if( bNativeOK )
1374         return;
1375 
1376     if ( nDrawFlags & BORDERWINDOW_DRAW_FRAME )
1377     {
1378         if ( nBorderStyle & WINDOW_BORDER_ACTIVE )
1379         {
1380             Color aColor = mpOutDev->GetSettings().GetStyleSettings().GetHighlightColor();
1381             mpOutDev->SetLineColor();
1382             mpOutDev->SetFillColor( aColor );
1383             mpOutDev->DrawRect( Rectangle( 0, 0, mnWidth-1, mnTopBorder ) );
1384             mpOutDev->DrawRect( Rectangle( 0, mnHeight-mnBottomBorder, mnWidth-1, mnHeight-1 ) );
1385             mpOutDev->DrawRect( Rectangle( 0, 0, mnLeftBorder, mnHeight-1 ) );
1386             mpOutDev->DrawRect( Rectangle( mnWidth-mnRightBorder, 0, mnWidth-1, mnHeight-1 ) );
1387         }
1388         else
1389         {
1390             sal_uInt16 nStyle = 0;
1391             // Wenn Border umgesetzt wurde oder BorderWindow ein Frame-Fenster
1392             // ist, dann Border nach aussen
1393             if ( (nBorderStyle & WINDOW_BORDER_DOUBLEOUT) || mpBorderWindow->mbSmallOutBorder )
1394                 nStyle |= FRAME_DRAW_DOUBLEOUT;
1395             else
1396                 nStyle |= FRAME_DRAW_DOUBLEIN;
1397             if ( nBorderStyle & WINDOW_BORDER_MONO )
1398                 nStyle |= FRAME_DRAW_MONO;
1399             if ( nBorderStyle & WINDOW_BORDER_MENU )
1400                 nStyle |= FRAME_DRAW_MENU;
1401             // tell DrawFrame that we're drawing a window border of a frame window to avoid round corners
1402             if( pWin && pWin == pWin->ImplGetFrameWindow() )
1403                 nStyle |= FRAME_DRAW_WINDOWBORDER;
1404 
1405             DecorationView  aDecoView( mpOutDev );
1406             Point           aTmpPoint;
1407             Rectangle       aInRect( aTmpPoint, Size( mnWidth, mnHeight ) );
1408             aDecoView.DrawFrame( aInRect, nStyle );
1409         }
1410     }
1411 }
1412 
1413 // =======================================================================
1414 
1415 // ---------------------------
1416 // - ImplStdBorderWindowView -
1417 // ---------------------------
1418 
1419 ImplStdBorderWindowView::ImplStdBorderWindowView( ImplBorderWindow* pBorderWindow )
1420 {
1421     maFrameData.mpBorderWindow  = pBorderWindow;
1422     maFrameData.mbDragFull      = sal_False;
1423     maFrameData.mnHitTest       = 0;
1424     maFrameData.mnPinState      = 0;
1425     maFrameData.mnCloseState    = 0;
1426     maFrameData.mnRollState     = 0;
1427     maFrameData.mnDockState     = 0;
1428     maFrameData.mnMenuState     = 0;
1429     maFrameData.mnHideState     = 0;
1430     maFrameData.mnHelpState     = 0;
1431     maFrameData.mbTitleClipped  = 0;
1432 
1433     mpATitleVirDev              = NULL;
1434     mpDTitleVirDev              = NULL;
1435 }
1436 
1437 // -----------------------------------------------------------------------
1438 
1439 ImplStdBorderWindowView::~ImplStdBorderWindowView()
1440 {
1441     if ( mpATitleVirDev )
1442         delete mpATitleVirDev;
1443     if ( mpDTitleVirDev )
1444         delete mpDTitleVirDev;
1445 }
1446 
1447 // -----------------------------------------------------------------------
1448 
1449 sal_Bool ImplStdBorderWindowView::MouseMove( const MouseEvent& rMEvt )
1450 {
1451     return ImplMouseMove( &maFrameData, rMEvt );
1452 }
1453 
1454 // -----------------------------------------------------------------------
1455 
1456 sal_Bool ImplStdBorderWindowView::MouseButtonDown( const MouseEvent& rMEvt )
1457 {
1458     return ImplMouseButtonDown( &maFrameData, rMEvt );
1459 }
1460 
1461 // -----------------------------------------------------------------------
1462 
1463 sal_Bool ImplStdBorderWindowView::Tracking( const TrackingEvent& rTEvt )
1464 {
1465     return ImplTracking( &maFrameData, rTEvt );
1466 }
1467 
1468 // -----------------------------------------------------------------------
1469 
1470 String ImplStdBorderWindowView::RequestHelp( const Point& rPos, Rectangle& rHelpRect )
1471 {
1472     return ImplRequestHelp( &maFrameData, rPos, rHelpRect );
1473 }
1474 
1475 // -----------------------------------------------------------------------
1476 
1477 Rectangle ImplStdBorderWindowView::GetMenuRect() const
1478 {
1479     return maFrameData.maMenuRect;
1480 }
1481 
1482 // -----------------------------------------------------------------------
1483 
1484 void ImplStdBorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHeight )
1485 {
1486     ImplBorderFrameData*    pData = &maFrameData;
1487     ImplBorderWindow*       pBorderWindow = maFrameData.mpBorderWindow;
1488     const StyleSettings&    rStyleSettings = pDev->GetSettings().GetStyleSettings();
1489     DecorationView          aDecoView( pDev );
1490     Rectangle               aRect( 0, 0, 10, 10 );
1491     Rectangle               aCalcRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEOUT | FRAME_DRAW_NODRAW );
1492 
1493     pData->mpOutDev         = pDev;
1494     pData->mnWidth          = nWidth;
1495     pData->mnHeight         = nHeight;
1496 
1497     pData->mnTitleType      = pBorderWindow->mnTitleType;
1498     pData->mbFloatWindow    = pBorderWindow->mbFloatWindow;
1499 
1500     if ( !(pBorderWindow->GetStyle() & WB_MOVEABLE) || (pData->mnTitleType == BORDERWINDOW_TITLE_NONE) )
1501         pData->mnBorderSize = 0;
1502     else if ( pData->mnTitleType == BORDERWINDOW_TITLE_TEAROFF )
1503         pData->mnBorderSize = 0;
1504     else
1505         pData->mnBorderSize = rStyleSettings.GetBorderSize();
1506     pData->mnLeftBorder     = aCalcRect.Left();
1507     pData->mnTopBorder      = aCalcRect.Top();
1508     pData->mnRightBorder    = aRect.Right()-aCalcRect.Right();
1509     pData->mnBottomBorder   = aRect.Bottom()-aCalcRect.Bottom();
1510     pData->mnLeftBorder    += pData->mnBorderSize;
1511     pData->mnTopBorder     += pData->mnBorderSize;
1512     pData->mnRightBorder   += pData->mnBorderSize;
1513     pData->mnBottomBorder  += pData->mnBorderSize;
1514     pData->mnNoTitleTop     = pData->mnTopBorder;
1515 
1516     ImplInitTitle( &maFrameData );
1517     if ( pData->mnTitleHeight )
1518     {
1519         // to improve symbol display force a minum title height
1520         if( pData->mnTitleHeight < MIN_CAPTION_HEIGHT )
1521             pData->mnTitleHeight = MIN_CAPTION_HEIGHT;
1522 
1523         // set a proper background for drawing
1524         // highlighted buttons in the title
1525         pBorderWindow->SetBackground( rStyleSettings.GetWindowColor() );
1526 
1527         pData->maTitleRect.Left()    = pData->mnLeftBorder;
1528         pData->maTitleRect.Right()   = nWidth-pData->mnRightBorder-1;
1529         pData->maTitleRect.Top()     = pData->mnTopBorder;
1530         pData->maTitleRect.Bottom()  = pData->maTitleRect.Top()+pData->mnTitleHeight-1;
1531 
1532         if ( pData->mnTitleType & (BORDERWINDOW_TITLE_NORMAL | BORDERWINDOW_TITLE_SMALL) )
1533         {
1534             long nLeft          = pData->maTitleRect.Left();
1535             long nRight         = pData->maTitleRect.Right();
1536             long nItemTop       = pData->maTitleRect.Top();
1537             long nItemBottom    = pData->maTitleRect.Bottom();
1538             nLeft              += 1;
1539             nRight             -= 3;
1540             nItemTop           += 2;
1541             nItemBottom        -= 2;
1542 
1543             if ( pBorderWindow->GetStyle() & WB_PINABLE )
1544             {
1545                 Image aImage;
1546                 ImplGetPinImage( 0, 0, aImage );
1547                 pData->maPinRect.Top()    = nItemTop;
1548                 pData->maPinRect.Bottom() = nItemBottom;
1549                 pData->maPinRect.Left()   = nLeft;
1550                 pData->maPinRect.Right()  = pData->maPinRect.Left()+aImage.GetSizePixel().Width();
1551                 nLeft += pData->maPinRect.GetWidth()+3;
1552             }
1553 
1554             if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
1555             {
1556                 pData->maCloseRect.Top()    = nItemTop;
1557                 pData->maCloseRect.Bottom() = nItemBottom;
1558                 pData->maCloseRect.Right()  = nRight;
1559                 pData->maCloseRect.Left()   = pData->maCloseRect.Right()-pData->maCloseRect.GetHeight()+1;
1560                 nRight -= pData->maCloseRect.GetWidth()+3;
1561             }
1562 
1563             if ( pBorderWindow->mbMenuBtn )
1564             {
1565                 pData->maMenuRect.Top()    = nItemTop;
1566                 pData->maMenuRect.Bottom() = nItemBottom;
1567                 pData->maMenuRect.Right()  = nRight;
1568                 pData->maMenuRect.Left()   = pData->maMenuRect.Right()-pData->maMenuRect.GetHeight()+1;
1569                 nRight -= pData->maMenuRect.GetWidth();
1570             }
1571 
1572             if ( pBorderWindow->mbDockBtn )
1573             {
1574                 pData->maDockRect.Top()    = nItemTop;
1575                 pData->maDockRect.Bottom() = nItemBottom;
1576                 pData->maDockRect.Right()  = nRight;
1577                 pData->maDockRect.Left()   = pData->maDockRect.Right()-pData->maDockRect.GetHeight()+1;
1578                 nRight -= pData->maDockRect.GetWidth();
1579                 if ( !pBorderWindow->mbHideBtn &&
1580                      !(pBorderWindow->GetStyle() & WB_ROLLABLE) )
1581                     nRight -= 3;
1582             }
1583 
1584             if ( pBorderWindow->mbHideBtn )
1585             {
1586                 pData->maHideRect.Top()    = nItemTop;
1587                 pData->maHideRect.Bottom() = nItemBottom;
1588                 pData->maHideRect.Right()  = nRight;
1589                 pData->maHideRect.Left()   = pData->maHideRect.Right()-pData->maHideRect.GetHeight()+1;
1590                 nRight -= pData->maHideRect.GetWidth();
1591                 if ( !(pBorderWindow->GetStyle() & WB_ROLLABLE) )
1592                     nRight -= 3;
1593             }
1594 
1595             if ( pBorderWindow->GetStyle() & WB_ROLLABLE )
1596             {
1597                 pData->maRollRect.Top()    = nItemTop;
1598                 pData->maRollRect.Bottom() = nItemBottom;
1599                 pData->maRollRect.Right()  = nRight;
1600                 pData->maRollRect.Left()   = pData->maRollRect.Right()-pData->maRollRect.GetHeight()+1;
1601                 nRight -= pData->maRollRect.GetWidth();
1602             }
1603 
1604             if ( pBorderWindow->mbHelpBtn )
1605             {
1606                 pData->maHelpRect.Top()    = nItemTop;
1607                 pData->maHelpRect.Bottom() = nItemBottom;
1608                 pData->maHelpRect.Right()  = nRight;
1609                 pData->maHelpRect.Left()   = pData->maHelpRect.Right()-pData->maHelpRect.GetHeight()+1;
1610                 nRight -= pData->maHelpRect.GetWidth()+3;
1611             }
1612         }
1613         else
1614         {
1615             pData->maPinRect.SetEmpty();
1616             pData->maCloseRect.SetEmpty();
1617             pData->maDockRect.SetEmpty();
1618             pData->maMenuRect.SetEmpty();
1619             pData->maHideRect.SetEmpty();
1620             pData->maRollRect.SetEmpty();
1621             pData->maHelpRect.SetEmpty();
1622         }
1623 
1624         pData->mnTopBorder  += pData->mnTitleHeight;
1625     }
1626     else
1627     {
1628         pData->maTitleRect.SetEmpty();
1629         pData->maPinRect.SetEmpty();
1630         pData->maCloseRect.SetEmpty();
1631         pData->maDockRect.SetEmpty();
1632         pData->maMenuRect.SetEmpty();
1633         pData->maHideRect.SetEmpty();
1634         pData->maRollRect.SetEmpty();
1635         pData->maHelpRect.SetEmpty();
1636     }
1637 }
1638 
1639 // -----------------------------------------------------------------------
1640 
1641 void ImplStdBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
1642                                          sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
1643 {
1644     rLeftBorder     = maFrameData.mnLeftBorder;
1645     rTopBorder      = maFrameData.mnTopBorder;
1646     rRightBorder    = maFrameData.mnRightBorder;
1647     rBottomBorder   = maFrameData.mnBottomBorder;
1648 }
1649 
1650 // -----------------------------------------------------------------------
1651 
1652 long ImplStdBorderWindowView::CalcTitleWidth() const
1653 {
1654     return ImplCalcTitleWidth( &maFrameData );
1655 }
1656 
1657 // -----------------------------------------------------------------------
1658 
1659 void ImplStdBorderWindowView::DrawWindow( sal_uInt16 nDrawFlags, OutputDevice* pOutDev, const Point* pOffset )
1660 {
1661     ImplBorderFrameData*    pData = &maFrameData;
1662     OutputDevice*           pDev = pOutDev ? pOutDev : pData->mpOutDev;
1663     ImplBorderWindow*       pBorderWindow = pData->mpBorderWindow;
1664     Point                   aTmpPoint = pOffset ? Point(*pOffset) : Point();
1665     Rectangle               aInRect( aTmpPoint, Size( pData->mnWidth, pData->mnHeight ) );
1666     const StyleSettings&    rStyleSettings = pData->mpOutDev->GetSettings().GetStyleSettings();
1667     DecorationView          aDecoView( pDev );
1668     Color                   aFrameColor( rStyleSettings.GetFaceColor() );
1669 
1670     aFrameColor.DecreaseContrast( (sal_uInt8) (0.50 * 255));
1671 
1672     // Draw Frame
1673     if ( nDrawFlags & BORDERWINDOW_DRAW_FRAME )
1674     {
1675         // single line frame
1676         pDev->SetLineColor( aFrameColor );
1677         pDev->SetFillColor();
1678         pDev->DrawRect( aInRect );
1679         aInRect.nLeft++; aInRect.nRight--;
1680         aInRect.nTop++; aInRect.nBottom--;
1681     }
1682     else
1683         aInRect = aDecoView.DrawFrame( aInRect, FRAME_DRAW_DOUBLEOUT | FRAME_DRAW_NODRAW);
1684 
1685     // Draw Border
1686     pDev->SetLineColor();
1687     long nBorderSize = pData->mnBorderSize;
1688     if ( (nDrawFlags & BORDERWINDOW_DRAW_BORDER) && nBorderSize )
1689     {
1690         pDev->SetFillColor( rStyleSettings.GetFaceColor() );
1691         pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Top() ),
1692                                    Size( aInRect.GetWidth(), nBorderSize ) ) );
1693         pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Top()+nBorderSize ),
1694                                    Size( nBorderSize, aInRect.GetHeight()-nBorderSize ) ) );
1695         pDev->DrawRect( Rectangle( Point( aInRect.Left(), aInRect.Bottom()-nBorderSize+1 ),
1696                                    Size( aInRect.GetWidth(), nBorderSize ) ) );
1697         pDev->DrawRect( Rectangle( Point( aInRect.Right()-nBorderSize+1, aInRect.Top()+nBorderSize ),
1698                                    Size( nBorderSize, aInRect.GetHeight()-nBorderSize ) ) );
1699     }
1700 
1701     // Draw Title
1702     if ( (nDrawFlags & BORDERWINDOW_DRAW_TITLE) && !pData->maTitleRect.IsEmpty() )
1703     {
1704         aInRect = pData->maTitleRect;
1705 
1706         // use no gradient anymore, just a static titlecolor
1707         pDev->SetFillColor( aFrameColor );
1708         pDev->SetTextColor( rStyleSettings.GetButtonTextColor() );
1709         Rectangle aTitleRect( pData->maTitleRect );
1710         if( pOffset )
1711             aTitleRect.Move( pOffset->X(), pOffset->Y() );
1712         pDev->DrawRect( aTitleRect );
1713 
1714 
1715         if ( pData->mnTitleType != BORDERWINDOW_TITLE_TEAROFF )
1716         {
1717             aInRect.Left()  += 2;
1718             aInRect.Right() -= 2;
1719 
1720             if ( !pData->maPinRect.IsEmpty() )
1721                 aInRect.Left() = pData->maPinRect.Right()+2;
1722 
1723             if ( !pData->maHelpRect.IsEmpty() )
1724                 aInRect.Right() = pData->maHelpRect.Left()-2;
1725             else if ( !pData->maRollRect.IsEmpty() )
1726                 aInRect.Right() = pData->maRollRect.Left()-2;
1727             else if ( !pData->maHideRect.IsEmpty() )
1728                 aInRect.Right() = pData->maHideRect.Left()-2;
1729             else if ( !pData->maDockRect.IsEmpty() )
1730                 aInRect.Right() = pData->maDockRect.Left()-2;
1731             else if ( !pData->maMenuRect.IsEmpty() )
1732                 aInRect.Right() = pData->maMenuRect.Left()-2;
1733             else if ( !pData->maCloseRect.IsEmpty() )
1734                 aInRect.Right() = pData->maCloseRect.Left()-2;
1735 
1736             if ( pOffset )
1737                 aInRect.Move( pOffset->X(), pOffset->Y() );
1738 
1739             sal_uInt16 nTextStyle = TEXT_DRAW_LEFT | TEXT_DRAW_VCENTER | TEXT_DRAW_ENDELLIPSIS | TEXT_DRAW_CLIP;
1740 
1741             // must show tooltip ?
1742             TextRectInfo aInfo;
1743             pDev->GetTextRect( aInRect, pBorderWindow->GetText(), nTextStyle, &aInfo );
1744             pData->mbTitleClipped = aInfo.IsEllipses();
1745 
1746             pDev->DrawText( aInRect, pBorderWindow->GetText(), nTextStyle );
1747         }
1748     }
1749 
1750     if ( ((nDrawFlags & BORDERWINDOW_DRAW_CLOSE) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
1751          !pData->maCloseRect.IsEmpty() )
1752     {
1753         Rectangle aSymbolRect( pData->maCloseRect );
1754         if ( pOffset )
1755             aSymbolRect.Move( pOffset->X(), pOffset->Y() );
1756         ImplDrawBrdWinSymbolButton( pDev, aSymbolRect, SYMBOL_CLOSE, pData->mnCloseState );
1757     }
1758     if ( ((nDrawFlags & BORDERWINDOW_DRAW_DOCK) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
1759          !pData->maDockRect.IsEmpty() )
1760     {
1761         Rectangle aSymbolRect( pData->maDockRect );
1762         if ( pOffset )
1763             aSymbolRect.Move( pOffset->X(), pOffset->Y() );
1764         ImplDrawBrdWinSymbolButton( pDev, aSymbolRect, SYMBOL_DOCK, pData->mnDockState );
1765     }
1766     if ( ((nDrawFlags & BORDERWINDOW_DRAW_MENU) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
1767          !pData->maMenuRect.IsEmpty() )
1768     {
1769         Rectangle aSymbolRect( pData->maMenuRect );
1770         if ( pOffset )
1771             aSymbolRect.Move( pOffset->X(), pOffset->Y() );
1772         ImplDrawBrdWinSymbolButton( pDev, aSymbolRect, SYMBOL_MENU, pData->mnMenuState );
1773     }
1774     if ( ((nDrawFlags & BORDERWINDOW_DRAW_HIDE) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
1775          !pData->maHideRect.IsEmpty() )
1776     {
1777         Rectangle aSymbolRect( pData->maHideRect );
1778         if ( pOffset )
1779             aSymbolRect.Move( pOffset->X(), pOffset->Y() );
1780         ImplDrawBrdWinSymbolButton( pDev, aSymbolRect, SYMBOL_HIDE, pData->mnHideState );
1781     }
1782     if ( ((nDrawFlags & BORDERWINDOW_DRAW_ROLL) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
1783          !pData->maRollRect.IsEmpty() )
1784     {
1785         SymbolType eType;
1786         if ( pBorderWindow->mbRollUp )
1787             eType = SYMBOL_ROLLDOWN;
1788         else
1789             eType = SYMBOL_ROLLUP;
1790         Rectangle aSymbolRect( pData->maRollRect );
1791         if ( pOffset )
1792             aSymbolRect.Move( pOffset->X(), pOffset->Y() );
1793         ImplDrawBrdWinSymbolButton( pDev, aSymbolRect, eType, pData->mnRollState );
1794     }
1795 
1796     if ( ((nDrawFlags & BORDERWINDOW_DRAW_HELP) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
1797          !pData->maHelpRect.IsEmpty() )
1798     {
1799         Rectangle aSymbolRect( pData->maHelpRect );
1800         if ( pOffset )
1801             aSymbolRect.Move( pOffset->X(), pOffset->Y() );
1802         ImplDrawBrdWinSymbolButton( pDev, aSymbolRect, SYMBOL_HELP, pData->mnHelpState );
1803     }
1804     if ( ((nDrawFlags & BORDERWINDOW_DRAW_PIN) || (nDrawFlags & BORDERWINDOW_DRAW_TITLE)) &&
1805          !pData->maPinRect.IsEmpty() )
1806     {
1807         Image aImage;
1808         ImplGetPinImage( pData->mnPinState, pBorderWindow->mbPined, aImage );
1809         Size  aImageSize = aImage.GetSizePixel();
1810         long  nRectHeight = pData->maPinRect.GetHeight();
1811         Point aPos( pData->maPinRect.TopLeft() );
1812         if ( pOffset )
1813             aPos.Move( pOffset->X(), pOffset->Y() );
1814         if ( nRectHeight < aImageSize.Height() )
1815         {
1816             pDev->DrawImage( aPos, Size( aImageSize.Width(), nRectHeight ), aImage );
1817         }
1818         else
1819         {
1820             aPos.Y() += (nRectHeight-aImageSize.Height())/2;
1821             pDev->DrawImage( aPos, aImage );
1822         }
1823     }
1824 }
1825 
1826 
1827 // =======================================================================
1828 void ImplBorderWindow::ImplInit( Window* pParent,
1829                                  WinBits nStyle, sal_uInt16 nTypeStyle,
1830                                  const ::com::sun::star::uno::Any& )
1831 {
1832     ImplInit( pParent, nStyle, nTypeStyle, NULL );
1833 }
1834 
1835 void ImplBorderWindow::ImplInit( Window* pParent,
1836                                  WinBits nStyle, sal_uInt16 nTypeStyle,
1837                                  SystemParentData* pSystemParentData
1838                                  )
1839 {
1840     // Alle WindowBits entfernen, die wir nicht haben wollen
1841     WinBits nOrgStyle = nStyle;
1842     WinBits nTestStyle = (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_PINABLE | WB_CLOSEABLE | WB_STANDALONE | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_SYSTEMFLOATWIN | WB_INTROWIN | WB_DEFAULTWIN | WB_TOOLTIPWIN | WB_NOSHADOW | WB_OWNERDRAWDECORATION | WB_SYSTEMCHILDWINDOW  | WB_NEEDSFOCUS);
1843     if ( nTypeStyle & BORDERWINDOW_STYLE_APP )
1844         nTestStyle |= WB_APP;
1845     nStyle &= nTestStyle;
1846 
1847     mpWindowImpl->mbBorderWin       = sal_True;
1848     mbSmallOutBorder    = sal_False;
1849     if ( nTypeStyle & BORDERWINDOW_STYLE_FRAME )
1850     {
1851         if( (nStyle & WB_SYSTEMCHILDWINDOW) )
1852         {
1853             mpWindowImpl->mbOverlapWin  = sal_True;
1854             mpWindowImpl->mbFrame       = sal_True;
1855             mbFrameBorder               = sal_False;
1856         }
1857         else if( (nStyle & WB_OWNERDRAWDECORATION) )
1858         {
1859             mpWindowImpl->mbOverlapWin  = sal_True;
1860             mpWindowImpl->mbFrame       = sal_True;
1861             mbFrameBorder   = (nOrgStyle & WB_NOBORDER) ? sal_False : sal_True;
1862         }
1863         else
1864         {
1865             mpWindowImpl->mbOverlapWin  = sal_True;
1866             mpWindowImpl->mbFrame       = sal_True;
1867             mbFrameBorder   = sal_False;
1868             // closeable windows may have a border as well, eg. system floating windows without caption
1869             if ( (nOrgStyle & (WB_BORDER | WB_NOBORDER | WB_MOVEABLE | WB_SIZEABLE/* | WB_CLOSEABLE*/)) == WB_BORDER )
1870                 mbSmallOutBorder = sal_True;
1871         }
1872     }
1873     else if ( nTypeStyle & BORDERWINDOW_STYLE_OVERLAP )
1874     {
1875         mpWindowImpl->mbOverlapWin  = sal_True;
1876         mbFrameBorder   = sal_True;
1877     }
1878     else
1879         mbFrameBorder   = sal_False;
1880 
1881     if ( nTypeStyle & BORDERWINDOW_STYLE_FLOAT )
1882         mbFloatWindow = sal_True;
1883     else
1884         mbFloatWindow = sal_False;
1885 
1886     Window::ImplInit( pParent, nStyle, pSystemParentData );
1887     SetBackground();
1888     SetTextFillColor();
1889 
1890     mpMenuBarWindow = NULL;
1891     mnMinWidth      = 0;
1892     mnMinHeight     = 0;
1893     mnMaxWidth      = SHRT_MAX;
1894     mnMaxHeight     = SHRT_MAX;
1895     mnRollHeight    = 0;
1896     mnOrgMenuHeight = 0;
1897     mbPined         = sal_False;
1898     mbRollUp        = sal_False;
1899     mbMenuHide      = sal_False;
1900     mbDockBtn       = sal_False;
1901     mbMenuBtn       = sal_False;
1902     mbHideBtn       = sal_False;
1903     mbHelpBtn       = sal_False;
1904     mbDisplayActive = IsActive();
1905 
1906     if ( nTypeStyle & BORDERWINDOW_STYLE_FLOAT )
1907         mnTitleType = BORDERWINDOW_TITLE_SMALL;
1908     else
1909         mnTitleType = BORDERWINDOW_TITLE_NORMAL;
1910     mnBorderStyle   = WINDOW_BORDER_NORMAL;
1911     InitView();
1912 }
1913 
1914 // =======================================================================
1915 
1916 ImplBorderWindow::ImplBorderWindow( Window* pParent,
1917                                     SystemParentData* pSystemParentData,
1918                                     WinBits nStyle, sal_uInt16 nTypeStyle
1919                                     ) : Window( WINDOW_BORDERWINDOW )
1920 {
1921     ImplInit( pParent, nStyle, nTypeStyle, pSystemParentData );
1922 }
1923 
1924 // -----------------------------------------------------------------------
1925 
1926 ImplBorderWindow::ImplBorderWindow( Window* pParent, WinBits nStyle ,
1927                                     sal_uInt16 nTypeStyle ) :
1928     Window( WINDOW_BORDERWINDOW )
1929 {
1930     ImplInit( pParent, nStyle, nTypeStyle, ::com::sun::star::uno::Any() );
1931 }
1932 
1933 ImplBorderWindow::ImplBorderWindow( Window* pParent,
1934                                     WinBits nStyle, sal_uInt16 nTypeStyle,
1935                                     const ::com::sun::star::uno::Any& aSystemToken ) :
1936     Window( WINDOW_BORDERWINDOW )
1937 {
1938     ImplInit( pParent, nStyle, nTypeStyle, aSystemToken );
1939 }
1940 
1941 // -----------------------------------------------------------------------
1942 
1943 ImplBorderWindow::~ImplBorderWindow()
1944 {
1945     delete mpBorderView;
1946 }
1947 
1948 // -----------------------------------------------------------------------
1949 
1950 void ImplBorderWindow::MouseMove( const MouseEvent& rMEvt )
1951 {
1952     mpBorderView->MouseMove( rMEvt );
1953 }
1954 
1955 // -----------------------------------------------------------------------
1956 
1957 void ImplBorderWindow::MouseButtonDown( const MouseEvent& rMEvt )
1958 {
1959     mpBorderView->MouseButtonDown( rMEvt );
1960 }
1961 
1962 // -----------------------------------------------------------------------
1963 
1964 void ImplBorderWindow::Tracking( const TrackingEvent& rTEvt )
1965 {
1966     mpBorderView->Tracking( rTEvt );
1967 }
1968 
1969 // -----------------------------------------------------------------------
1970 
1971 void ImplBorderWindow::Paint( const Rectangle& )
1972 {
1973     mpBorderView->DrawWindow( BORDERWINDOW_DRAW_ALL );
1974 }
1975 
1976 void ImplBorderWindow::Draw( const Rectangle&, OutputDevice* pOutDev, const Point& rPos )
1977 {
1978     mpBorderView->DrawWindow( BORDERWINDOW_DRAW_ALL, pOutDev, &rPos );
1979 }
1980 
1981 // -----------------------------------------------------------------------
1982 
1983 void ImplBorderWindow::Activate()
1984 {
1985     SetDisplayActive( sal_True );
1986     Window::Activate();
1987 }
1988 
1989 // -----------------------------------------------------------------------
1990 
1991 void ImplBorderWindow::Deactivate()
1992 {
1993     // Fenster die immer Active sind, nehmen wir von dieser Regel aus,
1994     // genauso, wenn ein Menu aktiv wird, ignorieren wir das Deactivate
1995     if ( GetActivateMode() && !ImplGetSVData()->maWinData.mbNoDeactivate )
1996         SetDisplayActive( sal_False );
1997     Window::Deactivate();
1998 }
1999 
2000 // -----------------------------------------------------------------------
2001 
2002 void ImplBorderWindow::RequestHelp( const HelpEvent& rHEvt )
2003 {
2004     // no keyboard help for border win
2005     if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) && !rHEvt.KeyboardActivated() )
2006     {
2007         Point       aMousePosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
2008         Rectangle   aHelpRect;
2009         String      aHelpStr( mpBorderView->RequestHelp( aMousePosPixel, aHelpRect ) );
2010 
2011         // Rechteck ermitteln
2012         if ( aHelpStr.Len() )
2013         {
2014             aHelpRect.SetPos( OutputToScreenPixel( aHelpRect.TopLeft() ) );
2015             if ( rHEvt.GetMode() & HELPMODE_BALLOON )
2016                 Help::ShowBalloon( this, aHelpRect.Center(), aHelpRect, aHelpStr );
2017             else
2018                 Help::ShowQuickHelp( this, aHelpRect, aHelpStr );
2019             return;
2020         }
2021     }
2022 
2023     Window::RequestHelp( rHEvt );
2024 }
2025 
2026 // -----------------------------------------------------------------------
2027 
2028 void ImplBorderWindow::Resize()
2029 {
2030     Size aSize = GetOutputSizePixel();
2031 
2032     if ( !mbRollUp )
2033     {
2034         Window* pClientWindow = ImplGetClientWindow();
2035 
2036         if ( mpMenuBarWindow )
2037         {
2038             sal_Int32 nLeftBorder;
2039             sal_Int32 nTopBorder;
2040             sal_Int32 nRightBorder;
2041             sal_Int32 nBottomBorder;
2042             long nMenuHeight = mpMenuBarWindow->GetSizePixel().Height();
2043             if ( mbMenuHide )
2044             {
2045                 if ( nMenuHeight )
2046                     mnOrgMenuHeight = nMenuHeight;
2047                 nMenuHeight = 0;
2048             }
2049             else
2050             {
2051                 if ( !nMenuHeight )
2052                     nMenuHeight = mnOrgMenuHeight;
2053             }
2054             mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
2055             mpMenuBarWindow->SetPosSizePixel( nLeftBorder,
2056                                               nTopBorder,
2057                                               aSize.Width()-nLeftBorder-nRightBorder,
2058                                               nMenuHeight,
2059                                               WINDOW_POSSIZE_POS |
2060                                               WINDOW_POSSIZE_WIDTH | WINDOW_POSSIZE_HEIGHT );
2061         }
2062 
2063         GetBorder( pClientWindow->mpWindowImpl->mnLeftBorder, pClientWindow->mpWindowImpl->mnTopBorder,
2064                    pClientWindow->mpWindowImpl->mnRightBorder, pClientWindow->mpWindowImpl->mnBottomBorder );
2065         pClientWindow->ImplPosSizeWindow( pClientWindow->mpWindowImpl->mnLeftBorder,
2066                                           pClientWindow->mpWindowImpl->mnTopBorder,
2067                                           aSize.Width()-pClientWindow->mpWindowImpl->mnLeftBorder-pClientWindow->mpWindowImpl->mnRightBorder,
2068                                           aSize.Height()-pClientWindow->mpWindowImpl->mnTopBorder-pClientWindow->mpWindowImpl->mnBottomBorder,
2069                                           WINDOW_POSSIZE_X | WINDOW_POSSIZE_Y |
2070                                           WINDOW_POSSIZE_WIDTH | WINDOW_POSSIZE_HEIGHT );
2071     }
2072 
2073     // UpdateView
2074     mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2075     InvalidateBorder();
2076 
2077     Window::Resize();
2078 }
2079 
2080 // -----------------------------------------------------------------------
2081 
2082 void ImplBorderWindow::StateChanged( StateChangedType nType )
2083 {
2084     if ( (nType == STATE_CHANGE_TEXT) ||
2085          (nType == STATE_CHANGE_IMAGE) ||
2086          (nType == STATE_CHANGE_DATA) )
2087     {
2088         if ( IsReallyVisible() && mbFrameBorder )
2089         {
2090             if ( HasPaintEvent() )
2091                 InvalidateBorder();
2092             else
2093                 mpBorderView->DrawWindow( BORDERWINDOW_DRAW_TITLE );
2094         }
2095     }
2096 
2097     Window::StateChanged( nType );
2098 }
2099 
2100 // -----------------------------------------------------------------------
2101 
2102 void ImplBorderWindow::DataChanged( const DataChangedEvent& rDCEvt )
2103 {
2104     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
2105          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
2106          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2107           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
2108     {
2109         if ( !mpWindowImpl->mbFrame || (GetStyle() & WB_OWNERDRAWDECORATION) )
2110             UpdateView( sal_True, ImplGetWindow()->GetOutputSizePixel() );
2111     }
2112 
2113     Window::DataChanged( rDCEvt );
2114 }
2115 
2116 // -----------------------------------------------------------------------
2117 
2118 void ImplBorderWindow::InitView()
2119 {
2120     if ( mbSmallOutBorder )
2121         mpBorderView = new ImplSmallBorderWindowView( this );
2122     else if ( mpWindowImpl->mbFrame )
2123     {
2124         if( mbFrameBorder )
2125             mpBorderView = new ImplStdBorderWindowView( this );
2126         else
2127             mpBorderView = new ImplNoBorderWindowView( this );
2128     }
2129     else if ( !mbFrameBorder )
2130         mpBorderView = new ImplSmallBorderWindowView( this );
2131     else
2132         mpBorderView = new ImplStdBorderWindowView( this );
2133     Size aSize = GetOutputSizePixel();
2134     mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2135 }
2136 
2137 // -----------------------------------------------------------------------
2138 
2139 void ImplBorderWindow::UpdateView( sal_Bool bNewView, const Size& rNewOutSize )
2140 {
2141     sal_Int32 nLeftBorder;
2142     sal_Int32 nTopBorder;
2143     sal_Int32 nRightBorder;
2144     sal_Int32 nBottomBorder;
2145     Size aOldSize = GetSizePixel();
2146     Size aOutputSize = rNewOutSize;
2147 
2148     if ( bNewView )
2149     {
2150         delete mpBorderView;
2151         InitView();
2152     }
2153     else
2154     {
2155         Size aSize = aOutputSize;
2156         mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
2157         aSize.Width()  += nLeftBorder+nRightBorder;
2158         aSize.Height() += nTopBorder+nBottomBorder;
2159         mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2160     }
2161 
2162     Window* pClientWindow = ImplGetClientWindow();
2163     if ( pClientWindow )
2164     {
2165         GetBorder( pClientWindow->mpWindowImpl->mnLeftBorder, pClientWindow->mpWindowImpl->mnTopBorder,
2166                    pClientWindow->mpWindowImpl->mnRightBorder, pClientWindow->mpWindowImpl->mnBottomBorder );
2167     }
2168     GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
2169     if ( aOldSize.Width() || aOldSize.Height() )
2170     {
2171         aOutputSize.Width()     += nLeftBorder+nRightBorder;
2172         aOutputSize.Height()    += nTopBorder+nBottomBorder;
2173         if ( aOutputSize == GetSizePixel() )
2174             InvalidateBorder();
2175         else
2176             SetSizePixel( aOutputSize );
2177     }
2178 }
2179 
2180 // -----------------------------------------------------------------------
2181 
2182 void ImplBorderWindow::InvalidateBorder()
2183 {
2184     if ( IsReallyVisible() )
2185     {
2186         // Nur wenn wir einen Border haben, muessen wir auch invalidieren
2187         sal_Int32 nLeftBorder;
2188         sal_Int32 nTopBorder;
2189         sal_Int32 nRightBorder;
2190         sal_Int32 nBottomBorder;
2191         mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
2192         if ( nLeftBorder || nTopBorder || nRightBorder || nBottomBorder )
2193         {
2194             Rectangle   aWinRect( Point( 0, 0 ), GetOutputSizePixel() );
2195             Region      aRegion( aWinRect );
2196             aWinRect.Left()   += nLeftBorder;
2197             aWinRect.Top()    += nTopBorder;
2198             aWinRect.Right()  -= nRightBorder;
2199             aWinRect.Bottom() -= nBottomBorder;
2200             // kein Output-Bereich mehr, dann alles invalidieren
2201             if ( (aWinRect.Right() < aWinRect.Left()) ||
2202                  (aWinRect.Bottom() < aWinRect.Top()) )
2203                 Invalidate( INVALIDATE_NOCHILDREN );
2204             else
2205             {
2206                 aRegion.Exclude( aWinRect );
2207                 Invalidate( aRegion, INVALIDATE_NOCHILDREN );
2208             }
2209         }
2210     }
2211 }
2212 
2213 // -----------------------------------------------------------------------
2214 
2215 void ImplBorderWindow::SetDisplayActive( sal_Bool bActive )
2216 {
2217     if ( mbDisplayActive != bActive )
2218     {
2219         mbDisplayActive = bActive;
2220         if ( mbFrameBorder )
2221             InvalidateBorder();
2222     }
2223 }
2224 
2225 // -----------------------------------------------------------------------
2226 
2227 void ImplBorderWindow::SetTitleType( sal_uInt16 nTitleType, const Size& rSize )
2228 {
2229     mnTitleType = nTitleType;
2230     UpdateView( sal_False, rSize );
2231 }
2232 
2233 // -----------------------------------------------------------------------
2234 
2235 void ImplBorderWindow::SetBorderStyle( sal_uInt16 nStyle )
2236 {
2237     if ( !mbFrameBorder && (mnBorderStyle != nStyle) )
2238     {
2239         mnBorderStyle = nStyle;
2240         UpdateView( sal_False, ImplGetWindow()->GetOutputSizePixel() );
2241     }
2242 }
2243 
2244 // -----------------------------------------------------------------------
2245 
2246 void ImplBorderWindow::SetPin( sal_Bool bPin )
2247 {
2248     mbPined = bPin;
2249     InvalidateBorder();
2250 }
2251 
2252 // -----------------------------------------------------------------------
2253 
2254 void ImplBorderWindow::SetRollUp( sal_Bool bRollUp, const Size& rSize )
2255 {
2256     mbRollUp = bRollUp;
2257     mnRollHeight = rSize.Height();
2258     UpdateView( sal_False, rSize );
2259 }
2260 
2261 // -----------------------------------------------------------------------
2262 
2263 void ImplBorderWindow::SetCloser()
2264 {
2265     SetStyle( GetStyle() | WB_CLOSEABLE );
2266     Size aSize = GetOutputSizePixel();
2267     mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2268     InvalidateBorder();
2269 }
2270 
2271 // -----------------------------------------------------------------------
2272 
2273 void ImplBorderWindow::SetDockButton( sal_Bool bDockButton )
2274 {
2275     mbDockBtn = bDockButton;
2276     Size aSize = GetOutputSizePixel();
2277     mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2278     InvalidateBorder();
2279 }
2280 
2281 // -----------------------------------------------------------------------
2282 
2283 void ImplBorderWindow::SetHideButton( sal_Bool bHideButton )
2284 {
2285     mbHideBtn = bHideButton;
2286     Size aSize = GetOutputSizePixel();
2287     mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2288     InvalidateBorder();
2289 }
2290 
2291 // -----------------------------------------------------------------------
2292 
2293 void ImplBorderWindow::SetHelpButton( sal_Bool bHelpButton )
2294 {
2295     mbHelpBtn = bHelpButton;
2296     Size aSize = GetOutputSizePixel();
2297     mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2298     InvalidateBorder();
2299 }
2300 
2301 // -----------------------------------------------------------------------
2302 
2303 void ImplBorderWindow::SetMenuButton( sal_Bool bMenuButton )
2304 {
2305     mbMenuBtn = bMenuButton;
2306     Size aSize = GetOutputSizePixel();
2307     mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2308     InvalidateBorder();
2309 }
2310 
2311 // -----------------------------------------------------------------------
2312 
2313 void ImplBorderWindow::UpdateMenuHeight()
2314 {
2315     Resize();
2316 }
2317 
2318 // -----------------------------------------------------------------------
2319 
2320 void ImplBorderWindow::SetMenuBarWindow( Window* pWindow )
2321 {
2322     mpMenuBarWindow = pWindow;
2323     UpdateMenuHeight();
2324     if ( pWindow )
2325         pWindow->Show();
2326 }
2327 
2328 // -----------------------------------------------------------------------
2329 
2330 void ImplBorderWindow::SetMenuBarMode( sal_Bool bHide )
2331 {
2332     mbMenuHide = bHide;
2333     UpdateMenuHeight();
2334 }
2335 
2336 // -----------------------------------------------------------------------
2337 
2338 void ImplBorderWindow::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
2339                                   sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
2340 {
2341     mpBorderView->GetBorder( rLeftBorder, rTopBorder, rRightBorder, rBottomBorder );
2342     if ( mpMenuBarWindow && !mbMenuHide )
2343         rTopBorder += mpMenuBarWindow->GetSizePixel().Height();
2344 }
2345 
2346 // -----------------------------------------------------------------------
2347 
2348 long ImplBorderWindow::CalcTitleWidth() const
2349 {
2350     return mpBorderView->CalcTitleWidth();
2351 }
2352 
2353 Rectangle ImplBorderWindow::GetMenuRect() const
2354 {
2355     return mpBorderView->GetMenuRect();
2356 }
2357