1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svimpicn.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
36 #include <vcl/metric.hxx>
38 #include <vcl/svapp.hxx>
40 #include <vcl/sound.hxx>
43 #include <svtools/svlbox.hxx>
44 #include <svtools/svicnvw.hxx>
45 #include <svimpicn.hxx>
47 #include <svtools/svlbitm.hxx>
49 #include <svtools/svarray.hxx>
53 #define VIEWMODE_ICON 0x0001 // Text unter Bitmap
54 #define VIEWMODE_NAME 0x0002 // Text rechts neben Bitmap
55 #define VIEWMODE_TEXT 0x0004 // Text ohne Bitmap
57 #define DD_SCROLL_PIXEL 10
59 // alle Angaben in Pixel
61 #define ICONVIEW_OFFS_BMP_STRING 3
63 // fuer das Bounding-Rectangle
64 #define LROFFS_BOUND 2
65 #define TBOFFS_BOUND 2
67 // fuer das Focus-Rectangle um Icons
71 #define NAMEVIEW_OFFS_BMP_STRING 3
73 // Abstaende von Fensterraendern
74 #define LROFFS_WINBORDER 4
75 #define TBOFFS_WINBORDER 4
77 // Breitenoffset Highlight-Rect bei Text
81 #define ICNVIEWDATA(xPtr) (SvIcnVwDataEntry*)(pView->GetViewDataEntry(xPtr))
82 #define ICNVIEWDATA2(xPtr) (SvIcnVwDataEntry*)(pView->pView->GetViewDataEntry(xPtr))
84 //--------------------------------------------------------------------------
85 //--------------------------------------------------------------------------
86 //--------------------------------------------------------------------------
87 // -------------------------------------------------------------------------
88 // Hilfsfunktionen von Thomas Hosemann zur mehrzeiligen Ausgabe von
89 // Strings. Die Funktionen werden spaeter in StarView integriert.
90 // -------------------------------------------------------------------------
91 //--------------------------------------------------------------------------
92 //--------------------------------------------------------------------------
93 //--------------------------------------------------------------------------
95 // keine doppelten Defines
99 #ifdef TEXT_DRAW_MULTILINE
100 #undef TEXT_DRAW_MULTILINE
102 #ifdef TEXT_DRAW_WORDBREAK
103 #undef TEXT_DRAW_WORDBREAK
106 // #define TEXT_DRAW_DISABLE ((USHORT)0x0001)
107 // #define TEXT_DRAW_3DLOOK ((USHORT)0x0002)
108 // #define TEXT_DRAW_MNEMONIC ((USHORT)0x0004)
109 #define TEXT_DRAW_LEFT ((USHORT)0x0010)
110 #define TEXT_DRAW_CENTER ((USHORT)0x0020)
111 #define TEXT_DRAW_RIGHT ((USHORT)0x0040)
112 #define TEXT_DRAW_TOP ((USHORT)0x0080)
113 #define TEXT_DRAW_VCENTER ((USHORT)0x0100)
114 #define TEXT_DRAW_BOTTOM ((USHORT)0x0200)
115 #define TEXT_DRAW_ENDELLIPSIS ((USHORT)0x0400)
116 #define TEXT_DRAW_PATHELLIPSIS ((USHORT)0x0800)
117 #define TEXT_DRAW_CLIP ((USHORT)0x1000)
118 #define TEXT_DRAW_MULTILINE ((USHORT)0x2000)
119 #define TEXT_DRAW_WORDBREAK ((USHORT)0x4000)
121 XubString
GetEllipsisString( OutputDevice
* pDev
,
122 const XubString
& rStr
, long nMaxWidth
,
123 USHORT nStyle
= TEXT_DRAW_ENDELLIPSIS
)
125 XubString aStr
= rStr
;
127 if ( nStyle
& TEXT_DRAW_ENDELLIPSIS
)
129 USHORT nIndex
= pDev
->GetTextBreak( rStr
, nMaxWidth
);
130 if ( nIndex
!= STRING_LEN
)
132 aStr
.Erase( nIndex
);
135 aStr
.AppendAscii("...");
136 while ( aStr
.Len() &&
137 (pDev
->GetTextWidth( aStr
) > nMaxWidth
) )
139 if ( (nIndex
> 1) || (nIndex
== aStr
.Len()) )
141 aStr
.Erase( nIndex
, 1 );
145 if ( !aStr
.Len() && (nStyle
& TEXT_DRAW_CLIP
) )
146 aStr
+= rStr
.GetChar( 0 );
161 TextLineInfo( long nWidth
, USHORT nIndex
, USHORT nLen
)
168 long GetWidth() const { return mnWidth
; }
169 USHORT
GetIndex() const { return mnIndex
; }
170 USHORT
GetLen() const { return mnLen
; }
173 #define MULTITEXTLINEINFO_RESIZE 16
174 typedef TextLineInfo
* PTextLineInfo
;
176 class MultiTextLineInfo
179 PTextLineInfo
* mpLines
;
185 ~MultiTextLineInfo();
187 void AddLine( TextLineInfo
* pLine
);
190 TextLineInfo
* GetLine( USHORT nLine
) const
191 { return mpLines
[nLine
]; }
192 USHORT
Count() const { return mnLines
; }
195 MultiTextLineInfo( const MultiTextLineInfo
& );
196 MultiTextLineInfo
& operator=( const MultiTextLineInfo
& );
199 MultiTextLineInfo::MultiTextLineInfo()
201 mpLines
= new PTextLineInfo
[MULTITEXTLINEINFO_RESIZE
];
203 mnSize
= MULTITEXTLINEINFO_RESIZE
;
206 MultiTextLineInfo::~MultiTextLineInfo()
208 for ( USHORT i
= 0; i
< mnLines
; i
++ )
213 void MultiTextLineInfo::AddLine( TextLineInfo
* pLine
)
215 if ( mnSize
== mnLines
)
217 mnSize
+= MULTITEXTLINEINFO_RESIZE
;
218 PTextLineInfo
* pNewLines
= new PTextLineInfo
[mnSize
];
219 memcpy( pNewLines
, mpLines
, mnLines
*sizeof(PTextLineInfo
) );
223 mpLines
[mnLines
] = pLine
;
227 void MultiTextLineInfo::Clear()
229 for ( USHORT i
= 0; i
< mnLines
; i
++ )
234 // -----------------------------------------------------------------------
236 long GetTextLines( OutputDevice
* pDev
, MultiTextLineInfo
& rLineInfo
,
237 long nWidth
, const XubString
& rStr
,
238 USHORT nStyle
= TEXT_DRAW_WORDBREAK
)
246 USHORT nStartPos
= 0; // Start-Position der Zeile
247 USHORT nLastLineLen
= 0; // Zeilenlaenge bis zum vorherigen Wort
248 USHORT nLastWordPos
= 0; // Position des letzten Wortanfangs
250 USHORT nPos
; // StartPositon der Zeile (nur Temp)
251 USHORT nLen
; // Laenge der Zeile (nur Temp)
252 USHORT nStrLen
= rStr
.Len();
253 long nMaxLineWidth
= 0; // Maximale Zeilenlaenge
254 long nLineWidth
; // Aktuelle Zeilenlaenge
255 long nLastLineWidth
= 0; // Zeilenlaenge der letzten Zeile
258 const xub_Unicode
* pStr
= rStr
.GetBuffer();
259 BOOL bHardBreak
= FALSE
;
265 // Auf Zeilenende ermitteln
266 if ( (c
== _CR
) || (c
== _LF
) )
271 // Testen, ob ein Wortende erreicht ist
272 if ( bHardBreak
|| (i
== nStrLen
) ||
273 (((c
== ' ') || (c
== '-')) && (nStyle
& TEXT_DRAW_WORDBREAK
)) )
278 nLineWidth
= pDev
->GetTextWidth( rStr
, nStartPos
, nLen
);
280 // Findet ein Zeilenumbruch statt
281 if ( bHardBreak
|| (i
== nStrLen
) ||
282 ((nLineWidth
>= nWidth
) && (nStyle
& TEXT_DRAW_WORDBREAK
)) )
286 if ( (nLineWidth
>= nWidth
) && (nStyle
& TEXT_DRAW_WORDBREAK
) )
288 nLineWidth
= nLastLineWidth
;
290 nStartPos
= nLastWordPos
;
291 nLastLineLen
= i
-nStartPos
;
292 nLastWordPos
= nStartPos
+nLastLineLen
+1;
295 else if ( bHardBreak
&& (i
> nStartPos
) )
301 // Zeilenende-Zeichen und '-' beruecksichtigen
306 if ( (c
!= c2
) && ((c2
== _CR
) || (c2
== _LF
)) )
314 nLastWordPos
= nStartPos
;
318 if ( nLineWidth
> nMaxLineWidth
)
319 nMaxLineWidth
= nLineWidth
;
321 if ( nLen
|| bHardBreak
)
322 rLineInfo
.AddLine( new TextLineInfo( nLineWidth
, nPos
, nLen
) );
324 // Testen, ob aktuelles Wort noch auf die Zeile passt,
325 // denn ansonsten mueessen wir es auftrennen
328 nLineWidth
= pDev
->GetTextWidth( rStr
, nStartPos
, nLastLineLen
);
329 if ( nLineWidth
> nWidth
)
331 // Wenn ein Wortumbruch in einem Wort stattfindet,
332 // ist die maximale Zeilenlaenge die Laenge
333 // des laengsten Wortes
334 if ( nLineWidth
> nMaxLineWidth
)
335 nMaxLineWidth
= nLineWidth
;
337 // Solange Wort auftrennen, bis es auf eine Zeile passt
340 nPos
= pDev
->GetTextBreak( rStr
, nWidth
, nStartPos
, nLastLineLen
);
341 nLen
= nPos
-nStartPos
;
347 nLineWidth
= pDev
->GetTextWidth( rStr
, nStartPos
, nLen
);
348 rLineInfo
.AddLine( new TextLineInfo( nLineWidth
, nStartPos
, nLen
) );
350 nLastLineLen
= nLastLineLen
- nLen
;
351 nLineWidth
= pDev
->GetTextWidth( rStr
, nStartPos
, nLastLineLen
);
353 while ( nLineWidth
> nWidth
);
355 nLastLineWidth
= nLineWidth
;
357 // Bei Stringende muessen wir die letzte Zeile auch noch
359 if ( (i
== nStrLen
) && nLastLineLen
)
360 rLineInfo
.AddLine( new TextLineInfo( nLastLineWidth
, nStartPos
, nLastLineLen
) );
367 nLastLineWidth
= nLineWidth
;
369 nLastWordPos
= nStartPos
+nLastLineLen
;
377 while ( i
<= nStrLen
);
379 return nMaxLineWidth
;
382 // -----------------------------------------------------------------------
384 USHORT
GetTextLines( OutputDevice
* pDev
, const Rectangle
& rRect
,
385 const XubString
& rStr
,
386 USHORT nStyle
= TEXT_DRAW_WORDBREAK
,
387 long* pMaxWidth
= NULL
)
389 MultiTextLineInfo aMultiLineInfo
;
390 long nMaxWidth
= GetTextLines( pDev
, aMultiLineInfo
,
391 rRect
.GetWidth(), rStr
, nStyle
);
393 *pMaxWidth
= nMaxWidth
;
394 return aMultiLineInfo
.Count();
397 // -----------------------------------------------------------------------
399 Rectangle
GetTextRect( OutputDevice
* pDev
, const Rectangle
& rRect
,
400 const XubString
& rStr
,
401 USHORT nStyle
= TEXT_DRAW_WORDBREAK
)
403 Rectangle aRect
= rRect
;
405 long nWidth
= rRect
.GetWidth();
409 if ( nStyle
& TEXT_DRAW_MULTILINE
)
411 MultiTextLineInfo aMultiLineInfo
;
412 TextLineInfo
* pLineInfo
;
416 GetTextLines( pDev
, aMultiLineInfo
, nWidth
, rStr
, nStyle
);
417 nFormatLines
= aMultiLineInfo
.Count();
418 nTextHeight
= pDev
->GetTextHeight();
419 nLines
= (USHORT
)(aRect
.GetHeight()/nTextHeight
);
420 if ( nFormatLines
<= nLines
)
421 nLines
= nFormatLines
;
424 if ( !(nStyle
& TEXT_DRAW_ENDELLIPSIS
) )
425 nLines
= nFormatLines
;
429 for ( USHORT i
= 0; i
< nLines
; i
++ )
431 pLineInfo
= aMultiLineInfo
.GetLine( i
);
432 if ( pLineInfo
->GetWidth() > nMaxWidth
)
433 nMaxWidth
= pLineInfo
->GetWidth();
439 nMaxWidth
= pDev
->GetTextWidth( rStr
);
440 nTextHeight
= pDev
->GetTextHeight();
441 if ( (nMaxWidth
> nWidth
) && (nStyle
& TEXT_DRAW_ENDELLIPSIS
) )
445 if ( nStyle
& TEXT_DRAW_RIGHT
)
446 aRect
.Left() = aRect
.Right()-nMaxWidth
+1;
447 else if ( nStyle
& TEXT_DRAW_CENTER
)
449 aRect
.Left() += (nWidth
-nMaxWidth
)/2;
450 aRect
.Right() = aRect
.Left()+nMaxWidth
-1;
453 aRect
.Right() = aRect
.Left()+nMaxWidth
-1;
455 if ( nStyle
& TEXT_DRAW_BOTTOM
)
456 aRect
.Top() = aRect
.Bottom()-(nTextHeight
*nLines
)+1;
457 else if ( nStyle
& TEXT_DRAW_VCENTER
)
459 aRect
.Top() += (aRect
.GetHeight()-(nTextHeight
*nLines
))/2;
460 aRect
.Bottom() = aRect
.Top()+(nTextHeight
*nLines
)-1;
463 aRect
.Bottom() = aRect
.Top()+(nTextHeight
*nLines
)-1;
468 // -----------------------------------------------------------------------
470 void DrawText( OutputDevice
* pDev
, const Rectangle
& rRect
,
471 const XubString
& rStr
, USHORT nStyle
= 0 )
473 if ( !rStr
.Len() || rRect
.IsEmpty() )
476 Point aPos
= rRect
.TopLeft();
477 long nWidth
= rRect
.GetWidth();
478 long nHeight
= rRect
.GetHeight();
479 FontAlign eAlign
= pDev
->GetFont().GetAlign();
481 if ( ((nWidth
<= 0) || (nHeight
<= 0)) && (nStyle
& TEXT_DRAW_CLIP
) )
484 // Mehrzeiligen Text behandeln wir anders
485 if ( nStyle
& TEXT_DRAW_MULTILINE
)
489 MultiTextLineInfo aMultiLineInfo
;
490 TextLineInfo
* pLineInfo
;
491 long nTextHeight
= pDev
->GetTextHeight();
494 USHORT nLines
= (USHORT
)(nHeight
/nTextHeight
);
496 BOOL bIsClipRegion
= FALSE
;
497 nMaxTextWidth
= GetTextLines( pDev
, aMultiLineInfo
, nWidth
, rStr
, nStyle
);
499 nFormatLines
= aMultiLineInfo
.Count();
500 if ( nFormatLines
> nLines
)
502 if ( nStyle
& TEXT_DRAW_ENDELLIPSIS
)
504 // Letzte Zeile zusammenbauen und kuerzen
505 nFormatLines
= nLines
-1;
506 pLineInfo
= aMultiLineInfo
.GetLine( nFormatLines
);
507 aLastLine
= rStr
.Copy( pLineInfo
->GetIndex() );
508 aLastLine
.ConvertLineEnd( LINEEND_LF
);
509 aLastLine
.SearchAndReplace( _LF
, ' ' );
510 aLastLine
= GetEllipsisString( pDev
, aLastLine
, nWidth
, nStyle
);
511 nStyle
&= ~(TEXT_DRAW_VCENTER
| TEXT_DRAW_BOTTOM
);
512 nStyle
|= TEXT_DRAW_TOP
;
517 if ( nMaxTextWidth
<= nWidth
)
518 nStyle
&= ~TEXT_DRAW_CLIP
;
522 if ( nStyle
& TEXT_DRAW_CLIP
)
524 bIsClipRegion
= pDev
->IsClipRegion();
527 aOldRegion
= pDev
->GetClipRegion();
528 pDev
->IntersectClipRegion( rRect
);
532 Region
aRegion( rRect
);
533 pDev
->SetClipRegion( aRegion
);
537 // Vertikales Alignment
538 if ( nStyle
& TEXT_DRAW_BOTTOM
)
539 aPos
.Y() += nHeight
-(nFormatLines
*nTextHeight
);
540 else if ( nStyle
& TEXT_DRAW_VCENTER
)
541 aPos
.Y() += (nHeight
-(nFormatLines
*nTextHeight
))/2;
544 if ( eAlign
== ALIGN_BOTTOM
)
545 aPos
.Y() += nTextHeight
;
546 else if ( eAlign
== ALIGN_BASELINE
)
547 aPos
.Y() += pDev
->GetFontMetric().GetAscent();
549 // Alle Zeilen ausgeben, bis auf die letzte
550 for ( i
= 0; i
< nFormatLines
; i
++ )
552 pLineInfo
= aMultiLineInfo
.GetLine( i
);
553 if ( nStyle
& TEXT_DRAW_RIGHT
)
554 aPos
.X() += nWidth
-pLineInfo
->GetWidth();
555 else if ( nStyle
& TEXT_DRAW_CENTER
)
556 aPos
.X() += (nWidth
-pLineInfo
->GetWidth())/2;
557 pDev
->DrawText( aPos
, rStr
, pLineInfo
->GetIndex(), pLineInfo
->GetLen() );
558 aPos
.Y() += nTextHeight
;
559 aPos
.X() = rRect
.Left();
562 // Gibt es noch eine letzte Zeile, dann diese linksbuendig ausgeben,
563 // da die Zeile gekuerzt wurde
564 if ( aLastLine
.Len() )
565 pDev
->DrawText( aPos
, aLastLine
);
567 // Clipping zuruecksetzen
568 if ( nStyle
& TEXT_DRAW_CLIP
)
571 pDev
->SetClipRegion( aOldRegion
);
573 pDev
->SetClipRegion();
578 XubString aStr
= rStr
;
579 Size
aTextSize(pDev
->GetTextWidth( aStr
), pDev
->GetTextHeight());
582 if ( aTextSize
.Width() > nWidth
)
584 if ( nStyle
& TEXT_DRAW_ENDELLIPSIS
)
586 aStr
= GetEllipsisString( pDev
, rStr
, nWidth
, nStyle
);
587 nStyle
&= ~(TEXT_DRAW_CENTER
| TEXT_DRAW_RIGHT
);
588 nStyle
|= TEXT_DRAW_LEFT
;
589 aTextSize
.Width() = pDev
->GetTextWidth(aStr
);
594 if ( aTextSize
.Height() <= nHeight
)
595 nStyle
&= ~TEXT_DRAW_CLIP
;
598 // Vertikales Alignment
599 if ( nStyle
& TEXT_DRAW_RIGHT
)
600 aPos
.X() += nWidth
-aTextSize
.Width();
601 else if ( nStyle
& TEXT_DRAW_CENTER
)
602 aPos
.X() += (nWidth
-aTextSize
.Width())/2;
605 if ( eAlign
== ALIGN_BOTTOM
)
606 aPos
.Y() += aTextSize
.Height();
607 else if ( eAlign
== ALIGN_BASELINE
)
608 aPos
.Y() += pDev
->GetFontMetric().GetAscent();
610 if ( nStyle
& TEXT_DRAW_BOTTOM
)
611 aPos
.Y() += nHeight
-aTextSize
.Height();
612 else if ( nStyle
& TEXT_DRAW_VCENTER
)
613 aPos
.Y() += (nHeight
-aTextSize
.Height())/2;
615 if ( nStyle
& TEXT_DRAW_CLIP
)
617 BOOL bIsClipRegion
= pDev
->IsClipRegion();
620 Region aOldRegion
= pDev
->GetClipRegion();
621 pDev
->IntersectClipRegion( rRect
);
622 pDev
->DrawText( aPos
, aStr
);
623 pDev
->SetClipRegion( aOldRegion
);
627 Region
aRegion( rRect
);
628 pDev
->SetClipRegion( aRegion
);
629 pDev
->DrawText( aPos
, aStr
);
630 pDev
->SetClipRegion();
634 pDev
->DrawText( aPos
, aStr
);
638 // -----------------------------------------------------------------------
641 //--------------------------------------------------------------------------
642 //--------------------------------------------------------------------------
643 //--------------------------------------------------------------------------
646 #define DRAWTEXT_FLAGS (TEXT_DRAW_CENTER|TEXT_DRAW_TOP|TEXT_DRAW_ENDELLIPSIS|\
647 TEXT_DRAW_CLIP|TEXT_DRAW_MULTILINE|TEXT_DRAW_WORDBREAK)
652 SvImpIconView
* pView
;
656 long nGridDX
, nGridDY
;
657 long nGridCols
, nGridRows
;
662 SvLBoxEntry
* pCurEntry
;
665 void Create() { if( !pColumns
) ImplCreate(); }
667 USHORT
GetSortListPos( SvPtrarr
* pList
, long nValue
, int bVertical
);
668 SvLBoxEntry
* SearchCol(USHORT nCol
,USHORT nTop
,USHORT nBottom
,USHORT nPref
,
669 BOOL bDown
, BOOL bSimple
);
670 SvLBoxEntry
* SearchRow(USHORT nRow
,USHORT nRight
,USHORT nLeft
,USHORT nPref
,
671 BOOL bRight
, BOOL bSimple
);
674 void CreateGridMap();
675 // Rueckgabe FALSE: Eintrag liegt nicht in der GridMap. rGridx,y werden
676 // dann an nGridCols, nGridRows geclippt
677 BOOL
GetGrid( const Point
& rDocPos
, USHORT
& rGridX
, USHORT
& rGridY
) const;
678 void SetGridUsed( USHORT nDX
, USHORT nDY
, BOOL bUsed
)
680 pGridMap
[ (nDY
* nGridCols
) + nDX
] = bUsed
;
682 BOOL
IsGridUsed( USHORT nDX
, USHORT nDY
)
684 return pGridMap
[ (nDY
* nGridCols
) + nDX
];
687 ImpIcnCursor( SvImpIconView
* pOwner
);
689 void Clear( BOOL bGridToo
= TRUE
);
691 // fuer Cursortravelling usw.
692 SvLBoxEntry
* GoLeftRight( SvLBoxEntry
*, BOOL bRight
);
693 SvLBoxEntry
* GoUpDown( SvLBoxEntry
*, BOOL bDown
);
695 // Rueckgaebe: FALSE == Das leere Rect steht hinter dem letzten
696 // Eintrag; d.h. beim naechsten Einfuegen ergibt sich das naechste
697 // leere Rechteck durch Addition. Hinweis: Das Rechteck kann dann
698 // ausserhalb des View-Space liegen
699 BOOL
FindEmptyGridRect( Rectangle
& rRect
);
701 // Erzeugt fuer jede Zeile (Hoehe=nGridDY) eine nach BoundRect.Left()
702 // sortierte Liste der Eintraege, die in ihr stehen. Eine Liste kann
703 // leer sein. Die Listen gehen in das Eigentum des Rufenden ueber und
704 // muessen mit DestroyGridAdjustData geloescht werden
705 void CreateGridAjustData( SvPtrarr
& pLists
, SvLBoxEntry
* pRow
=0);
706 static void DestroyGridAdjustData( SvPtrarr
& rLists
);
707 void SetGridUsed( const Rectangle
&, BOOL bUsed
= TRUE
);
713 SvImpIconView::SvImpIconView( SvIconView
* pCurView
, SvLBoxTreeList
* pTree
,
714 WinBits nWinStyle
) :
715 aVerSBar( pCurView
, WB_DRAG
| WB_VSCROLL
),
716 aHorSBar( pCurView
, WB_DRAG
| WB_HSCROLL
)
721 pZOrderList
= new SvPtrarr
;
722 SetWindowBits( nWinStyle
);
732 eTextMode
= ShowTextShort
;
733 pImpCursor
= new ImpIcnCursor( this );
735 aVerSBar
.SetScrollHdl( LINK( this, SvImpIconView
, ScrollUpDownHdl
) );
736 aHorSBar
.SetScrollHdl( LINK( this, SvImpIconView
, ScrollLeftRightHdl
) );
737 nHorSBarHeight
= aHorSBar
.GetSizePixel().Height();
738 nVerSBarWidth
= aVerSBar
.GetSizePixel().Width();
740 aMouseMoveTimer
.SetTimeout( 20 );
741 aMouseMoveTimer
.SetTimeoutHdl(LINK(this,SvImpIconView
,MouseMoveTimeoutHdl
));
743 aEditTimer
.SetTimeout( 800 );
744 aEditTimer
.SetTimeoutHdl(LINK(this,SvImpIconView
,EditTimeoutHdl
));
749 SvImpIconView::~SvImpIconView()
758 ClearSelectedRectList();
761 void SvImpIconView::Clear( BOOL bInCtor
)
768 bMustRecalcBoundingRects
= FALSE
;
772 nFlags
|= F_GRID_INSERT
;
773 nFlags
&= ~F_PAINTED
;
774 SetNextEntryPos( Point( LROFFS_WINBORDER
, TBOFFS_WINBORDER
) );
779 aVirtOutputSize
.Width() = 0;
780 aVirtOutputSize
.Height() = 0;
781 pZOrderList
->Remove(0,pZOrderList
->Count());
782 MapMode
aMapMode( pView
->GetMapMode());
783 aMapMode
.SetOrigin( Point() );
784 pView
->SetMapMode( aMapMode
);
785 if( pView
->IsUpdateMode() )
791 void SvImpIconView::SetWindowBits( WinBits nWinStyle
)
793 nWinBits
= nWinStyle
;
794 nViewMode
= VIEWMODE_TEXT
;
795 if( nWinStyle
& WB_NAME
)
796 nViewMode
= VIEWMODE_NAME
;
797 if( nWinStyle
& WB_ICON
)
798 nViewMode
= VIEWMODE_ICON
;
802 IMPL_LINK( SvImpIconView
, ScrollUpDownHdl
, ScrollBar
*, pScrollBar
)
804 pView
->EndEditing( TRUE
);
805 // Pfeil hoch: delta=-1; Pfeil runter: delta=+1
806 Scroll( 0, pScrollBar
->GetDelta(), TRUE
);
810 IMPL_LINK( SvImpIconView
, ScrollLeftRightHdl
, ScrollBar
*, pScrollBar
)
812 pView
->EndEditing( TRUE
);
813 // Pfeil links: delta=-1; Pfeil rechts: delta=+1
814 Scroll( pScrollBar
->GetDelta(), 0, TRUE
);
818 void SvImpIconView::ChangedFont()
825 void SvImpIconView::CheckAllSizes()
830 SvLBoxEntry
* pEntry
= pModel
->First();
833 CheckSizes( pEntry
);
834 pEntry
= pModel
->Next( pEntry
);
838 void SvImpIconView::CheckSizes( SvLBoxEntry
* pEntry
,
839 const SvIcnVwDataEntry
* pViewData
)
844 pViewData
= ICNVIEWDATA(pEntry
);
846 SvLBoxString
* pStringItem
= (SvLBoxString
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
849 aSize
= GetItemSize( pView
, pEntry
, pStringItem
, pViewData
);
850 if( aSize
.Width() > nMaxTextWidth
)
852 nMaxTextWidth
= aSize
.Width();
853 if( !(nFlags
& F_GRIDMODE
) )
854 bMustRecalcBoundingRects
= TRUE
;
857 SvLBoxContextBmp
* pBmpItem
= (SvLBoxContextBmp
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
860 aSize
= GetItemSize( pView
, pEntry
, pBmpItem
, pViewData
);
861 if( aSize
.Width() > nMaxBmpWidth
)
863 nMaxBmpWidth
= aSize
.Width();
864 nMaxBmpWidth
+= (2*LROFFS_ICON
);
865 if( !(nFlags
& F_GRIDMODE
) )
866 bMustRecalcBoundingRects
= TRUE
;
868 if( aSize
.Height() > nMaxBmpHeight
)
870 nMaxBmpHeight
= aSize
.Height();
871 nMaxBmpHeight
+= (2*TBOFFS_ICON
);;
872 if( !(nFlags
& F_GRIDMODE
) )
873 bMustRecalcBoundingRects
= TRUE
;
878 void SvImpIconView::EntryInserted( SvLBoxEntry
* pEntry
)
880 if( pModel
->GetParent(pEntry
) == pCurParent
)
883 DBG_ASSERT(pZOrderList
->GetPos(pEntry
)==0xffff,"EntryInserted:ZOrder?");
884 pZOrderList
->Insert( pEntry
, pZOrderList
->Count() );
885 if( nFlags
& F_GRIDMODE
)
886 pImpCursor
->Clear( FALSE
);
888 pImpCursor
->Clear( TRUE
);
889 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
890 CheckSizes( pEntry
, pViewData
);
891 if( pView
->IsUpdateMode() )
893 FindBoundingRect( pEntry
, pViewData
);
894 PaintEntry( pEntry
, pViewData
);
897 InvalidateBoundingRect( pViewData
->aRect
);
901 void SvImpIconView::RemovingEntry( SvLBoxEntry
* pEntry
)
903 if( pModel
->GetParent(pEntry
) == pCurParent
)
906 DBG_ASSERT(pZOrderList
->GetPos(pEntry
)!=0xffff,"RemovingEntry:ZOrder?");
907 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
908 if( IsBoundingRectValid( pViewData
->aRect
) )
910 // bei gueltigem Bounding-Rect muss in EntryRemoved eine
911 // Sonderbehandlung erfolgen
912 nFlags
|= F_ENTRY_REMOVED
;
913 pView
->Invalidate( pViewData
->aRect
);
915 if( pEntry
== pCursor
)
917 SvLBoxEntry
* pNewCursor
= GetNewCursor();
919 pCursor
= 0; // damit er nicht deselektiert wird
920 SetCursor( pNewCursor
);
922 USHORT nPos
= pZOrderList
->GetPos( (void*)pEntry
);
923 pZOrderList
->Remove( nPos
, 1 );
928 void SvImpIconView::EntryRemoved()
930 if( (nFlags
& (F_ENTRY_REMOVED
| F_PAINTED
)) == (F_ENTRY_REMOVED
| F_PAINTED
))
932 // Ein Eintrag mit gueltigem BoundRect wurde geloescht und wir
933 // haben schon mal gepaintet. In diesem Fall muessen wir die
934 // Position des naechsten Eintrags, der eingefuegt wird oder noch
935 // kein gueltiges BoundRect hat, "suchen" d.h. ein "Loch" in
936 // der View auffuellen.
937 nFlags
&= ~( F_ENTRY_REMOVED
| F_GRID_INSERT
);
942 void SvImpIconView::MovingEntry( SvLBoxEntry
* pEntry
)
944 DBG_ASSERT(pEntry
,"MovingEntry: 0!");
947 if( pModel
->GetParent(pEntry
) == pCurParent
)
949 DBG_ASSERT(pZOrderList
->GetPos(pEntry
)!=0xffff,"MovingEntry:ZOrder?");
950 nFlags
|= F_MOVING_SIBLING
;
951 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
952 if( IsBoundingRectValid( pViewData
->aRect
) )
953 pView
->Invalidate( pViewData
->aRect
);
954 // falls Eintrag seinen Parent wechselt vorsichtshalber
955 // die neue Cursorposition berechnen
956 if( pEntry
== pCursor
)
957 pNextCursor
= GetNewCursor();
963 void SvImpIconView::EntryMoved( SvLBoxEntry
* pEntry
)
966 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
967 if( pModel
->GetParent(pEntry
)==pCurParent
)
969 if( nFlags
& F_MOVING_SIBLING
)
971 // die Neu-Positionierung eines Eintrags bei D&D innerhalb
972 // einer IconView findet bereits in NotifyMoving statt
973 // (MovingEntry/EntryMoved wird dann nicht mehr gerufen)
979 pZOrderList
->Insert( pEntry
, pZOrderList
->Count() );
980 DBG_ASSERT(pZOrderList
->Count()==pModel
->GetChildCount(pCurParent
),"EntryMoved:Bad zorder count");
981 FindBoundingRect( pEntry
, pViewData
);
983 PaintEntry( pEntry
, pViewData
);
987 if( pEntry
== pCursor
)
989 DBG_ASSERT(pNextCursor
,"EntryMoved: Next cursor bad");
990 SetCursor( pNextCursor
);
993 USHORT nPos
= pZOrderList
->GetPos( (void*)pEntry
);
994 pZOrderList
->Remove( nPos
, 1 );
995 pView
->Select( pEntry
, FALSE
);
996 // wenn er nochmal in dieser View auftaucht, muss sein
997 // Bounding-Rect neu berechnet werden
998 InvalidateBoundingRect( pViewData
->aRect
);
1000 nFlags
&= (~F_MOVING_SIBLING
);
1003 void SvImpIconView::TreeInserted( SvLBoxEntry
* pEntry
)
1005 EntryMoved( pEntry
); // vorlaeufig
1008 void SvImpIconView::EntryExpanded( SvLBoxEntry
* )
1012 void SvImpIconView::EntryCollapsed( SvLBoxEntry
*)
1016 void SvImpIconView::CollapsingEntry( SvLBoxEntry
* )
1020 void SvImpIconView::EntrySelected( SvLBoxEntry
* pEntry
, BOOL bSelect
)
1022 if( pModel
->GetParent(pEntry
) != pCurParent
)
1025 // bei SingleSelection dafuer sorgen, dass der Cursor immer
1026 // auf dem (einzigen) selektierten Eintrag steht
1027 if( bSelect
&& pCursor
&&
1028 pView
->GetSelectionMode() == SINGLE_SELECTION
&&
1031 SetCursor( pEntry
);
1032 DBG_ASSERT(pView
->GetSelectionCount()==1,"selection count?");
1034 // bei Gummibandselektion ist uns das zu teuer
1035 if( !(nFlags
& F_RUBBERING
))
1037 if( pView
->IsUpdateMode() )
1039 if( pEntry
== pCursor
)
1040 ShowCursor( FALSE
);
1041 if( nFlags
& F_RUBBERING
)
1042 PaintEntry( pEntry
);
1044 pView
->Invalidate( GetBoundingRect( pEntry
) );
1045 if( pEntry
== pCursor
)
1050 void SvImpIconView::SetNextEntryPos(const Point
& rPos
)
1052 aPrevBoundRect
.SetPos( rPos
);
1053 aPrevBoundRect
.Right() = LONG_MAX
; // dont know
1056 Point
SvImpIconView::FindNextEntryPos( const Size
& rBoundSize
)
1058 if( nFlags
& F_GRIDMODE
)
1060 if( nFlags
& F_GRID_INSERT
)
1062 if( aPrevBoundRect
.Right() != LONG_MAX
)
1064 // passt der naechste Entry noch in die Zeile ?
1065 long nNextWidth
= aPrevBoundRect
.Right() + nGridDX
+ LROFFS_WINBORDER
;
1066 if( nNextWidth
> aVirtOutputSize
.Width() )
1068 // darf aVirtOutputSize verbreitert werden ?
1069 if( nNextWidth
< nMaxVirtWidth
)
1071 // verbreitern & in Zeile aufnehmen
1072 aPrevBoundRect
.Left() += nGridDX
;
1076 // erhoehen & neue Zeile beginnen
1077 aPrevBoundRect
.Top() += nGridDY
;
1078 aPrevBoundRect
.Left() = LROFFS_WINBORDER
;
1083 // in die Zeile aufnehmen
1084 aPrevBoundRect
.Left() += nGridDX
;
1087 aPrevBoundRect
.SetSize( Size( nGridDX
, nGridDY
) );
1091 if( !pImpCursor
->FindEmptyGridRect( aPrevBoundRect
) )
1093 // mitten in den Entries gibts keine Loecher mehr,
1094 // wir koennen also wieder ins "Fast Insert" springen
1095 nFlags
|= F_GRID_INSERT
;
1101 if( aPrevBoundRect
.Right() != LONG_MAX
)
1103 // passt der naechste Entry noch in die Zeile ?
1104 long nNextWidth
=aPrevBoundRect
.Right()+rBoundSize
.Width()+LROFFS_BOUND
+nHorDist
;
1105 if( nNextWidth
> aVirtOutputSize
.Width() )
1107 // darf aVirtOutputSize verbreitert werden ?
1108 if( nNextWidth
< nMaxVirtWidth
)
1110 // verbreitern & in Zeile aufnehmen
1111 aPrevBoundRect
.SetPos( aPrevBoundRect
.TopRight() );
1112 aPrevBoundRect
.Left() += nHorDist
;
1116 // erhoehen & neue Zeile beginnen
1117 aPrevBoundRect
.Top() += nMaxBoundHeight
+ nVerDist
+ TBOFFS_BOUND
;
1118 aPrevBoundRect
.Left() = LROFFS_WINBORDER
;
1123 // in die Zeile aufnehmen
1124 aPrevBoundRect
.SetPos( aPrevBoundRect
.TopRight() );
1125 aPrevBoundRect
.Left() += nHorDist
;
1128 aPrevBoundRect
.SetSize( rBoundSize
);
1130 return aPrevBoundRect
.TopLeft();
1133 void SvImpIconView::ResetVirtSize()
1136 aVirtOutputSize
.Width() = 0;
1137 aVirtOutputSize
.Height() = 0;
1138 BOOL bLockedEntryFound
= FALSE
;
1139 nFlags
&= (~F_GRID_INSERT
);
1140 SvLBoxEntry
* pCur
= pModel
->FirstChild( pCurParent
);
1143 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pCur
);
1144 if( pViewData
->IsEntryPosLocked() )
1146 // VirtSize u.a. anpassen
1147 if( !IsBoundingRectValid( pViewData
->aRect
) )
1148 FindBoundingRect( pCur
, pViewData
);
1150 AdjustVirtSize( pViewData
->aRect
);
1151 bLockedEntryFound
= TRUE
;
1154 InvalidateBoundingRect( pViewData
->aRect
);
1156 pCur
= pModel
->NextSibling( pCur
);
1158 if( !bLockedEntryFound
)
1161 nFlags
|= F_GRID_INSERT
;
1164 SetNextEntryPos( Point( LROFFS_WINBORDER
, TBOFFS_WINBORDER
) );
1165 pImpCursor
->Clear();
1169 void SvImpIconView::AdjustVirtSize( const Rectangle
& rRect
)
1171 long nHeightOffs
= 0;
1172 long nWidthOffs
= 0;
1174 if( aVirtOutputSize
.Width() < (rRect
.Right()+LROFFS_WINBORDER
) )
1175 nWidthOffs
= (rRect
.Right()+LROFFS_WINBORDER
) - aVirtOutputSize
.Width();
1177 if( aVirtOutputSize
.Height() < (rRect
.Bottom()+TBOFFS_WINBORDER
) )
1178 nHeightOffs
= (rRect
.Bottom()+TBOFFS_WINBORDER
) - aVirtOutputSize
.Height();
1180 if( nWidthOffs
|| nHeightOffs
)
1183 aVirtOutputSize
.Width() += nWidthOffs
;
1184 aRange
.Max() = aVirtOutputSize
.Width();
1185 aHorSBar
.SetRange( aRange
);
1187 aVirtOutputSize
.Height() += nHeightOffs
;
1188 aRange
.Max() = aVirtOutputSize
.Height();
1189 aVerSBar
.SetRange( aRange
);
1191 pImpCursor
->Clear();
1196 void SvImpIconView::Arrange()
1198 nMaxVirtWidth
= aOutputSize
.Width();
1202 void SvImpIconView::ImpArrange()
1205 ShowCursor( FALSE
);
1207 bMustRecalcBoundingRects
= FALSE
;
1208 MapMode
aMapMode( pView
->GetMapMode());
1209 aMapMode
.SetOrigin( Point() );
1210 pView
->SetMapMode( aMapMode
);
1212 RecalcAllBoundingRectsSmart();
1213 pView
->Invalidate();
1217 void SvImpIconView::Paint( const Rectangle
& rRect
)
1219 if( !pView
->IsUpdateMode() )
1222 #if defined(DBG_UTIL) && defined(OV_DRAWGRID)
1223 if( nFlags
& F_GRIDMODE
)
1225 Color aOldColor
= pView
->GetLineColor();
1226 Color
aNewColor( COL_BLACK
);
1227 pView
->SetLineColor( aNewColor
);
1228 Point
aOffs( pView
->GetMapMode().GetOrigin());
1229 Size
aXSize( pView
->GetOutputSizePixel() );
1230 for( long nDX
= nGridDX
; nDX
<= aXSize
.Width(); nDX
+= nGridDX
)
1232 Point
aStart( nDX
+LROFFS_BOUND
, 0 );
1233 Point
aEnd( nDX
+LROFFS_BOUND
, aXSize
.Height());
1236 pView
->DrawLine( aStart
, aEnd
);
1238 for( long nDY
= nGridDY
; nDY
<= aXSize
.Height(); nDY
+= nGridDY
)
1240 Point
aStart( 0, nDY
+TBOFFS_BOUND
);
1241 Point
aEnd( aXSize
.Width(), nDY
+TBOFFS_BOUND
);
1244 pView
->DrawLine( aStart
, aEnd
);
1246 pView
->SetLineColor( aOldColor
);
1249 nFlags
|= F_PAINTED
;
1251 if( !(pModel
->HasChilds( pCurParent
) ))
1254 pCursor
= pModel
->FirstChild( pCurParent
);
1256 USHORT nCount
= pZOrderList
->Count();
1260 SvPtrarr
* pNewZOrderList
= new SvPtrarr
;
1261 SvPtrarr
* pPaintedEntries
= new SvPtrarr
;
1266 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)(pZOrderList
->GetObject(nPos
));
1267 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
1268 const Rectangle
& rBoundRect
= GetBoundingRect( pEntry
, pViewData
);
1269 if( rRect
.IsOver( rBoundRect
) )
1271 PaintEntry( pEntry
, rBoundRect
.TopLeft(), pViewData
);
1272 // Eintraege, die neu gezeichnet werden, auf Top setzen
1273 pPaintedEntries
->Insert( pEntry
, pPaintedEntries
->Count() );
1276 pNewZOrderList
->Insert( pEntry
, pNewZOrderList
->Count() );
1282 pZOrderList
= pNewZOrderList
;
1283 nCount
= pPaintedEntries
->Count();
1286 for( USHORT nCur
= 0; nCur
< nCount
; nCur
++ )
1287 pZOrderList
->Insert( pPaintedEntries
->GetObject( nCur
),pZOrderList
->Count());
1289 delete pPaintedEntries
;
1292 if( GetResizeRect( aRect
))
1293 PaintResizeRect( aRect
);
1296 BOOL
SvImpIconView::GetResizeRect( Rectangle
& rRect
)
1298 if( aHorSBar
.IsVisible() && aVerSBar
.IsVisible() )
1300 const MapMode
& rMapMode
= pView
->GetMapMode();
1301 Point
aOrigin( rMapMode
.GetOrigin());
1303 aOrigin
.X() += aOutputSize
.Width();
1304 aOrigin
.Y() += aOutputSize
.Height();
1305 rRect
.SetPos( aOrigin
);
1306 rRect
.SetSize( Size( nVerSBarWidth
, nHorSBarHeight
));
1312 void SvImpIconView::PaintResizeRect( const Rectangle
& rRect
)
1314 const StyleSettings
& rStyleSettings
= pView
->GetSettings().GetStyleSettings();
1315 Color aNewColor
= rStyleSettings
.GetFaceColor();
1316 Color aOldColor
= pView
->GetFillColor();
1317 pView
->SetFillColor( aNewColor
);
1318 pView
->DrawRect( rRect
);
1319 pView
->SetFillColor( aOldColor
);
1322 void SvImpIconView::RepaintSelectionItems()
1324 DBG_ERROR("RepaintSelectionItems");
1325 pView
->Invalidate(); // vorlaeufig
1328 SvLBoxItem
* SvImpIconView::GetItem( SvLBoxEntry
* pEntry
,
1329 const Point
& rAbsPos
)
1332 SvLBoxString
* pStringItem
= (SvLBoxString
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
1335 aRect
= CalcTextRect( pEntry
, pStringItem
);
1336 if( aRect
.IsInside( rAbsPos
) )
1339 SvLBoxContextBmp
* pBmpItem
= (SvLBoxContextBmp
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
1342 aRect
= CalcBmpRect( pEntry
);
1343 if( aRect
.IsInside( rAbsPos
) )
1349 void SvImpIconView::CalcDocPos( Point
& aMaeuschenPos
)
1351 aMaeuschenPos
-= pView
->GetMapMode().GetOrigin();
1354 void SvImpIconView::MouseButtonDown( const MouseEvent
& rMEvt
)
1358 Point
aDocPos( rMEvt
.GetPosPixel() );
1359 if(aDocPos
.X()>=aOutputSize
.Width() || aDocPos
.Y()>=aOutputSize
.Height())
1361 CalcDocPos( aDocPos
);
1362 SvLBoxEntry
* pEntry
= GetEntry( aDocPos
);
1365 if( pView
->GetSelectionMode() != SINGLE_SELECTION
)
1367 if( !rMEvt
.IsMod1() ) // Ctrl
1369 pView
->SelectAll( FALSE
);
1370 ClearSelectedRectList();
1373 nFlags
|= F_ADD_MODE
;
1374 nFlags
|= F_RUBBERING
;
1375 aCurSelectionRect
.SetPos( aDocPos
);
1376 pView
->CaptureMouse();
1381 BOOL bSelected
= pView
->IsSelected( pEntry
);
1382 BOOL bEditingEnabled
= pView
->IsInplaceEditingEnabled();
1384 if( rMEvt
.GetClicks() == 2 )
1386 DeselectAllBut( pEntry
);
1387 pView
->pHdlEntry
= pEntry
;
1388 pView
->DoubleClickHdl();
1392 // Inplace-Editing ?
1393 if( rMEvt
.IsMod2() ) // Alt?
1395 if( bEditingEnabled
)
1397 SvLBoxItem
* pItem
= GetItem(pEntry
,aDocPos
);
1399 pView
->EditingRequest( pEntry
, pItem
, aDocPos
);
1402 else if( pView
->GetSelectionMode() == SINGLE_SELECTION
)
1404 DeselectAllBut( pEntry
);
1405 SetCursor( pEntry
);
1406 pView
->Select( pEntry
, TRUE
);
1407 if( bEditingEnabled
&& bSelected
&& !rMEvt
.GetModifier() &&
1408 rMEvt
.IsLeft() && IsTextHit( pEntry
, aDocPos
) )
1410 nFlags
|= F_START_EDITTIMER_IN_MOUSEUP
;
1415 if( !rMEvt
.GetModifier() )
1419 DeselectAllBut( pEntry
);
1420 SetCursor( pEntry
);
1421 pView
->Select( pEntry
, TRUE
);
1425 // erst im Up deselektieren, falls Move per D&D!
1426 nFlags
|= F_DOWN_DESELECT
;
1427 if( bEditingEnabled
&& IsTextHit( pEntry
, aDocPos
) &&
1430 nFlags
|= F_START_EDITTIMER_IN_MOUSEUP
;
1434 else if( rMEvt
.IsMod1() )
1435 nFlags
|= F_DOWN_CTRL
;
1440 void SvImpIconView::MouseButtonUp( const MouseEvent
& rMEvt
)
1442 aMouseMoveTimer
.Stop();
1443 pView
->ReleaseMouse();
1444 // HACK, da Einar noch nicht PrepareCommandEvent aufruft
1445 if( rMEvt
.IsRight() && (nFlags
& (F_DOWN_CTRL
| F_DOWN_DESELECT
) ))
1446 nFlags
&= ~(F_DOWN_CTRL
| F_DOWN_DESELECT
);
1448 if( nFlags
& F_RUBBERING
)
1450 aMouseMoveTimer
.Stop();
1451 AddSelectedRect( aCurSelectionRect
);
1452 HideSelectionRect();
1453 nFlags
&= ~(F_RUBBERING
| F_ADD_MODE
);
1456 SvLBoxEntry
* pEntry
= pView
->GetEntry( rMEvt
.GetPosPixel(), TRUE
);
1459 if( nFlags
& F_DOWN_CTRL
)
1461 // Ctrl & MultiSelection
1462 ToggleSelection( pEntry
);
1463 SetCursor( pEntry
);
1465 else if( nFlags
& F_DOWN_DESELECT
)
1467 DeselectAllBut( pEntry
);
1468 SetCursor( pEntry
);
1469 pView
->Select( pEntry
, TRUE
);
1473 nFlags
&= ~(F_DOWN_CTRL
| F_DOWN_DESELECT
);
1474 if( nFlags
& F_START_EDITTIMER_IN_MOUSEUP
)
1477 nFlags
&= ~F_START_EDITTIMER_IN_MOUSEUP
;
1481 void SvImpIconView::MouseMove( const MouseEvent
& rMEvt
)
1483 if( nFlags
& F_RUBBERING
)
1485 const Point
& rPosPixel
= rMEvt
.GetPosPixel();
1486 if( !aMouseMoveTimer
.IsActive() )
1488 aMouseMoveEvent
= rMEvt
;
1489 aMouseMoveTimer
.Start();
1490 // ausserhalb des Fensters liegende Move-Events muessen
1491 // vom Timer kommen, damit die Scrollgeschwindigkeit
1492 // unabhaengig von Mausbewegungen ist.
1493 if( rPosPixel
.X() < 0 || rPosPixel
.Y() < 0 )
1495 const Size
& rSize
= pView
->GetOutputSizePixel();
1496 if( rPosPixel
.X() > rSize
.Width() || rPosPixel
.Y() > rSize
.Height())
1500 if( &rMEvt
!= &aMouseMoveEvent
)
1501 aMouseMoveEvent
= rMEvt
;
1503 long nScrollDX
, nScrollDY
;
1505 CalcScrollOffsets(rMEvt
.GetPosPixel(),nScrollDX
,nScrollDY
,FALSE
);
1506 BOOL bSelRectHidden
= FALSE
;
1507 if( nScrollDX
|| nScrollDY
)
1509 HideSelectionRect();
1510 bSelRectHidden
= TRUE
;
1511 pView
->Scroll( nScrollDX
, nScrollDY
);
1513 Point
aDocPos( rMEvt
.GetPosPixel() );
1514 aDocPos
= pView
->PixelToLogic( aDocPos
);
1515 Rectangle
aRect( aCurSelectionRect
.TopLeft(), aDocPos
);
1516 if( aRect
!= aCurSelectionRect
)
1518 HideSelectionRect();
1519 bSelRectHidden
= TRUE
;
1520 BOOL bAdd
= (nFlags
& F_ADD_MODE
) ? TRUE
: FALSE
;
1521 SelectRect( aRect
, bAdd
, &aSelectedRectList
);
1523 if( bSelRectHidden
)
1524 DrawSelectionRect( aRect
);
1528 BOOL
SvImpIconView::KeyInput( const KeyEvent
& rKEvt
)
1531 BOOL bKeyUsed
= TRUE
;
1532 BOOL bMod1
= rKEvt
.GetKeyCode().IsMod1();
1533 BOOL bInAddMode
= (BOOL
)((nFlags
& F_ADD_MODE
) != 0);
1534 int bDeselAll
= (pView
->GetSelectionMode() != SINGLE_SELECTION
) &&
1536 SvLBoxEntry
* pNewCursor
;
1537 USHORT nCode
= rKEvt
.GetKeyCode().GetCode();
1543 MakeVisible( pCursor
);
1544 pNewCursor
= pImpCursor
->GoUpDown(pCursor
,FALSE
);
1548 pView
->SelectAll( FALSE
);
1549 ShowCursor( FALSE
);
1550 MakeVisible( pNewCursor
);
1551 SetCursor( pNewCursor
);
1553 pView
->Select( pCursor
, TRUE
);
1557 Rectangle
aRect( GetBoundingRect( pCursor
) );
1560 aRect
.Bottom() -= aRect
.Top();
1562 MakeVisible( aRect
);
1571 pNewCursor
=pImpCursor
->GoUpDown( pCursor
,TRUE
);
1574 MakeVisible( pCursor
);
1576 pView
->SelectAll( FALSE
);
1577 ShowCursor( FALSE
);
1578 MakeVisible( pNewCursor
);
1579 SetCursor( pNewCursor
);
1581 pView
->Select( pCursor
, TRUE
);
1589 pNewCursor
=pImpCursor
->GoLeftRight(pCursor
,TRUE
);
1592 MakeVisible( pCursor
);
1594 pView
->SelectAll( FALSE
);
1595 ShowCursor( FALSE
);
1596 MakeVisible( pNewCursor
);
1597 SetCursor( pNewCursor
);
1599 pView
->Select( pCursor
, TRUE
);
1607 MakeVisible( pCursor
);
1608 pNewCursor
= pImpCursor
->GoLeftRight(pCursor
,FALSE
);
1612 pView
->SelectAll( FALSE
);
1613 ShowCursor( FALSE
);
1614 MakeVisible( pNewCursor
);
1615 SetCursor( pNewCursor
);
1617 pView
->Select( pCursor
, TRUE
);
1621 Rectangle
aRect( GetBoundingRect(pCursor
));
1624 aRect
.Right() -= aRect
.Left();
1626 MakeVisible( aRect
);
1633 if( nFlags
& F_RUBBERING
)
1635 HideSelectionRect();
1636 pView
->SelectAll( FALSE
);
1637 nFlags
&= ~F_RUBBERING
;
1642 if( rKEvt
.GetKeyCode().IsShift() )
1644 if( nFlags
& F_ADD_MODE
)
1645 nFlags
&= (~F_ADD_MODE
);
1647 nFlags
|= F_ADD_MODE
;
1653 if( rKEvt
.GetKeyCode().IsShift() )
1655 if( pCursor
&& pView
->IsInplaceEditingEnabled() )
1656 pView
->EditEntry( pCursor
);
1664 ToggleSelection( pCursor
);
1677 pView
->SelectAll( TRUE
);
1683 pView
->SelectAll( FALSE
);
1689 if( pCursor
&& pView
->IsInplaceEditingEnabled() )
1690 pView
->EditEntry( pCursor
);
1702 void SvImpIconView::PositionScrollBars( long nRealWidth
, long nRealHeight
)
1705 Point
aPos( 0, nRealHeight
);
1706 aPos
.Y() -= nHorSBarHeight
;
1709 // vom linken und unteren Rand ein Pixel abschneiden
1716 if( aHorSBar
.GetPosPixel() != aPos
)
1717 aHorSBar
.SetPosPixel( aPos
);
1720 aPos
.X() = nRealWidth
; aPos
.Y() = 0;
1721 aPos
.X() -= nVerSBarWidth
;
1723 #if defined(WIN) || defined(WNT)
1733 if( aVerSBar
.GetPosPixel() != aPos
)
1734 aVerSBar
.SetPosPixel( aPos
);
1739 void SvImpIconView::AdjustScrollBars()
1741 long nVirtHeight
= aVirtOutputSize
.Height();
1742 long nVirtWidth
= aVirtOutputSize
.Width();
1744 Size
aOSize( pView
->Control::GetOutputSizePixel() );
1745 long nRealHeight
= aOSize
.Height();
1746 long nRealWidth
= aOSize
.Width();
1748 PositionScrollBars( nRealWidth
, nRealHeight
);
1750 const MapMode
& rMapMode
= pView
->GetMapMode();
1751 Point
aOrigin( rMapMode
.GetOrigin() );
1754 if( nRealWidth
> nVirtWidth
)
1755 nVisibleWidth
= nVirtWidth
+ aOrigin
.X();
1757 nVisibleWidth
= nRealWidth
;
1759 long nVisibleHeight
;
1760 if( nRealHeight
> nVirtHeight
)
1761 nVisibleHeight
= nVirtHeight
+ aOrigin
.Y();
1763 nVisibleHeight
= nRealHeight
;
1765 bool bVerSBar
= (pView
->nWindowStyle
& WB_VSCROLL
) ? true : false;
1766 bool bHorSBar
= (pView
->nWindowStyle
& WB_HSCROLL
) ? true : false;
1771 // activate ver scrollbar ?
1772 if( bVerSBar
|| ( nVirtHeight
> nVisibleHeight
) )
1775 nRealWidth
-= nVerSBarWidth
;
1777 if( nRealWidth
> nVirtWidth
)
1778 nVisibleWidth
= nVirtWidth
+ aOrigin
.X();
1780 nVisibleWidth
= nRealWidth
;
1782 nFlags
|= F_HOR_SBARSIZE_WITH_VBAR
;
1784 // activate hor scrollbar ?
1785 if( bHorSBar
|| (nVirtWidth
> nVisibleWidth
) )
1788 nRealHeight
-= nHorSBarHeight
;
1790 if( nRealHeight
> nVirtHeight
)
1791 nVisibleHeight
= nVirtHeight
+ aOrigin
.Y();
1793 nVisibleHeight
= nRealHeight
;
1795 // brauchen wir jetzt doch eine senkrechte Scrollbar ?
1796 if( !(nResult
& 0x0001) && // nur wenn nicht schon da
1797 ( (nVirtHeight
> nVisibleHeight
) || bVerSBar
) )
1799 nResult
= 3; // both are active
1800 nRealWidth
-= nVerSBarWidth
;
1802 if( nRealWidth
> nVirtWidth
)
1803 nVisibleWidth
= nVirtWidth
+ aOrigin
.X();
1805 nVisibleWidth
= nRealWidth
;
1807 nFlags
|= F_VER_SBARSIZE_WITH_HBAR
;
1812 // size ver scrollbar
1813 long nThumb
= aVerSBar
.GetThumbPos();
1814 Size
aSize( nVerSBarWidth
, nRealHeight
);
1815 #if defined(WIN) || defined(WNT)
1816 aSize
.Height() += 2;
1819 aSize
.Height() += 3;
1821 if( aSize
!= aVerSBar
.GetSizePixel() )
1822 aVerSBar
.SetSizePixel( aSize
);
1823 aVerSBar
.SetVisibleSize( nVisibleHeight
);
1824 aVerSBar
.SetPageSize( (nVisibleHeight
*75)/100 );
1825 if( nResult
& 0x0001 )
1827 aVerSBar
.SetThumbPos( nThumb
);
1832 aVerSBar
.SetThumbPos( 0 );
1836 // size hor scrollbar
1837 nThumb
= aHorSBar
.GetThumbPos();
1838 aSize
.Width() = nRealWidth
;
1839 aSize
.Height() = nHorSBarHeight
;
1840 #if defined(WIN) || defined(WNT)
1845 if( nResult
& 0x0001 ) // vertikale Scrollbar ?
1848 #if defined(WIN) || defined(WNT)
1849 if( nResult
& 0x0001 ) // vertikale Scrollbar ?
1855 if( aSize
!= aHorSBar
.GetSizePixel() )
1856 aHorSBar
.SetSizePixel( aSize
);
1857 aHorSBar
.SetVisibleSize( nVisibleWidth
); //nRealWidth );
1858 aHorSBar
.SetPageSize( (nVisibleWidth
*75)/100 );
1859 if( nResult
& 0x0002 )
1861 aHorSBar
.SetThumbPos( nThumb
);
1866 aHorSBar
.SetThumbPos( 0 );
1873 aOutputSize
.Width() = nRealWidth
;
1874 #if defined(WIN) || defined(WNT)
1875 if( nResult
& 0x0002 ) // hor scrollbar ?
1876 nRealHeight
++; // weil unterer Rand geclippt wird
1879 if( nResult
& 0x0002 ) // hor scrollbar ?
1882 aOutputSize
.Height() = nRealHeight
;
1885 void __EXPORT
SvImpIconView::Resize()
1889 if( GetResizeRect(aRect
) )
1890 pView
->Invalidate( aRect
);
1891 aOutputSize
= pView
->GetOutputSizePixel();
1892 pImpCursor
->Clear();
1895 const Size
& rSize
= pView
->Control::GetOutputSizePixel();
1896 PositionScrollBars( rSize
.Width(), rSize
.Height() );
1897 // Die ScrollBars werden asynchron ein/ausgeblendet, damit abgeleitete
1898 // Klassen im Resize ein Arrange durchfuehren koennen, ohne dass
1899 // die ScrollBars aufblitzen (SfxExplorerIconView!)
1900 nCurUserEvent
= Application::PostUserEvent(LINK(this,SvImpIconView
,UserEventHdl
),0);
1903 if( GetResizeRect(aRect
) )
1904 PaintResizeRect( aRect
);
1908 BOOL
SvImpIconView::CheckHorScrollBar()
1910 if( !pZOrderList
|| !aHorSBar
.IsVisible() )
1912 const MapMode
& rMapMode
= pView
->GetMapMode();
1913 Point
aOrigin( rMapMode
.GetOrigin() );
1914 if(!(pView
->nWindowStyle
& WB_HSCROLL
) && !aOrigin
.X() )
1916 long nWidth
= aOutputSize
.Width();
1917 USHORT nCount
= pZOrderList
->Count();
1918 long nMostRight
= 0;
1919 for( USHORT nCur
= 0; nCur
< nCount
; nCur
++ )
1921 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)pZOrderList
->operator[](nCur
);
1922 long nRight
= GetBoundingRect(pEntry
).Right();
1923 if( nRight
> nWidth
)
1925 if( nRight
> nMostRight
)
1926 nMostRight
= nRight
;
1929 aOutputSize
.Height() += nHorSBarHeight
;
1930 aVirtOutputSize
.Width() = nMostRight
;
1931 aHorSBar
.SetThumbPos( 0 );
1933 aRange
.Max() = nMostRight
- 1;
1934 aHorSBar
.SetRange( aRange
);
1935 if( aVerSBar
.IsVisible() )
1937 Size
aSize( aVerSBar
.GetSizePixel());
1938 aSize
.Height() += nHorSBarHeight
;
1939 aVerSBar
.SetSizePixel( aSize
);
1946 BOOL
SvImpIconView::CheckVerScrollBar()
1948 if( !pZOrderList
|| !aVerSBar
.IsVisible() )
1950 const MapMode
& rMapMode
= pView
->GetMapMode();
1951 Point
aOrigin( rMapMode
.GetOrigin() );
1952 if(!(pView
->nWindowStyle
& WB_VSCROLL
) && !aOrigin
.Y() )
1955 long nHeight
= aOutputSize
.Height();
1956 USHORT nCount
= pZOrderList
->Count();
1957 for( USHORT nCur
= 0; nCur
< nCount
; nCur
++ )
1959 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)pZOrderList
->operator[](nCur
);
1960 long nBottom
= GetBoundingRect(pEntry
).Bottom();
1961 if( nBottom
> nHeight
)
1963 if( nBottom
> nDeepest
)
1967 aOutputSize
.Width() += nVerSBarWidth
;
1968 aVirtOutputSize
.Height() = nDeepest
;
1969 aVerSBar
.SetThumbPos( 0 );
1971 aRange
.Max() = nDeepest
- 1;
1972 aVerSBar
.SetRange( aRange
);
1973 if( aHorSBar
.IsVisible() )
1975 Size
aSize( aHorSBar
.GetSizePixel());
1976 aSize
.Width() += nVerSBarWidth
;
1977 aHorSBar
.SetSizePixel( aSize
);
1985 // blendet Scrollbars aus, wenn sie nicht mehr benoetigt werden
1986 void SvImpIconView::CheckScrollBars()
1988 CheckVerScrollBar();
1989 if( CheckHorScrollBar() )
1990 CheckVerScrollBar();
1994 void __EXPORT
SvImpIconView::GetFocus()
1998 pView
->SetEntryFocus( pCursor
, TRUE
);
2003 void __EXPORT
SvImpIconView::LoseFocus()
2007 pView
->SetEntryFocus( pCursor
,FALSE
);
2008 ShowCursor( FALSE
);
2011 void SvImpIconView::UpdateAll()
2014 pImpCursor
->Clear();
2015 pView
->Invalidate();
2018 void SvImpIconView::PaintEntry( SvLBoxEntry
* pEntry
, SvIcnVwDataEntry
* pViewData
)
2020 Point
aPos( GetEntryPosition( pEntry
) );
2021 PaintEntry( pEntry
, aPos
, pViewData
);
2024 void SvImpIconView::PaintEmphasis( const Rectangle
& rRect
, BOOL bSelected
,
2025 BOOL bCursored
, OutputDevice
* pOut
)
2028 if( nFlags
& F_NO_EMPHASIS
)
2034 // Selektion painten
2035 Color aOldFillColor
= pOut
->GetFillColor();
2036 Color aOldLineColor
= pOut
->GetLineColor();
2038 const StyleSettings
& rStyleSettings
= pOut
->GetSettings().GetStyleSettings();
2041 aNewColor
= rStyleSettings
.GetHighlightColor();
2046 aNewColor
=rStyleSettings
.GetFieldColor();
2048 aNewColor
= pOut
->GetBackground().GetColor();
2054 pOut
->SetLineColor( Color( COL_BLACK
) );
2056 pOut
->SetFillColor( aNewColor
);
2057 pOut
->DrawRect( rRect
);
2058 pOut
->SetFillColor( aOldFillColor
);
2059 pOut
->SetLineColor( aOldLineColor
);
2062 void SvImpIconView::PaintItem( const Rectangle
& rRect
,
2063 SvLBoxItem
* pItem
, SvLBoxEntry
* pEntry
, USHORT nPaintFlags
,
2064 OutputDevice
* pOut
)
2066 if( nViewMode
== VIEWMODE_ICON
&& pItem
->IsA() == SV_ITEM_ID_LBOXSTRING
)
2068 const String
& rStr
= ((SvLBoxString
*)pItem
)->GetText();
2069 DrawText( pOut
, rRect
, rStr
, DRAWTEXT_FLAGS
);
2073 Point
aPos( rRect
.TopLeft() );
2074 const Size
& rSize
= GetItemSize( pView
, pEntry
, pItem
);
2075 if( nPaintFlags
& PAINTFLAG_HOR_CENTERED
)
2076 aPos
.X() += (rRect
.GetWidth() - rSize
.Width() ) / 2;
2077 if( nPaintFlags
& PAINTFLAG_VER_CENTERED
)
2078 aPos
.Y() += (rRect
.GetHeight() - rSize
.Height() ) / 2;
2079 pItem
->Paint( aPos
, *(SvLBox
*)pOut
, 0, pEntry
);
2083 void SvImpIconView::PaintEntry( SvLBoxEntry
* pEntry
, const Point
& rPos
,
2084 SvIcnVwDataEntry
* pViewData
, OutputDevice
* pOut
)
2086 if( !pView
->IsUpdateMode() )
2092 SvLBoxContextBmp
* pBmpItem
;
2094 pView
->PreparePaint( pEntry
);
2097 pViewData
= ICNVIEWDATA(pEntry
);
2099 SvLBoxString
* pStringItem
= (SvLBoxString
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
2101 BOOL bSelected
= pViewData
->IsSelected();
2102 BOOL bCursored
= pViewData
->IsCursored();
2104 Font
aTempFont( pOut
->GetFont() );
2105 // waehrend D&D nicht die Fontfarbe wechseln, da sonst auch die
2106 // Emphasis gezeichnet werden muss! (weisser Adler auf weissem Grund)
2107 if( bSelected
&& !(nFlags
& F_NO_EMPHASIS
) )
2109 const StyleSettings
& rStyleSettings
= pOut
->GetSettings().GetStyleSettings();
2110 Font
aNewFont( aTempFont
);
2111 aNewFont
.SetColor( rStyleSettings
.GetHighlightTextColor() );
2112 pOut
->SetFont( aNewFont
);
2114 Rectangle
aTextRect( CalcTextRect(pEntry
,pStringItem
,&rPos
,FALSE
,pViewData
));
2115 Rectangle
aBmpRect( CalcBmpRect(pEntry
, &rPos
, pViewData
) );
2120 pBmpItem
= (SvLBoxContextBmp
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
2121 PaintEmphasis( aBmpRect
, bSelected
, bCursored
, pOut
);
2122 PaintItem( aBmpRect
, pBmpItem
, pEntry
,
2123 PAINTFLAG_HOR_CENTERED
| PAINTFLAG_VER_CENTERED
, pOut
);
2124 PaintEmphasis( aTextRect
, bSelected
, FALSE
, pOut
);
2125 PaintItem( aTextRect
, pStringItem
, pEntry
, PAINTFLAG_HOR_CENTERED
, pOut
);
2129 pBmpItem
= (SvLBoxContextBmp
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
2130 PaintEmphasis( aBmpRect
, bSelected
, bCursored
, pOut
);
2131 PaintItem( aBmpRect
, pBmpItem
, pEntry
, PAINTFLAG_VER_CENTERED
, pOut
);
2132 PaintEmphasis( aTextRect
, bSelected
, FALSE
, pOut
);
2133 PaintItem( aTextRect
, pStringItem
, pEntry
,PAINTFLAG_VER_CENTERED
, pOut
);
2137 PaintEmphasis( aTextRect
, bSelected
, bCursored
, pOut
);
2138 PaintItem( aTextRect
, pStringItem
, pEntry
, PAINTFLAG_VER_CENTERED
, pOut
);
2141 pOut
->SetFont( aTempFont
);
2144 void SvImpIconView::SetEntryPosition( SvLBoxEntry
* pEntry
, const Point
& rPos
,
2145 BOOL bAdjustAtGrid
, BOOL bCheckScrollBars
)
2147 if( pModel
->GetParent(pEntry
) == pCurParent
)
2149 ShowCursor( FALSE
);
2150 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
2151 Rectangle
aBoundRect( GetBoundingRect( pEntry
, pViewData
));
2152 pView
->Invalidate( aBoundRect
);
2154 if( rPos
!= aBoundRect
.TopLeft() )
2156 Point aGridOffs
= pViewData
->aGridRect
.TopLeft() -
2157 pViewData
->aRect
.TopLeft();
2158 pImpCursor
->Clear();
2159 nFlags
&= ~F_GRID_INSERT
;
2160 aBoundRect
.SetPos( rPos
);
2161 pViewData
->aRect
= aBoundRect
;
2162 pViewData
->aGridRect
.SetPos( rPos
+ aGridOffs
);
2163 AdjustVirtSize( aBoundRect
);
2165 //HACK(Billigloesung, die noch verbessert werden muss)
2168 AdjustAtGrid( pEntry
);
2171 if( bCheckScrollBars
&& pView
->IsUpdateMode() )
2174 PaintEntry( pEntry
, pViewData
);
2179 void SvImpIconView::ViewDataInitialized( SvLBoxEntry
*)
2183 void SvImpIconView::ModelHasEntryInvalidated( SvListEntry
* pEntry
)
2185 if( pEntry
== pCursor
)
2186 ShowCursor( FALSE
);
2187 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
2188 pView
->Invalidate( pViewData
->aRect
);
2190 if( nFlags
& F_GRIDMODE
)
2191 Center( (SvLBoxEntry
*)pEntry
, pViewData
);
2193 pViewData
->aRect
.SetSize( CalcBoundingSize(
2194 (SvLBoxEntry
*)pEntry
, pViewData
) );
2196 ViewDataInitialized( (SvLBoxEntry
*)pEntry
);
2197 pView
->Invalidate( pViewData
->aRect
);
2198 if( pEntry
== pCursor
)
2203 void SvImpIconView::InvalidateEntry( SvLBoxEntry
* pEntry
)
2205 const Rectangle
& rRect
= GetBoundingRect( pEntry
);
2206 pView
->Invalidate( rRect
);
2209 void SvImpIconView::SetNoSelection()
2213 void SvImpIconView::SetDragDropMode( DragDropMode
)
2217 void SvImpIconView::SetSelectionMode( SelectionMode
)
2221 BOOL
SvImpIconView::IsEntryInView( SvLBoxEntry
* )
2226 SvLBoxEntry
* SvImpIconView::GetDropTarget( const Point
& rPos
)
2228 Point
aDocPos( rPos
);
2229 CalcDocPos( aDocPos
);
2230 SvLBoxEntry
* pTarget
= GetEntry( aDocPos
);
2231 if( !pTarget
|| !pTarget
->HasChilds() )
2232 pTarget
= pCurParent
;
2236 SvLBoxEntry
* SvImpIconView::GetEntry( const Point
& rDocPos
)
2238 CheckBoundingRects();
2239 SvLBoxEntry
* pTarget
= 0;
2240 // Z-Order-Liste vom Ende her absuchen
2241 USHORT nCount
= pZOrderList
->Count();
2245 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)(pZOrderList
->GetObject(nCount
));
2246 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
2247 if( pViewData
->aRect
.IsInside( rDocPos
) )
2256 SvLBoxEntry
* SvImpIconView::GetNextEntry( const Point
& rDocPos
, SvLBoxEntry
* pCurEntry
)
2258 CheckBoundingRects();
2259 SvLBoxEntry
* pTarget
= 0;
2260 USHORT nStartPos
= pZOrderList
->GetPos( (void*)pCurEntry
);
2261 if( nStartPos
!= USHRT_MAX
)
2263 USHORT nCount
= pZOrderList
->Count();
2264 for( USHORT nCur
= nStartPos
+1; nCur
< nCount
; nCur
++ )
2266 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)(pZOrderList
->GetObject(nCur
));
2267 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
2268 if( pViewData
->aRect
.IsInside( rDocPos
) )
2278 SvLBoxEntry
* SvImpIconView::GetPrevEntry( const Point
& rDocPos
, SvLBoxEntry
* pCurEntry
)
2280 CheckBoundingRects();
2281 SvLBoxEntry
* pTarget
= 0;
2282 USHORT nStartPos
= pZOrderList
->GetPos( (void*)pCurEntry
);
2283 if( nStartPos
!= USHRT_MAX
&& nStartPos
!= 0 )
2288 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)(pZOrderList
->GetObject(nStartPos
));
2289 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
2290 if( pViewData
->aRect
.IsInside( rDocPos
) )
2295 } while( nStartPos
> 0 );
2301 Point
SvImpIconView::GetEntryPosition( SvLBoxEntry
* pEntry
)
2303 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
2304 DBG_ASSERT(pViewData
,"Entry not in model");
2305 return pViewData
->aRect
.TopLeft();
2308 const Rectangle
& SvImpIconView::GetBoundingRect( SvLBoxEntry
* pEntry
, SvIcnVwDataEntry
* pViewData
)
2311 pViewData
= ICNVIEWDATA(pEntry
);
2312 DBG_ASSERT(pViewData
,"Entry not in model");
2313 if( !IsBoundingRectValid( pViewData
->aRect
))
2314 FindBoundingRect( pEntry
, pViewData
);
2315 return pViewData
->aRect
;
2318 void SvImpIconView::SetSpaceBetweenEntries( long nHor
, long nVer
)
2324 Rectangle
SvImpIconView::CalcBmpRect( SvLBoxEntry
* pEntry
, const Point
* pPos
,
2325 SvIcnVwDataEntry
* pViewData
)
2328 pViewData
= ICNVIEWDATA(pEntry
);
2330 Rectangle aBound
= GetBoundingRect( pEntry
, pViewData
);
2332 aBound
.SetPos( *pPos
);
2333 Point
aPos( aBound
.TopLeft() );
2339 aPos
.X() += ( aBound
.GetWidth() - nMaxBmpWidth
) / 2;
2340 Size
aSize( nMaxBmpWidth
, nMaxBmpHeight
);
2341 // das Bitmap-Rechteck soll nicht das TextRect beruehren
2342 aSize
.Height() -= 3;
2343 return Rectangle( aPos
, aSize
);
2347 return Rectangle( aPos
,
2348 Size( nMaxBmpWidth
, aBound
.GetHeight() ));
2351 return Rectangle( aPos
, aBound
.GetSize() );
2361 Rectangle
SvImpIconView::CalcTextRect( SvLBoxEntry
* pEntry
,
2362 SvLBoxString
* pItem
, const Point
* pPos
, BOOL bForInplaceEdit
,
2363 SvIcnVwDataEntry
* pViewData
)
2365 long nBmpHeight
, nBmpWidth
;
2368 pItem
= (SvLBoxString
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
2371 pViewData
= ICNVIEWDATA(pEntry
);
2373 Size
aTextSize( GetItemSize( pView
, pEntry
, pItem
, pViewData
));
2374 aTextSize
.Width() += 2*LROFFS_TEXT
;
2376 Size
aContextBmpSize(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
)->GetSize(pView
,pEntry
));
2377 Rectangle aBound
= GetBoundingRect( pEntry
, pViewData
);
2379 aBound
.SetPos( *pPos
);
2380 Point
aPos( aBound
.TopLeft() );
2385 nBmpHeight
= aContextBmpSize
.Height();
2386 if( nBmpHeight
< nMaxBmpHeight
)
2387 nBmpHeight
= nMaxBmpHeight
;
2388 aPos
.Y() += nBmpHeight
;
2390 // beim Inplace-Editieren, spendieren wir ein bisschen mehr Platz
2391 if( bForInplaceEdit
)
2394 long nMinWidth
= (( (aContextBmpSize
.Width()*10) / 100 ) * 2 ) +
2395 aContextBmpSize
.Width();
2396 if( nMinWidth
> aBound
.GetWidth() )
2397 nMinWidth
= aBound
.GetWidth();
2399 if( aTextSize
.Width() < nMinWidth
)
2400 aTextSize
.Width() = nMinWidth
;
2402 // beim Inplace-Ed. darfs auch untere Eintraege ueberlappen
2403 Rectangle aMaxGridTextRect
= CalcMaxTextRect(pEntry
, pViewData
);
2404 Size aOptSize
= aMaxGridTextRect
.GetSize();
2405 if( aOptSize
.Height() > aTextSize
.Height() )
2406 aTextSize
.Height() = aOptSize
.Height();
2410 aPos
.X() += ( aBound
.GetWidth() - aTextSize
.Width() ) / 2;
2414 nBmpWidth
= aContextBmpSize
.Width();
2415 if( nBmpWidth
< nMaxBmpWidth
)
2416 nBmpWidth
= nMaxBmpWidth
;
2417 aPos
.X() += nBmpWidth
;
2418 // vertikal ausrichten
2419 aPos
.Y() += ( nBmpWidth
- aTextSize
.Height() ) / 2;
2423 Rectangle
aRect( aPos
, aTextSize
);
2424 // KNALLT BEIM D&D, WENN GECLIPPT WIRD (In DrawText von Thomas)
2425 // ClipAtVirtOutRect( aRect );
2430 long SvImpIconView::CalcBoundingWidth( SvLBoxEntry
* pEntry
,
2431 const SvIcnVwDataEntry
* pViewData
) const
2433 DBG_ASSERT(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
),"No Bitmaps");
2434 DBG_ASSERT(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
),"No Text");
2435 long nStringWidth
= GetItemSize( pView
, pEntry
, pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
),pViewData
).Width();
2436 nStringWidth
+= 2*LROFFS_TEXT
;
2437 long nBmpWidth
= pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
)->GetSize(pView
,pEntry
).Width();
2443 nWidth
= Max( nStringWidth
, nBmpWidth
);
2444 nWidth
= Max( nWidth
, nMaxBmpWidth
);
2448 nWidth
= Max( nBmpWidth
, nMaxBmpWidth
);
2449 nWidth
+= NAMEVIEW_OFFS_BMP_STRING
; // Abstand Bitmap String
2450 nWidth
+= nStringWidth
;
2454 nWidth
= nStringWidth
;
2460 long SvImpIconView::CalcBoundingHeight( SvLBoxEntry
* pEntry
,
2461 const SvIcnVwDataEntry
* pViewData
) const
2463 DBG_ASSERT(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
),"No Bitmaps");
2464 DBG_ASSERT(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
),"No Text");
2465 long nStringHeight
= GetItemSize(pView
,pEntry
,pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
),pViewData
).Height();
2466 long nBmpHeight
= pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
)->GetSize(pView
,pEntry
).Height();
2472 nHeight
= Max( nBmpHeight
, nMaxBmpHeight
);
2473 nHeight
+= ICONVIEW_OFFS_BMP_STRING
; // Abstand Bitmap String
2474 nHeight
+= nStringHeight
;
2478 nHeight
= Max( nBmpHeight
, nMaxBmpHeight
);
2479 nHeight
= Max( nHeight
, nStringHeight
);
2483 nHeight
= nStringHeight
;
2486 if( nHeight
> nMaxBoundHeight
)
2488 ((SvImpIconView
*)this)->nMaxBoundHeight
= nHeight
;
2489 ((SvImpIconView
*)this)->aHorSBar
.SetLineSize( nHeight
/ 2 );
2490 ((SvImpIconView
*)this)->aVerSBar
.SetLineSize( nHeight
/ 2 );
2495 Size
SvImpIconView::CalcBoundingSize( SvLBoxEntry
* pEntry
,
2496 SvIcnVwDataEntry
* pViewData
) const
2499 pViewData
= ICNVIEWDATA(pEntry
);
2500 return Size( CalcBoundingWidth(pEntry
,pViewData
),
2501 CalcBoundingHeight(pEntry
,pViewData
) );
2504 void SvImpIconView::RecalcAllBoundingRects()
2506 nMaxBoundHeight
= 0;
2507 pZOrderList
->Remove(0, pZOrderList
->Count() );
2508 SvLBoxEntry
* pEntry
= pModel
->FirstChild( pCurParent
);
2511 FindBoundingRect( pEntry
);
2512 pZOrderList
->Insert( pEntry
, pZOrderList
->Count() );
2513 pEntry
= pModel
->NextSibling( pEntry
);
2515 bMustRecalcBoundingRects
= FALSE
;
2519 void SvImpIconView::RecalcAllBoundingRectsSmart()
2521 nMaxBoundHeight
= 0;
2522 pZOrderList
->Remove(0, pZOrderList
->Count() );
2523 SvLBoxEntry
* pEntry
= pModel
->FirstChild( pCurParent
);
2526 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
2527 if( IsBoundingRectValid( pViewData
->aRect
))
2529 Size
aBoundSize( pViewData
->aRect
.GetSize() );
2530 if( aBoundSize
.Height() > nMaxBoundHeight
)
2531 nMaxBoundHeight
= aBoundSize
.Height();
2532 pZOrderList
->Insert( pEntry
, pZOrderList
->Count() );
2536 FindBoundingRect( pEntry
, pViewData
);
2538 pZOrderList
->Insert( pEntry
, pZOrderList
->Count() );
2539 pEntry
= pModel
->NextSibling( pEntry
);
2544 void SvImpIconView::UpdateBoundingRects()
2546 SvLBoxEntry
* pEntry
= pModel
->FirstChild( pCurParent
);
2549 GetBoundingRect( pEntry
);
2550 pEntry
= pModel
->NextSibling( pEntry
);
2554 void SvImpIconView::FindBoundingRect( SvLBoxEntry
* pEntry
,
2555 SvIcnVwDataEntry
* pViewData
)
2558 pViewData
= ICNVIEWDATA(pEntry
);
2560 Size
aSize( CalcBoundingSize( pEntry
, pViewData
) );
2563 DBG_ASSERT(!pViewData
->IsEntryPosLocked(),"Locked entry pos in FindBoundingRect");
2564 // damits in der IconView nicht drunter & drueber geht
2565 if( pViewData
->IsEntryPosLocked() && IsBoundingRectValid(pViewData
->aRect
) )
2567 AdjustVirtSize( pViewData
->aRect
);
2571 aPos
= FindNextEntryPos( aSize
);
2573 if( nFlags
& F_GRIDMODE
)
2575 Rectangle
aGridRect( aPos
, Size(nGridDX
, nGridDY
) );
2576 pViewData
->aGridRect
= aGridRect
;
2577 Center( pEntry
, pViewData
);
2578 AdjustVirtSize( pViewData
->aRect
);
2579 pImpCursor
->SetGridUsed( pViewData
->aRect
);
2583 pViewData
->aRect
= Rectangle( aPos
, aSize
);
2584 AdjustVirtSize( pViewData
->aRect
);
2589 void SvImpIconView::SetCursor( SvLBoxEntry
* pEntry
)
2591 if( pEntry
== pCursor
)
2594 ShowCursor( FALSE
);
2597 pView
->SetEntryFocus( pCursor
, FALSE
);
2598 if( pView
->GetSelectionMode() == SINGLE_SELECTION
)
2599 pView
->Select( pCursor
, FALSE
);
2605 pView
->SetEntryFocus(pCursor
, TRUE
);
2606 if( pView
->GetSelectionMode() == SINGLE_SELECTION
)
2607 pView
->Select( pCursor
, TRUE
);
2613 void SvImpIconView::ShowCursor( BOOL bShow
)
2615 if( !pCursor
|| !bShow
|| !pView
->HasFocus() )
2620 Rectangle
aRect ( CalcFocusRect( pCursor
) );
2621 pView
->ShowFocus( aRect
);
2625 void SvImpIconView::HideDDIcon()
2633 void SvImpIconView::ImpHideDDIcon()
2637 Size
aSize( pDDDev
->GetOutputSizePixel() );
2638 // pView restaurieren
2639 pView
->DrawOutDev( aDDLastRectPos
, aSize
, Point(), aSize
, *pDDDev
);
2644 void SvImpIconView::ShowDDIcon( SvLBoxEntry
* pRefEntry
, const Point
& rPosPix
)
2647 if( pRefEntry
!= pDDRefEntry
)
2652 BOOL bSelected
= pView
->SvListView::Select( pRefEntry
, FALSE
);
2657 // nicht bei jedem Move ein Device anlegen, da dies besonders
2658 // auf Remote-Clients zu langsam ist
2664 pDDDev
= new VirtualDevice( *pView
);
2665 pDDDev
->SetFont( pView
->GetFont() );
2672 const Rectangle
& rRect
= GetBoundingRect( pRefEntry
);
2673 pDDDev
->SetOutputSizePixel( rRect
.GetSize() );
2675 Point
aPos( rPosPix
);
2678 Size
aSize( pDDDev
->GetOutputSizePixel() );
2679 pDDRefEntry
= pRefEntry
;
2680 aDDLastEntryPos
= aPos
;
2681 aDDLastRectPos
= aPos
;
2683 // Hintergrund sichern
2684 pDDDev
->DrawOutDev( Point(), aSize
, aPos
, aSize
, *pView
);
2685 // Icon in pView malen
2686 nFlags
|= F_NO_EMPHASIS
;
2687 PaintEntry( pRefEntry
, aPos
);
2688 nFlags
&= ~F_NO_EMPHASIS
;
2690 pView
->SvListView::Select( pRefEntry
, TRUE
);
2693 void SvImpIconView::HideShowDDIcon( SvLBoxEntry
* pRefEntry
, const Point
& rPosPix
)
2695 /* In Notfaellen folgenden flackernden Code aktivieren:
2698 ShowDDIcon( pRefEntry, rPosPix );
2703 ShowDDIcon( pRefEntry
, rPosPix
);
2707 if( pRefEntry
!= pDDRefEntry
)
2710 ShowDDIcon( pRefEntry
, rPosPix
);
2716 Point
aCurEntryPos( rPosPix
);
2717 CalcDocPos( aCurEntryPos
);
2719 const Rectangle
& rRect
= GetBoundingRect( pRefEntry
);
2720 Size
aEntrySize( rRect
.GetSize() );
2721 Rectangle
aPrevEntryRect( aDDLastEntryPos
, aEntrySize
);
2722 Rectangle
aCurEntryRect( aCurEntryPos
, aEntrySize
);
2724 if( !aPrevEntryRect
.IsOver( aCurEntryRect
) )
2727 ShowDDIcon( pRefEntry
, rPosPix
);
2731 // Ueberlappung des neuen und alten D&D-Pointers!
2733 Rectangle
aFullRect( aPrevEntryRect
.Union( aCurEntryRect
) );
2736 pDDTempDev
= new VirtualDevice( *pView
);
2737 pDDTempDev
->SetFont( pView
->GetFont() );
2740 Size
aFullSize( aFullRect
.GetSize() );
2741 Point
aFullPos( aFullRect
.TopLeft() );
2743 pDDTempDev
->SetOutputSizePixel( aFullSize
);
2745 // Hintergrund (mit dem alten D&D-Pointer!) sichern
2746 pDDTempDev
->DrawOutDev( aEmptyPoint
, aFullSize
, aFullPos
, aFullSize
, *pView
);
2747 // den alten Buffer in den neuen Buffer pasten
2748 aDDLastRectPos
= aDDLastRectPos
- aFullPos
;
2750 pDDTempDev
->DrawOutDev(
2752 pDDDev
->GetOutputSizePixel(),
2754 pDDDev
->GetOutputSizePixel(),
2758 VirtualDevice
* pTemp
= pDDDev
;
2759 pDDDev
= pDDTempDev
;
2762 // in den restaurierten Hintergrund den neuen D&D-Pointer zeichnen
2763 pDDTempDev
->SetOutputSizePixel( pDDDev
->GetOutputSizePixel() );
2764 pDDTempDev
->DrawOutDev(
2765 aEmptyPoint
, aFullSize
, aEmptyPoint
, aFullSize
, *pDDDev
);
2766 Point aRelPos
= aCurEntryPos
- aFullPos
;
2767 nFlags
|= F_NO_EMPHASIS
;
2768 PaintEntry( pRefEntry
, aRelPos
, 0, pDDTempDev
);
2769 nFlags
&= ~F_NO_EMPHASIS
;
2771 aDDLastRectPos
= aFullPos
;
2772 aDDLastEntryPos
= aCurEntryPos
;
2776 pDDDev
->GetOutputSizePixel(),
2778 pDDDev
->GetOutputSizePixel(),
2781 BOOL bSelected
= pView
->SvListView::Select( pRefEntry
, FALSE
);
2783 pView
->SvListView::Select( pRefEntry
, TRUE
);
2786 void SvImpIconView::ShowTargetEmphasis( SvLBoxEntry
* pEntry
, BOOL
)
2788 CheckBoundingRects();
2790 if( pEntry
!= pCurParent
&&
2791 (pEntry
->HasChilds() || pEntry
->HasChildsOnDemand()) )
2792 aRect
= CalcBmpRect( pEntry
);
2795 aRect
.SetSize( aOutputSize
);
2796 const MapMode
& rMapMode
= pView
->GetMapMode();
2797 Point
aOrigin( rMapMode
.GetOrigin());
2798 aOrigin
*= -1; // in Doc-Koord wandeln
2799 aRect
.SetPos( aOrigin
);
2800 aRect
.Left()++; aRect
.Top()++;
2801 aRect
.Right()--; aRect
.Bottom()--;
2803 ImpDrawXORRect( aRect
);
2806 BOOL
SvImpIconView::NotifyMoving( SvLBoxEntry
* pTarget
, SvLBoxEntry
* pEntry
,
2807 SvLBoxEntry
*& rpNewPar
, ULONG
& rNewChildPos
)
2809 if( pTarget
== pCurParent
&& pModel
->GetParent(pEntry
) == pCurParent
)
2811 // D&D innerhalb einer Childlist
2813 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
2814 Size
aSize( pViewData
->aRect
.GetSize() );
2815 Point aNewPos
= FindNextEntryPos( aSize
);
2816 AdjustVirtSize( Rectangle( aNewPos
, aSize
) );
2817 SetEntryPosition( pEntry
, aNewPos
, FALSE
, TRUE
);
2820 return pView
->SvLBox::NotifyMoving(pTarget
,pEntry
,rpNewPar
,rNewChildPos
);
2823 BOOL
SvImpIconView::NotifyCopying( SvLBoxEntry
* pTarget
, SvLBoxEntry
* pEntry
,
2824 SvLBoxEntry
*& rpNewParent
, ULONG
& rNewChildPos
)
2826 return pView
->SvLBox::NotifyCopying(pTarget
,pEntry
,rpNewParent
,rNewChildPos
);
2829 void SvImpIconView::WriteDragServerInfo( const Point
& rPos
, SvLBoxDDInfo
* pInfo
)
2831 SvLBoxEntry
* pCurEntry
= GetCurEntry();
2836 aEntryPos
-= GetEntryPosition( pCurEntry
);
2838 pInfo
->nMouseRelX
= aEntryPos
.X();
2839 pInfo
->nMouseRelY
= aEntryPos
.Y();
2842 void SvImpIconView::ReadDragServerInfo( const Point
& rPos
, SvLBoxDDInfo
* pInfo
)
2844 Point
aDropPos( rPos
);
2845 aDropPos
.X() -= pInfo
->nMouseRelX
;
2846 aDropPos
.Y() -= pInfo
->nMouseRelY
;
2847 SetNextEntryPos( aDropPos
);
2850 void SvImpIconView::InvalidateBoundingRect( SvLBoxEntry
* pEntry
)
2852 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
2853 InvalidateBoundingRect( pViewData
->aRect
);
2856 void SvImpIconView::PrepareCommandEvent( const Point
& rPt
)
2858 aMouseMoveTimer
.Stop();
2860 nFlags
|= F_CMD_ARRIVED
;
2861 SvLBoxEntry
* pEntry
= pView
->GetEntry( rPt
, TRUE
);
2862 if( (nFlags
& F_DOWN_CTRL
) && pEntry
&& !pView
->IsSelected(pEntry
) )
2863 pView
->Select( pEntry
, TRUE
);
2864 nFlags
&= ~(F_DOWN_CTRL
| F_DOWN_DESELECT
);
2867 void SvImpIconView::SttDrag( const Point
& rPos
)
2869 PrepareCommandEvent( rPos
);
2871 nFlags
|= F_DRAG_SOURCE
;
2872 ShowCursor( FALSE
);
2875 void SvImpIconView::EndDrag()
2878 nFlags
&= (~F_DRAG_SOURCE
);
2881 void SvImpIconView::ToTop( SvLBoxEntry
* pEntry
)
2883 DBG_ASSERT(pZOrderList
->GetPos(pEntry
)!=0xffff,"ToTop:ZOrder?");
2884 if( pZOrderList
->GetObject( pZOrderList
->Count() -1 ) != pEntry
)
2886 USHORT nPos
= pZOrderList
->GetPos( (void*)pEntry
);
2887 pZOrderList
->Remove( nPos
, 1 );
2888 pZOrderList
->Insert( pEntry
, pZOrderList
->Count() );
2892 void SvImpIconView::SetCurParent( SvLBoxEntry
* pNewParent
)
2895 pCurParent
= pNewParent
;
2899 void SvImpIconView::ClipAtVirtOutRect( Rectangle
& rRect
) const
2901 if( rRect
.Bottom() >= aVirtOutputSize
.Height() )
2902 rRect
.Bottom() = aVirtOutputSize
.Height() - 1;
2903 if( rRect
.Right() >= aVirtOutputSize
.Width() )
2904 rRect
.Right() = aVirtOutputSize
.Width() - 1;
2905 if( rRect
.Top() < 0 )
2907 if( rRect
.Left() < 0 )
2911 // rRect: Bereich des Dokumentes (in Dokumentkoordinaten), der
2912 // sichtbar gemacht werden soll.
2913 // bScrBar == TRUE: Das Rect wurde aufgrund eines ScrollBar-Events berechnet
2915 void SvImpIconView::MakeVisible( const Rectangle
& rRect
, BOOL bScrBar
)
2917 Rectangle
aRect( rRect
);
2918 ClipAtVirtOutRect( aRect
);
2919 MapMode
aMapMode( pView
->GetMapMode() );
2920 Point
aOrigin( aMapMode
.GetOrigin() );
2921 // in Dokumentkoordinate umwandeln
2924 Rectangle
aOutputArea( aOrigin
, aOutputSize
);
2925 if( aOutputArea
.IsInside( aRect
) )
2926 return; // ist schon sichtbar
2929 if( aRect
.Top() < aOutputArea
.Top() )
2931 // nach oben scrollen (nDy < 0)
2932 nDy
= aRect
.Top() - aOutputArea
.Top();
2934 else if( aRect
.Bottom() > aOutputArea
.Bottom() )
2936 // nach unten scrollen (nDy > 0)
2937 nDy
= aRect
.Bottom() - aOutputArea
.Bottom();
2943 if( aRect
.Left() < aOutputArea
.Left() )
2945 // nach links scrollen (nDx < 0)
2946 nDx
= aRect
.Left() - aOutputArea
.Left();
2948 else if( aRect
.Right() > aOutputArea
.Right() )
2950 // nach rechts scrollen (nDx > 0)
2951 nDx
= aRect
.Right() - aOutputArea
.Right();
2958 aOutputArea
.SetPos( aOrigin
);
2962 // Origin fuer SV invertieren (damit wir in
2963 // Dokumentkoordinaten scrollen/painten koennen)
2965 aMapMode
.SetOrigin( aOrigin
);
2966 pView
->SetMapMode( aMapMode
);
2968 // in umgekehrte Richtung scrollen!
2969 pView
->Control::Scroll( -nDx
, -nDy
, aOutputArea
, TRUE
);
2970 if( aHorSBar
.IsVisible() || aVerSBar
.IsVisible() )
2975 // Thumbs korrigieren
2976 if(aHorSBar
.IsVisible() && aHorSBar
.GetThumbPos() != aOrigin
.X())
2977 aHorSBar
.SetThumbPos( aOrigin
.X() );
2978 if(aVerSBar
.IsVisible() && aVerSBar
.GetThumbPos() != aOrigin
.Y())
2979 aVerSBar
.SetThumbPos( aOrigin
.Y() );
2982 // pruefen, ob ScrollBars noch benoetigt werden
2988 SvLBoxEntry
* SvImpIconView::GetNewCursor()
2990 SvLBoxEntry
* pNewCursor
;
2993 pNewCursor
= pImpCursor
->GoLeftRight( pCursor
, FALSE
);
2996 pNewCursor
= pImpCursor
->GoLeftRight( pCursor
, TRUE
);
2999 pNewCursor
= pImpCursor
->GoUpDown( pCursor
, FALSE
);
3001 pNewCursor
= pImpCursor
->GoUpDown( pCursor
, TRUE
);
3006 pNewCursor
= pModel
->FirstChild( pCurParent
);
3007 DBG_ASSERT(!pNewCursor
|| (pCursor
&&pCursor
!=pNewCursor
),"GetNewCursor failed");
3012 USHORT
SvImpIconView:: GetSelectionCount() const
3014 USHORT nSelected
= 0;
3015 SvLBoxEntry
* pEntry
= pModel
->FirstChild( pCurParent
);
3018 if( pView
->IsSelected( pEntry
) )
3020 pEntry
= pModel
->NextSibling( pEntry
);
3026 void SvImpIconView::ToggleSelection( SvLBoxEntry
* pEntry
)
3029 if( pView
->IsSelected( pEntry
) )
3033 pView
->Select( pEntry
, bSel
);
3036 void SvImpIconView::DeselectAllBut( SvLBoxEntry
* pThisEntryNot
)
3038 ClearSelectedRectList();
3039 SvLBoxEntry
* pEntry
= pModel
->FirstChild( pCurParent
);
3042 if( pEntry
!= pThisEntryNot
&& pView
->IsSelected( pEntry
))
3043 pView
->Select( pEntry
, FALSE
);
3044 pEntry
= pModel
->NextSibling( pEntry
);
3051 ImpIcnCursor::ImpIcnCursor( SvImpIconView
* pOwner
)
3066 ImpIcnCursor::~ImpIcnCursor()
3073 USHORT
ImpIcnCursor::GetSortListPos( SvPtrarr
* pList
, long nValue
,
3076 USHORT nCount
= (USHORT
)pList
->Count();
3081 long nPrevValue
= LONG_MIN
;
3084 const Rectangle
& rRect
=
3085 pView
->GetBoundingRect((SvLBoxEntry
*)(pList
->GetObject(nCurPos
)));
3088 nCurValue
= rRect
.Top();
3090 nCurValue
= rRect
.Left();
3091 if( nValue
>= nPrevValue
&& nValue
<= nCurValue
)
3092 return (USHORT
)nCurPos
;
3093 nPrevValue
= nCurValue
;
3097 return pList
->Count();
3100 void ImpIcnCursor::ImplCreate()
3102 pView
->CheckBoundingRects();
3103 DBG_ASSERT(pColumns
==0&&pRows
==0,"ImplCreate: Not cleared");
3107 pColumns
= new SvPtrarr
[ nCols
];
3108 pRows
= new SvPtrarr
[ nRows
];
3112 SvLBoxTreeList
* pModel
= pView
->pModel
;
3113 SvLBoxEntry
* pEntry
= pModel
->FirstChild( pView
->pCurParent
);
3116 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA2(pEntry
);
3117 // const Rectangle& rRect = pView->GetBoundingRect( pEntry );
3118 Rectangle
rRect( pView
->CalcBmpRect( pEntry
,0,pViewData
) );
3119 short nY
= (short)( ((rRect
.Top()+rRect
.Bottom())/2) / nDeltaHeight
);
3120 short nX
= (short)( ((rRect
.Left()+rRect
.Right())/2) / nDeltaWidth
);
3122 // Rundungsfehler abfangen
3124 nY
= sal::static_int_cast
< short >(nRows
- 1);
3126 nX
= sal::static_int_cast
< short >(nCols
- 1);
3128 USHORT nIns
= GetSortListPos( &pColumns
[nX
], rRect
.Top(), TRUE
);
3129 pColumns
[ nX
].Insert( pEntry
, nIns
);
3131 nIns
= GetSortListPos( &pRows
[nY
], rRect
.Left(), FALSE
);
3132 pRows
[ nY
].Insert( pEntry
, nIns
);
3137 pEntry
= pModel
->NextSibling( pEntry
);
3141 void ImpIcnCursor::CreateGridMap()
3146 const Size
& rSize
= pView
->aVirtOutputSize
;
3147 long nWidth
= rSize
.Width();
3148 if( nWidth
< pView
->nMaxVirtWidth
)
3149 nWidth
= pView
->nMaxVirtWidth
;
3150 nWidth
-= 2*LROFFS_WINBORDER
;
3154 nGridDX
= pView
->nGridDX
;
3155 nGridDY
= pView
->nGridDY
;
3157 // Hinweis: Wegen der Abrundung bei Berechnung von nGridCols
3158 // ist es moeglich, dass Eintrage nicht im Grid liegen. Diese
3159 // wurden typischerweise manuell verschoben und gelockt
3160 nGridCols
= nWidth
/ nGridDX
;
3161 if( !nGridCols
) nGridCols
= 1;
3163 nGridRows
= rSize
.Height() / nGridDY
;
3164 // nRows nicht abrunden, da zur Vermeidung von Ueberlappungen
3165 // das gesamte BoundingRect des Eintrags zur Markierung im Grid
3166 // herangezogen wird.
3167 if( (nGridRows
* nGridDY
) < rSize
.Height() )
3169 else if( !nGridRows
)
3173 //nGridRows += 50; // in fuenfziger-Schritten
3175 pGridMap
= new BOOL
[ nGridRows
*nGridCols
];
3176 memset( (void*)pGridMap
, 0, nGridRows
*nGridCols
);
3178 SvLBoxTreeList
* pModel
= pView
->pModel
;
3179 SvLBoxEntry
* pEntry
= pModel
->FirstChild( pView
->pCurParent
);
3182 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA2(pEntry
);
3183 const Rectangle
& rRect
= pViewData
->aRect
;
3184 // nur, wenn der Entry schon plaziert ist
3185 if( pView
->IsBoundingRectValid( rRect
))
3187 // Alle vom Eintrag beruehrten Grids kennzeichnen
3188 SetGridUsed( pView
->GetBoundingRect( pEntry
, pViewData
) );
3190 pEntry
= pModel
->NextSibling( pEntry
);
3194 BOOL
ImpIcnCursor::GetGrid( const Point
& rDocPos
, USHORT
& rGridX
, USHORT
& rGridY
) const
3196 Point
aPos( rDocPos
);
3197 aPos
.X() -= LROFFS_WINBORDER
;
3198 aPos
.Y() -= TBOFFS_WINBORDER
;
3199 rGridX
= (USHORT
)(aPos
.X() / nGridDX
);
3200 rGridY
= (USHORT
)(aPos
.Y() / nGridDY
);
3201 BOOL bInGrid
= TRUE
;
3202 if( rGridX
>= nGridCols
)
3204 rGridX
= sal::static_int_cast
< USHORT
>(nGridCols
- 1);
3207 if( rGridY
>= nGridRows
)
3209 rGridY
= sal::static_int_cast
< USHORT
>(nGridRows
- 1);
3211 return FALSE
; // beide Koordinaten nicht im Grid
3216 void ImpIcnCursor::SetGridUsed( const Rectangle
& rRect
, BOOL bUsed
)
3219 USHORT nTLX
, nTLY
, nBRX
, nBRY
;
3221 BOOL bTLInGrid
= GetGrid( rRect
.TopLeft(), nTLX
, nTLY
);
3222 BOOL bBRInGrid
= GetGrid( rRect
.BottomRight(), nBRX
, nBRY
);
3224 if( !bTLInGrid
&& !bBRInGrid
)
3227 for( USHORT nCurY
= nTLY
; nCurY
<= nBRY
; nCurY
++ )
3229 for( USHORT nCurX
= nTLX
; nCurX
<= nBRX
; nCurX
++ )
3231 SetGridUsed( nCurX
, nCurY
, bUsed
);
3236 void ImpIcnCursor::Clear( BOOL bGridToo
)
3248 if( bGridToo
&& pGridMap
)
3256 SvLBoxEntry
* ImpIcnCursor::SearchCol(USHORT nCol
,USHORT nTop
,USHORT nBottom
,
3257 USHORT
, BOOL bDown
, BOOL bSimple
)
3259 DBG_ASSERT(pCurEntry
,"SearchCol: No reference entry");
3260 SvPtrarr
* pList
= &(pColumns
[ nCol
]);
3261 USHORT nCount
= pList
->Count();
3265 const Rectangle
& rRefRect
= pView
->GetBoundingRect(pCurEntry
);
3269 USHORT nListPos
= pList
->GetPos( pCurEntry
);
3270 DBG_ASSERT(nListPos
!=0xffff,"Entry not in Col-List");
3273 while( nListPos
< nCount
-1 )
3276 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)pList
->GetObject( nListPos
);
3277 const Rectangle
& rRect
= pView
->GetBoundingRect( pEntry
);
3278 if( rRect
.Top() > rRefRect
.Top() )
3288 if( nListPos
< nCount
)
3290 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)pList
->GetObject( nListPos
);
3291 const Rectangle
& rRect
= pView
->GetBoundingRect( pEntry
);
3292 if( rRect
.Top() < rRefRect
.Top() )
3300 if( nTop
> nBottom
)
3302 USHORT nTemp
= nTop
;
3306 long nMinDistance
= LONG_MAX
;
3307 SvLBoxEntry
* pResult
= 0;
3308 for( USHORT nCur
= 0; nCur
< nCount
; nCur
++ )
3310 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)(pList
->GetObject( nCur
));
3311 if( pEntry
!= pCurEntry
)
3313 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA2(pEntry
);
3314 USHORT nY
= pViewData
->nY
;
3315 if( nY
>= nTop
&& nY
<= nBottom
)
3317 const Rectangle
& rRect
= pView
->GetBoundingRect( pEntry
);
3318 long nDistance
= rRect
.Top() - rRefRect
.Top();
3321 if( nDistance
&& nDistance
< nMinDistance
)
3323 nMinDistance
= nDistance
;
3332 SvLBoxEntry
* ImpIcnCursor::SearchRow(USHORT nRow
,USHORT nLeft
,USHORT nRight
,
3333 USHORT
, BOOL bRight
, BOOL bSimple
)
3335 DBG_ASSERT(pCurEntry
,"SearchRow: No reference entry");
3336 SvPtrarr
* pList
= &(pRows
[ nRow
]);
3337 USHORT nCount
= pList
->Count();
3341 const Rectangle
& rRefRect
= pView
->GetBoundingRect(pCurEntry
);
3345 USHORT nListPos
= pList
->GetPos( pCurEntry
);
3346 DBG_ASSERT(nListPos
!=0xffff,"Entry not in Row-List");
3349 while( nListPos
< nCount
-1 )
3352 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)pList
->GetObject( nListPos
);
3353 const Rectangle
& rRect
= pView
->GetBoundingRect( pEntry
);
3354 if( rRect
.Left() > rRefRect
.Left() )
3364 if( nListPos
< nCount
)
3366 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)pList
->GetObject( nListPos
);
3367 const Rectangle
& rRect
= pView
->GetBoundingRect( pEntry
);
3368 if( rRect
.Left() < rRefRect
.Left() )
3376 if( nRight
< nLeft
)
3378 USHORT nTemp
= nRight
;
3382 long nMinDistance
= LONG_MAX
;
3383 SvLBoxEntry
* pResult
= 0;
3384 for( USHORT nCur
= 0; nCur
< nCount
; nCur
++ )
3386 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)(pList
->GetObject( nCur
));
3387 if( pEntry
!= pCurEntry
)
3389 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA2(pEntry
);
3390 USHORT nX
= pViewData
->nX
;
3391 if( nX
>= nLeft
&& nX
<= nRight
)
3393 const Rectangle
& rRect
= pView
->GetBoundingRect( pEntry
);
3394 long nDistance
= rRect
.Left() - rRefRect
.Left();
3397 if( nDistance
&& nDistance
< nMinDistance
)
3399 nMinDistance
= nDistance
;
3411 Sucht ab dem uebergebenen Eintrag den naechsten rechts- bzw.
3412 linksstehenden. Suchverfahren am Beispiel bRight = TRUE:
3417 S 1 1 1 ====> Suchrichtung
3423 1 : erstes Suchrechteck
3424 a,b,c : 2., 3., 4. Suchrechteck
3427 SvLBoxEntry
* ImpIcnCursor::GoLeftRight( SvLBoxEntry
* pIcnEntry
, BOOL bRight
)
3429 SvLBoxEntry
* pResult
;
3430 pCurEntry
= pIcnEntry
;
3432 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA2(pIcnEntry
);
3433 USHORT nY
= pViewData
->nY
;
3434 USHORT nX
= pViewData
->nX
;
3435 DBG_ASSERT(nY
< nRows
,"GoLeftRight:Bad column");
3436 DBG_ASSERT(nX
< nCols
,"GoLeftRight:Bad row");
3437 // Nachbar auf gleicher Zeile ?
3439 pResult
= SearchRow(
3440 nY
, nX
, sal::static_int_cast
< USHORT
>(nCols
-1), nX
, TRUE
, TRUE
);
3442 pResult
= SearchRow( nY
, nX
,0, nX
, FALSE
, TRUE
);
3448 long nColOffs
, nLastCol
;
3457 nLastCol
= -1; // 0-1
3460 USHORT nRowMin
= nY
;
3461 USHORT nRowMax
= nY
;
3464 SvLBoxEntry
* pEntry
= SearchCol((USHORT
)nCurCol
,nRowMin
,nRowMax
,nY
,TRUE
, FALSE
);
3469 if( nRowMax
< (nRows
-1))
3471 nCurCol
+= nColOffs
;
3472 } while( nCurCol
!= nLastCol
);
3476 SvLBoxEntry
* ImpIcnCursor::GoUpDown( SvLBoxEntry
* pIcnEntry
, BOOL bDown
)
3478 SvLBoxEntry
* pResult
;
3479 pCurEntry
= pIcnEntry
;
3481 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA2(pIcnEntry
);
3482 USHORT nY
= pViewData
->nY
;
3483 USHORT nX
= pViewData
->nX
;
3484 DBG_ASSERT(nY
<nRows
,"GoUpDown:Bad column");
3485 DBG_ASSERT(nX
<nCols
,"GoUpDown:Bad row");
3487 // Nachbar in gleicher Spalte ?
3489 pResult
= SearchCol(
3490 nX
, nY
, sal::static_int_cast
< USHORT
>(nRows
-1), nY
, TRUE
, TRUE
);
3492 pResult
= SearchCol( nX
, nY
,0, nY
, FALSE
, TRUE
);
3498 long nRowOffs
, nLastRow
;
3507 nLastRow
= -1; // 0-1
3510 USHORT nColMin
= nX
;
3511 USHORT nColMax
= nX
;
3514 SvLBoxEntry
* pEntry
= SearchRow((USHORT
)nCurRow
,nColMin
,nColMax
,nX
,TRUE
, FALSE
);
3519 if( nColMax
< (nCols
-1))
3521 nCurRow
+= nRowOffs
;
3522 } while( nCurRow
!= nLastRow
);
3526 void ImpIcnCursor::SetDeltas()
3528 const Size
& rSize
= pView
->aVirtOutputSize
;
3529 if( pView
->nFlags
& F_GRIDMODE
)
3531 nGridDX
= pView
->nGridDX
;
3532 nGridDY
= pView
->nGridDY
;
3539 nCols
= rSize
.Width() / nGridDX
;
3542 nRows
= rSize
.Height() / nGridDY
;
3543 if( (nRows
* nGridDY
) < rSize
.Height() )
3548 nDeltaWidth
= (short)(rSize
.Width() / nCols
);
3549 nDeltaHeight
= (short)(rSize
.Height() / nRows
);
3553 DBG_WARNING("SetDeltas:Bad height");
3558 DBG_WARNING("SetDeltas:Bad width");
3563 void ImpIcnCursor::ExpandGrid()
3567 long nNewGridRows
= nGridRows
+ 20;
3568 unsigned char* pTempMap
= new unsigned char[ nNewGridRows
* nGridCols
];
3569 memcpy( pTempMap
, pGridMap
, nGridRows
* nGridCols
);
3571 pGridMap
= pTempMap
;
3572 nGridRows
= nNewGridRows
;
3576 BOOL
ImpIcnCursor::FindEmptyGridRect( Rectangle
& rRect
)
3579 USHORT nCount
= (USHORT
)(nGridCols
* nGridRows
);
3582 for( USHORT nCur
= 0; nCur
< nCount
; nCur
++ )
3584 if( !pGridMap
[ nCur
] )
3586 USHORT nCol
= (USHORT
)(nCur
% nGridCols
);
3587 USHORT nRow
= (USHORT
)(nCur
/ nGridCols
);
3588 rRect
.Top() = nRow
* nGridDY
+ TBOFFS_WINBORDER
;
3589 rRect
.Bottom() = rRect
.Top() + nGridDY
;
3590 rRect
.Left() = nCol
* nGridDX
+ LROFFS_WINBORDER
;
3591 rRect
.Right() = rRect
.Left() + nGridDX
;
3592 SetGridUsed( nCol
, nRow
, TRUE
);
3595 //if( nRow + 5 > nGridRows )
3597 DBG_ASSERT(pGridMap
[nCur
],"SetGridUsed failed");
3601 // Gridmap ist voll: Um eine Zeile erweitern
3602 rRect
.Top() = nGridRows
* nGridDY
+ TBOFFS_WINBORDER
;
3603 rRect
.Bottom() = rRect
.Top() + nGridDY
;
3604 rRect
.Left() = LROFFS_WINBORDER
;
3605 rRect
.Right() = rRect
.Left() + nGridDX
;
3612 void ImpIcnCursor::CreateGridAjustData( SvPtrarr
& rLists
, SvLBoxEntry
* pRefEntry
)
3616 USHORT nAdjustRows
= (USHORT
)(pView
->aVirtOutputSize
.Height() / pView
->nGridDY
);
3617 nAdjustRows
++; // wg. Abrundung!
3621 for( USHORT nCurList
= 0; nCurList
< nAdjustRows
; nCurList
++ )
3623 SvPtrarr
* pRow
= new SvPtrarr
;
3624 rLists
.Insert( (void*)pRow
, nCurList
);
3626 SvLBoxEntry
* pEntry
= pView
->pModel
->FirstChild( pView
->pCurParent
);
3629 const Rectangle
& rRect
= pView
->GetBoundingRect( pEntry
);
3630 short nY
= (short)( ((rRect
.Top()+rRect
.Bottom())/2) / pView
->nGridDY
);
3631 USHORT nIns
= GetSortListPos((SvPtrarr
*)rLists
[nY
],rRect
.Left(),FALSE
);
3632 ((SvPtrarr
*)rLists
[ nY
])->Insert( pEntry
, nIns
);
3633 pEntry
= pView
->pModel
->NextSibling( pEntry
);
3638 // Aufbau eines hor. "Schlauchs" auf der RefEntry-Zeile
3640 // UEBERLEGEN: BoundingRect nehmen wg. Ueberlappungen???
3642 Rectangle
rRefRect( pView
->CalcBmpRect( pRefEntry
) );
3643 //const Rectangle& rRefRect = pView->GetBoundingRect( pRefEntry );
3644 short nRefRow
= (short)( ((rRefRect
.Top()+rRefRect
.Bottom())/2) / pView
->nGridDY
);
3645 SvPtrarr
* pRow
= new SvPtrarr
;
3646 rLists
.Insert( (void*)pRow
, 0 );
3647 SvLBoxEntry
* pEntry
= pView
->pModel
->FirstChild( pView
->pCurParent
);
3650 Rectangle
rRect( pView
->CalcBmpRect(pEntry
) );
3651 //const Rectangle& rRect = pView->GetBoundingRect( pEntry );
3652 short nY
= (short)( ((rRect
.Top()+rRect
.Bottom())/2) / pView
->nGridDY
);
3655 USHORT nIns
= GetSortListPos( pRow
, rRect
.Left(), FALSE
);
3656 pRow
->Insert( pEntry
, nIns
);
3658 pEntry
= pView
->pModel
->NextSibling( pEntry
);
3664 void ImpIcnCursor::DestroyGridAdjustData( SvPtrarr
& rLists
)
3666 USHORT nCount
= rLists
.Count();
3667 for( USHORT nCur
= 0; nCur
< nCount
; nCur
++ )
3669 SvPtrarr
* pArr
= (SvPtrarr
*)rLists
[ nCur
];
3672 rLists
.Remove( 0, rLists
.Count() );
3675 void SvImpIconView::SetGrid( long nDX
, long nDY
)
3679 nFlags
|= F_GRIDMODE
;
3682 Rectangle
SvImpIconView::CalcMaxTextRect( const SvLBoxEntry
* pEntry
,
3683 const SvIcnVwDataEntry
* pViewData
) const
3685 Rectangle aRect
= pViewData
->aGridRect
;
3686 long nBmpHeight
= ((SvLBoxEntry
*)pEntry
)->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
)->GetSize(pView
,(SvLBoxEntry
*)pEntry
).Height();
3687 aRect
.Top() += nBmpHeight
;
3688 aRect
.Top() += ICONVIEW_OFFS_BMP_STRING
;
3689 if( aRect
.Top() > aRect
.Bottom())
3690 aRect
.Top() = aRect
.Bottom();
3691 aRect
.Left() += LROFFS_BOUND
;
3693 aRect
.Right() -= LROFFS_BOUND
;
3695 if( aRect
.Left() > aRect
.Right())
3696 aRect
.Left() = aRect
.Right();
3697 if( GetTextMode( pEntry
, pViewData
) == ShowTextFull
)
3698 aRect
.Bottom() = LONG_MAX
;
3702 void SvImpIconView::Center( SvLBoxEntry
* pEntry
,
3703 SvIcnVwDataEntry
* pViewData
) const
3705 SvLBoxString
* pStringItem
= (SvLBoxString
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
3706 const String
& rEntryText
= pStringItem
->GetText();
3708 Rectangle aTextRect
= CalcMaxTextRect(pEntry
,pViewData
);
3709 aTextRect
= GetTextRect( pView
, aTextRect
, rEntryText
, DRAWTEXT_FLAGS
);
3710 pViewData
->aTextSize
= aTextRect
.GetSize();
3712 pViewData
->aRect
= pViewData
->aGridRect
;
3713 Size
aSize( CalcBoundingSize( pEntry
, pViewData
) );
3714 long nBorder
= pViewData
->aGridRect
.GetWidth() - aSize
.Width();
3715 pViewData
->aRect
.Left() += nBorder
/ 2;
3716 pViewData
->aRect
.Right() -= nBorder
/ 2;
3717 pViewData
->aRect
.Bottom() = pViewData
->aRect
.Top() + aSize
.Height();
3721 // Die Deltas entsprechen Offsets, um die die View auf dem Doc verschoben wird
3722 // links, hoch: Offsets < 0
3723 // rechts, runter: Offsets > 0
3724 void SvImpIconView::Scroll( long nDeltaX
, long nDeltaY
, BOOL bScrollBar
)
3726 const MapMode
& rMapMode
= pView
->GetMapMode();
3727 Point
aOrigin( rMapMode
.GetOrigin() );
3728 // in Dokumentkoordinate umwandeln
3730 aOrigin
.Y() += nDeltaY
;
3731 aOrigin
.X() += nDeltaX
;
3732 Rectangle
aRect( aOrigin
, aOutputSize
);
3733 MakeVisible( aRect
, bScrollBar
);
3737 const Size
& SvImpIconView::GetItemSize( SvIconView
* pIconView
,
3738 SvLBoxEntry
* pEntry
, SvLBoxItem
* pItem
, const SvIcnVwDataEntry
* pViewData
) const
3740 if( (nFlags
& F_GRIDMODE
) && pItem
->IsA() == SV_ITEM_ID_LBOXSTRING
)
3743 pViewData
= ICNVIEWDATA(pEntry
);
3744 return pViewData
->aTextSize
;
3747 return pItem
->GetSize( pIconView
, pEntry
);
3750 Rectangle
SvImpIconView::CalcFocusRect( SvLBoxEntry
* pEntry
)
3753 SvLBoxString
* pStringItem
= (SvLBoxString
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
3754 DBG_ASSERT(pStringItem
,"Text not set");
3755 return CalcTextRect( pEntry
, pStringItem
);
3757 return CalcBmpRect( pEntry
);
3762 void SvImpIconView::SelectRect( const Rectangle
& rRect
, BOOL bAdd
,
3763 SvPtrarr
* pOtherRects
, short nBorderOffs
)
3765 if( !pZOrderList
|| !pZOrderList
->Count() )
3768 CheckBoundingRects();
3770 USHORT nCount
= pZOrderList
->Count();
3772 Rectangle
aRect( rRect
);
3776 aRect
.Left() -= nBorderOffs
;
3777 aRect
.Right() += nBorderOffs
;
3778 aRect
.Top() -= nBorderOffs
;
3779 aRect
.Bottom() += nBorderOffs
;
3781 BOOL bCalcOverlap
= (bAdd
&& pOtherRects
&& pOtherRects
->Count()) ? TRUE
: FALSE
;
3783 for( USHORT nPos
= 0; nPos
< nCount
; nPos
++ )
3785 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)(pZOrderList
->GetObject(nPos
));
3787 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
3788 DBG_ASSERT(pViewData
,"Entry not in model");
3789 if( !IsBoundingRectValid( pViewData
->aRect
))
3790 FindBoundingRect( pEntry
, pViewData
);
3791 const Rectangle
& rBoundRect
= pViewData
->aRect
;
3792 BOOL bSelected
= pViewData
->IsSelected();
3796 bOverlaps
= IsOver( pOtherRects
, rBoundRect
);
3799 BOOL bOver
= aRect
.IsOver( rBoundRect
);
3801 if( bOver
&& !bOverlaps
)
3803 // Ist im neuen Selektionsrechteck und in keinem alten
3806 pView
->Select( pEntry
, TRUE
);
3810 // ist ausserhalb des Selektionsrechtecks
3811 // => Selektion entfernen
3813 pView
->Select( pEntry
, FALSE
);
3815 else if( bAdd
&& bOverlaps
)
3817 // Der Eintrag befindet sich in einem alten (=>Aufspannen
3818 // mehrerer Rechtecke mit Ctrl!) Selektionsrechteck
3820 // Hier ist noch ein Bug! Der Selektionsstatus eines Eintrags
3821 // in einem vorherigen Rechteck, muss restauriert werden, wenn
3822 // er vom aktuellen Selektionsrechteck beruehrt wurde, jetzt aber
3823 // nicht mehr in ihm liegt. Ich gehe hier der Einfachheit halber
3824 // pauschal davon aus, dass die Eintraege in den alten Rechtecken
3825 // alle selektiert sind. Ebenso ist es falsch, die Schnittmenge
3826 // nur zu deselektieren.
3827 // Loesungsmoeglichkeit: Snapshot der Selektion vor dem Auf-
3828 // spannen des Rechtecks merken
3829 if( rBoundRect
.IsOver( rRect
))
3831 // Schnittmenge zwischen alten Rects & aktuellem Rect desel.
3833 pView
->Select( pEntry
, FALSE
);
3837 // Eintrag eines alten Rects selektieren
3839 pView
->Select( pEntry
, TRUE
);
3842 else if( !bOver
&& bSelected
)
3844 // Der Eintrag liegt voellig ausserhalb und wird deshalb desel.
3845 pView
->Select( pEntry
, FALSE
);
3851 BOOL
SvImpIconView::IsOver( SvPtrarr
* pRectList
, const Rectangle
& rBoundRect
) const
3853 USHORT nCount
= pRectList
->Count();
3854 for( USHORT nCur
= 0; nCur
< nCount
; nCur
++ )
3856 Rectangle
* pRect
= (Rectangle
*)pRectList
->GetObject( nCur
);
3857 if( rBoundRect
.IsOver( *pRect
))
3863 void SvImpIconView::AddSelectedRect( const Rectangle
& rRect
, short nBorderOffs
)
3865 Rectangle
* pRect
= new Rectangle( rRect
);
3869 pRect
->Left() -= nBorderOffs
;
3870 pRect
->Right() += nBorderOffs
;
3871 pRect
->Top() -= nBorderOffs
;
3872 pRect
->Bottom() += nBorderOffs
;
3874 aSelectedRectList
.Insert( (void*)pRect
, aSelectedRectList
.Count() );
3877 void SvImpIconView::ClearSelectedRectList()
3879 USHORT nCount
= aSelectedRectList
.Count();
3880 for( USHORT nCur
= 0; nCur
< nCount
; nCur
++ )
3882 Rectangle
* pRect
= (Rectangle
*)aSelectedRectList
.GetObject( nCur
);
3885 aSelectedRectList
.Remove( 0, aSelectedRectList
.Count() );
3889 void SvImpIconView::DrawSelectionRect( const Rectangle
& rRect
)
3891 pView
->HideTracking();
3892 nFlags
|= F_SELRECT_VISIBLE
;
3893 pView
->ShowTracking( rRect
, SHOWTRACK_SMALL
| SHOWTRACK_WINDOW
);
3894 aCurSelectionRect
= rRect
;
3897 void SvImpIconView::HideSelectionRect()
3899 if( nFlags
& F_SELRECT_VISIBLE
)
3901 pView
->HideTracking();
3902 nFlags
&= ~F_SELRECT_VISIBLE
;
3906 void SvImpIconView::ImpDrawXORRect( const Rectangle
& rRect
)
3908 RasterOp eOldOp
= pView
->GetRasterOp();
3909 pView
->SetRasterOp( ROP_XOR
);
3910 Color aOldColor
= pView
->GetFillColor();
3911 pView
->SetFillColor();
3912 pView
->DrawRect( rRect
);
3913 pView
->SetFillColor( aOldColor
);
3914 pView
->SetRasterOp( eOldOp
);
3917 void SvImpIconView::CalcScrollOffsets( const Point
& rPosPixel
,
3918 long& rX
, long& rY
, BOOL bInDragDrop
, USHORT nBorderWidth
)
3920 // Scrolling der View, falls sich der Mauszeiger im Grenzbereich des
3921 // Fensters befindet
3922 long nPixelToScrollX
= 0;
3923 long nPixelToScrollY
= 0;
3924 Size aWndSize
= aOutputSize
;
3926 nBorderWidth
= (USHORT
)(Min( (long)(aWndSize
.Height()-1), (long)nBorderWidth
));
3927 nBorderWidth
= (USHORT
)(Min( (long)(aWndSize
.Width()-1), (long)nBorderWidth
));
3929 if ( rPosPixel
.X() < nBorderWidth
)
3932 nPixelToScrollX
= -DD_SCROLL_PIXEL
;
3934 nPixelToScrollX
= rPosPixel
.X()- nBorderWidth
;
3936 else if ( rPosPixel
.X() > aWndSize
.Width() - nBorderWidth
)
3939 nPixelToScrollX
= DD_SCROLL_PIXEL
;
3941 nPixelToScrollX
= rPosPixel
.X() - (aWndSize
.Width() - nBorderWidth
);
3943 if ( rPosPixel
.Y() < nBorderWidth
)
3946 nPixelToScrollY
= -DD_SCROLL_PIXEL
;
3948 nPixelToScrollY
= rPosPixel
.Y() - nBorderWidth
;
3950 else if ( rPosPixel
.Y() > aWndSize
.Height() - nBorderWidth
)
3953 nPixelToScrollY
= DD_SCROLL_PIXEL
;
3955 nPixelToScrollY
= rPosPixel
.Y() - (aWndSize
.Height() - nBorderWidth
);
3958 rX
= nPixelToScrollX
;
3959 rY
= nPixelToScrollY
;
3962 IMPL_LINK(SvImpIconView
, MouseMoveTimeoutHdl
, Timer
*, pTimer
)
3965 MouseMove( aMouseMoveEvent
);
3969 void SvImpIconView::EndTracking()
3971 pView
->ReleaseMouse();
3972 if( nFlags
& F_RUBBERING
)
3974 aMouseMoveTimer
.Stop();
3975 nFlags
&= ~(F_RUBBERING
| F_ADD_MODE
);
3979 BOOL
SvImpIconView::IsTextHit( SvLBoxEntry
* pEntry
, const Point
& rDocPos
)
3981 SvLBoxString
* pItem
= (SvLBoxString
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
3984 Rectangle
aRect( CalcTextRect( pEntry
, pItem
));
3985 if( aRect
.IsInside( rDocPos
) )
3991 IMPL_LINK(SvImpIconView
, EditTimeoutHdl
, Timer
*, EMPTYARG
)
3993 SvLBoxEntry
* pEntry
= GetCurEntry();
3994 if( pView
->IsInplaceEditingEnabled() && pEntry
&&
3995 pView
->IsSelected( pEntry
))
3997 pView
->EditEntry( pEntry
);
4004 // Funktionen zum Ausrichten der Eintraege am Grid
4007 // pStart == 0: Alle Eintraege werden ausgerichtet
4008 // sonst: Alle Eintraege der Zeile ab einschliesslich pStart werden ausgerichtet
4009 void SvImpIconView::AdjustAtGrid( SvLBoxEntry
* pStart
)
4012 pImpCursor
->CreateGridAjustData( aLists
, pStart
);
4013 USHORT nCount
= aLists
.Count();
4014 for( USHORT nCur
= 0; nCur
< nCount
; nCur
++ )
4016 AdjustAtGrid( *(SvPtrarr
*)aLists
[ nCur
], pStart
);
4018 ImpIcnCursor::DestroyGridAdjustData( aLists
);
4022 // Richtet eine Zeile aus, erweitert ggf. die Breite; Bricht die Zeile nicht um
4023 void SvImpIconView::AdjustAtGrid( const SvPtrarr
& rRow
, SvLBoxEntry
* pStart
)
4035 for( USHORT nCur
= 0; nCur
< rRow
.Count(); nCur
++ )
4037 SvLBoxEntry
* pCur
= (SvLBoxEntry
*)rRow
[ nCur
];
4038 if( !bGo
&& pCur
== pStart
)
4041 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pCur
);
4042 // Massgebend (fuer das menschliche Auge) ist die Bitmap, da sonst
4043 // durch lange Texte der Eintrag stark springen kann
4044 const Rectangle
& rBoundRect
= GetBoundingRect( pCur
, pViewData
);
4045 Rectangle
aCenterRect( CalcBmpRect( pCur
, 0, pViewData
));
4046 if( bGo
&& !pViewData
->IsEntryPosLocked() )
4048 long nWidth
= aCenterRect
.GetSize().Width();
4049 Point
aNewPos( AdjustAtGrid( aCenterRect
, rBoundRect
) );
4050 while( aNewPos
.X() < nCurRight
)
4051 aNewPos
.X() += nGridDX
;
4052 if( aNewPos
!= rBoundRect
.TopLeft() )
4053 SetEntryPosition( pCur
, aNewPos
);
4054 nCurRight
= aNewPos
.X() + nWidth
;
4058 nCurRight
= rBoundRect
.Right();
4063 // Richtet Rect am Grid aus, garantiert jedoch nicht, dass die
4064 // neue Pos. frei ist. Die Pos. kann fuer SetEntryPos verwendet werden.
4065 // Das CenterRect beschreibt den Teil des BoundRects, der fuer
4066 // die Berechnung des Ziel-Rechtecks verwendet wird.
4067 Point
SvImpIconView::AdjustAtGrid( const Rectangle
& rCenterRect
,
4068 const Rectangle
& rBoundRect
) const
4070 Point
aPos( rCenterRect
.TopLeft() );
4071 Size
aSize( rCenterRect
.GetSize() );
4073 aPos
.X() -= LROFFS_WINBORDER
;
4074 aPos
.Y() -= TBOFFS_WINBORDER
;
4076 // align (ref ist mitte des rects)
4077 short nGridX
= (short)((aPos
.X()+(aSize
.Width()/2)) / nGridDX
);
4078 short nGridY
= (short)((aPos
.Y()+(aSize
.Height()/2)) / nGridDY
);
4079 aPos
.X() = nGridX
* nGridDX
;
4080 aPos
.Y() = nGridY
* nGridDY
;
4082 aPos
.X() += (nGridDX
- rBoundRect
.GetSize().Width() ) / 2;
4084 aPos
.X() += LROFFS_WINBORDER
;
4085 aPos
.Y() += TBOFFS_WINBORDER
;
4091 void SvImpIconView::SetTextMode( SvIconViewTextMode eMode
, SvLBoxEntry
* pEntry
)
4095 if( eTextMode
!= eMode
)
4097 if( eTextMode
== ShowTextDontKnow
)
4098 eTextMode
= ShowTextShort
;
4105 SvIcnVwDataEntry
* pViewData
= ICNVIEWDATA(pEntry
);
4106 if( pViewData
->eTextMode
!= eMode
)
4108 pViewData
->eTextMode
= eMode
;
4109 pModel
->InvalidateEntry( pEntry
);
4110 AdjustVirtSize( pViewData
->aRect
);
4115 SvIconViewTextMode
SvImpIconView::GetTextMode( const SvLBoxEntry
* pEntry
,
4116 const SvIcnVwDataEntry
* pViewData
) const
4123 pViewData
= ICNVIEWDATA(((SvLBoxEntry
*)pEntry
));
4124 return pViewData
->GetTextMode();
4128 SvIconViewTextMode
SvImpIconView::GetEntryTextModeSmart( const SvLBoxEntry
* pEntry
,
4129 const SvIcnVwDataEntry
* pViewData
) const
4131 DBG_ASSERT(pEntry
,"GetEntryTextModeSmart: Entry not set");
4133 pViewData
= ICNVIEWDATA(((SvLBoxEntry
*)pEntry
));
4134 SvIconViewTextMode eMode
= pViewData
->GetTextMode();
4135 if( eMode
== ShowTextDontKnow
)
4140 void SvImpIconView::ShowFocusRect( const SvLBoxEntry
* pEntry
)
4146 Rectangle
aRect ( CalcFocusRect( (SvLBoxEntry
*)pEntry
) );
4147 pView
->ShowFocus( aRect
);
4151 IMPL_LINK(SvImpIconView
, UserEventHdl
, void*, EMPTYARG
)
4156 if( GetResizeRect(aRect
) )
4157 PaintResizeRect( aRect
);
4161 void SvImpIconView::CancelUserEvent()
4165 Application::RemoveUserEvent( nCurUserEvent
);