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: frmsel.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_svx.hxx"
33 #include <svx/frmsel.hxx>
37 #include "frmselimpl.hxx"
38 #include "AccessibleFrameSelector.hxx"
39 #include <svx/dialmgr.hxx>
41 #ifndef _SVX_DIALOGS_HRC
42 #include <svx/dialogs.hrc>
44 #ifndef SVX_FRMSEL_HRC
48 #include <tools/rcid.h>
52 using ::com::sun::star::uno::Reference
;
53 using ::com::sun::star::accessibility::XAccessible
;
55 // ============================================================================
56 // global functions from framebordertype.hxx
58 FrameBorderType
GetFrameBorderTypeFromIndex( size_t nIndex
)
60 DBG_ASSERT( nIndex
< (size_t)FRAMEBORDERTYPE_COUNT
,
61 "svx::GetFrameBorderTypeFromIndex - invalid index" );
62 return static_cast< FrameBorderType
>( nIndex
+ 1 );
65 size_t GetIndexFromFrameBorderType( FrameBorderType eBorder
)
67 DBG_ASSERT( eBorder
!= FRAMEBORDER_NONE
,
68 "svx::GetIndexFromFrameBorderType - invalid frame border type" );
69 return static_cast< size_t >( eBorder
) - 1;
72 // ============================================================================
76 /** Space between outer control border and any graphical element of the control. */
77 const long FRAMESEL_GEOM_OUTER
= 2;
79 /** Space between arrows and usable inner area. */
80 const long FRAMESEL_GEOM_INNER
= 3;
82 /** Maximum width to draw a frame border style. */
83 const long FRAMESEL_GEOM_WIDTH
= 9;
85 /** Additional margin for click area of outer lines. */
86 const long FRAMESEL_GEOM_ADD_CLICK_OUTER
= 5;
88 /** Additional margin for click area of inner lines. */
89 const long FRAMESEL_GEOM_ADD_CLICK_INNER
= 2;
91 // ----------------------------------------------------------------------------
93 static const frame::Style
OBJ_FRAMESTYLE_DONTCARE( 3, 0, 0 );
94 static const FrameBorder
OBJ_FRAMEBORDER_NONE( FRAMEBORDER_NONE
);
96 // ----------------------------------------------------------------------------
98 /** Returns the corresponding flag for a frame border. */
99 FrameSelFlags
lclGetFlagFromType( FrameBorderType eBorder
)
103 case FRAMEBORDER_LEFT
: return FRAMESEL_LEFT
;
104 case FRAMEBORDER_RIGHT
: return FRAMESEL_RIGHT
;
105 case FRAMEBORDER_TOP
: return FRAMESEL_TOP
;
106 case FRAMEBORDER_BOTTOM
: return FRAMESEL_BOTTOM
;
107 case FRAMEBORDER_HOR
: return FRAMESEL_INNER_HOR
;
108 case FRAMEBORDER_VER
: return FRAMESEL_INNER_VER
;
109 case FRAMEBORDER_TLBR
: return FRAMESEL_DIAG_TLBR
;
110 case FRAMEBORDER_BLTR
: return FRAMESEL_DIAG_BLTR
;
111 case FRAMEBORDER_NONE
: break;
113 return FRAMESEL_NONE
;
116 /** Converts an SvxBorderLine line width (in twips) to a pixel line width. */
117 inline sal_uInt16
lclGetPixel( USHORT nWidth
)
119 // convert all core styles expect 0 to a visible UI style (at least 1 pixel), map 1pt to 1pixel
120 return nWidth
? std::min
< sal_uInt16
>( std::max
< sal_uInt16
>( (nWidth
+ 5) / 20, 1 ), FRAMESEL_GEOM_WIDTH
) : 0;
123 /** Merges the rSource polypolygon into the rDest polypolygon. */
124 inline void lclPolyPolyUnion( PolyPolygon
& rDest
, const PolyPolygon
& rSource
)
126 const PolyPolygon
aTmp( rDest
);
127 aTmp
.GetUnion( rSource
, rDest
);
132 // ============================================================================
134 // ============================================================================
136 FrameBorder::FrameBorder( FrameBorderType eType
) :
138 meState( FRAMESTATE_HIDE
),
139 meKeyLeft( FRAMEBORDER_NONE
),
140 meKeyRight( FRAMEBORDER_NONE
),
141 meKeyTop( FRAMEBORDER_NONE
),
142 meKeyBottom( FRAMEBORDER_NONE
),
148 void FrameBorder::Enable( FrameSelFlags nFlags
)
150 mbEnabled
= (nFlags
& lclGetFlagFromType( meType
)) != 0;
152 SetState( FRAMESTATE_HIDE
);
155 void FrameBorder::SetCoreStyle( const SvxBorderLine
* pStyle
)
158 maCoreStyle
= *pStyle
;
160 maCoreStyle
= SvxBorderLine();
162 // from twips to points
163 maUIStyle
.Set( maCoreStyle
, 0.05, FRAMESEL_GEOM_WIDTH
, true );
164 meState
= maUIStyle
.Prim() ? FRAMESTATE_SHOW
: FRAMESTATE_HIDE
;
167 void FrameBorder::SetState( FrameBorderState eState
)
172 case FRAMESTATE_SHOW
:
173 DBG_ERRORFILE( "svx::FrameBorder::SetState - use SetCoreStyle to make border visible" );
175 case FRAMESTATE_HIDE
:
176 maCoreStyle
= SvxBorderLine();
179 case FRAMESTATE_DONTCARE
:
180 maCoreStyle
= SvxBorderLine();
181 maUIStyle
= OBJ_FRAMESTYLE_DONTCARE
;
186 void FrameBorder::AddFocusPolygon( const Polygon
& rFocus
)
188 lclPolyPolyUnion( maFocusArea
, rFocus
);
191 void FrameBorder::MergeFocusToPolyPolygon( PolyPolygon
& rPPoly
) const
193 lclPolyPolyUnion( rPPoly
, maFocusArea
);
196 void FrameBorder::AddClickRect( const Rectangle
& rRect
)
198 lclPolyPolyUnion( maClickArea
, Polygon( rRect
) );
201 bool FrameBorder::ContainsClickPoint( const Point
& rPos
) const
203 return Region( maClickArea
).IsInside( rPos
);
206 void FrameBorder::MergeClickAreaToPolyPolygon( PolyPolygon
& rPPoly
) const
208 lclPolyPolyUnion( rPPoly
, maClickArea
);
211 Rectangle
FrameBorder::GetClickBoundRect() const
213 return maClickArea
.GetBoundRect();
216 void FrameBorder::SetKeyboardNeighbors(
217 FrameBorderType eLeft
, FrameBorderType eRight
, FrameBorderType eTop
, FrameBorderType eBottom
)
222 meKeyBottom
= eBottom
;
225 FrameBorderType
FrameBorder::GetKeyboardNeighbor( USHORT nKeyCode
) const
227 FrameBorderType eBorder
= FRAMEBORDER_NONE
;
230 case KEY_LEFT
: eBorder
= meKeyLeft
; break;
231 case KEY_RIGHT
: eBorder
= meKeyRight
; break;
232 case KEY_UP
: eBorder
= meKeyTop
; break;
233 case KEY_DOWN
: eBorder
= meKeyBottom
; break;
234 default: DBG_ERRORFILE( "svx::FrameBorder::GetKeyboardNeighbor - unknown key code" );
239 // ============================================================================
241 // ============================================================================
243 FrameSelectorImpl::FrameSelectorImpl( FrameSelector
& rFrameSel
) :
244 Resource( SVX_RES( RID_SVXSTR_BORDER_CONTROL
) ),
245 mrFrameSel( rFrameSel
),
247 maLeft( FRAMEBORDER_LEFT
),
248 maRight( FRAMEBORDER_RIGHT
),
249 maTop( FRAMEBORDER_TOP
),
250 maBottom( FRAMEBORDER_BOTTOM
),
251 maHor( FRAMEBORDER_HOR
),
252 maVer( FRAMEBORDER_VER
),
253 maTLBR( FRAMEBORDER_TLBR
),
254 maBLTR( FRAMEBORDER_BLTR
),
255 mnFlags( FRAMESEL_OUTER
),
260 mbFullRepaint( true ),
261 mbAutoSelect( true ),
265 maChildVec( 8, static_cast< a11y::AccFrameSelector
* >( 0 ) ),
270 maAllBorders
.resize( FRAMEBORDERTYPE_COUNT
, 0 );
271 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_LEFT
) ] = &maLeft
;
272 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_RIGHT
) ] = &maRight
;
273 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_TOP
) ] = &maTop
;
274 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_BOTTOM
) ] = &maBottom
;
275 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_HOR
) ] = &maHor
;
276 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_VER
) ] = &maVer
;
277 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_TLBR
) ] = &maTLBR
;
278 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_BLTR
) ] = &maBLTR
;
279 #if OSL_DEBUG_LEVEL >= 2
282 for( FrameBorderCIter
aIt( maAllBorders
); bOk
&& aIt
.Is(); bOk
= (*aIt
!= 0), ++aIt
);
283 DBG_ASSERT( bOk
, "svx::FrameSelectorImpl::FrameSelectorImpl - missing entry in maAllBorders" );
286 // left neighbor right neighbor upper neighbor lower neighbor
287 maLeft
.SetKeyboardNeighbors( FRAMEBORDER_NONE
, FRAMEBORDER_TLBR
, FRAMEBORDER_TOP
, FRAMEBORDER_BOTTOM
);
288 maRight
.SetKeyboardNeighbors( FRAMEBORDER_BLTR
, FRAMEBORDER_NONE
, FRAMEBORDER_TOP
, FRAMEBORDER_BOTTOM
);
289 maTop
.SetKeyboardNeighbors( FRAMEBORDER_LEFT
, FRAMEBORDER_RIGHT
, FRAMEBORDER_NONE
, FRAMEBORDER_TLBR
);
290 maBottom
.SetKeyboardNeighbors( FRAMEBORDER_LEFT
, FRAMEBORDER_RIGHT
, FRAMEBORDER_BLTR
, FRAMEBORDER_NONE
);
291 maHor
.SetKeyboardNeighbors( FRAMEBORDER_LEFT
, FRAMEBORDER_RIGHT
, FRAMEBORDER_TLBR
, FRAMEBORDER_BLTR
);
292 maVer
.SetKeyboardNeighbors( FRAMEBORDER_TLBR
, FRAMEBORDER_BLTR
, FRAMEBORDER_TOP
, FRAMEBORDER_BOTTOM
);
293 maTLBR
.SetKeyboardNeighbors( FRAMEBORDER_LEFT
, FRAMEBORDER_VER
, FRAMEBORDER_TOP
, FRAMEBORDER_HOR
);
294 maBLTR
.SetKeyboardNeighbors( FRAMEBORDER_VER
, FRAMEBORDER_RIGHT
, FRAMEBORDER_HOR
, FRAMEBORDER_BOTTOM
);
297 FrameSelectorImpl::~FrameSelectorImpl()
300 mpAccess
->Invalidate();
301 for( AccessibleImplVec::iterator aIt
= maChildVec
.begin(), aEnd
= maChildVec
.end(); aIt
!= aEnd
; ++aIt
)
303 (*aIt
)->Invalidate();
306 // initialization -------------------------------------------------------------
308 void FrameSelectorImpl::Initialize( FrameSelFlags nFlags
)
312 maEnabBorders
.clear();
313 for( FrameBorderIter
aIt( maAllBorders
); aIt
.Is(); ++aIt
)
315 (*aIt
)->Enable( mnFlags
);
316 if( (*aIt
)->IsEnabled() )
317 maEnabBorders
.push_back( *aIt
);
319 mbHor
= maHor
.IsEnabled();
320 mbVer
= maVer
.IsEnabled();
321 mbTLBR
= maTLBR
.IsEnabled();
322 mbBLTR
= maBLTR
.IsEnabled();
327 void FrameSelectorImpl::InitColors()
329 const StyleSettings
& rSett
= mrFrameSel
.GetSettings().GetStyleSettings();
330 maBackCol
= rSett
.GetFieldColor();
331 mbHCMode
= maBackCol
.IsDark();
332 maArrowCol
= rSett
.GetFieldTextColor();
333 maMarkCol
.operator=( maBackCol
).Merge( maArrowCol
, mbHCMode
? 0x80 : 0xC0 );
334 maHCLineCol
= rSett
.GetLabelTextColor();
337 void FrameSelectorImpl::InitArrowImageList()
339 /* Build the arrow images bitmap with current colors. */
342 pColorAry1
[0] = Color( 0, 0, 0 );
343 pColorAry2
[0] = maArrowCol
; // black -> arrow color
344 pColorAry1
[1] = Color( 0, 255, 0 );
345 pColorAry2
[1] = maMarkCol
; // green -> marker color
346 pColorAry1
[2] = Color( 255, 0, 255 );
347 pColorAry2
[2] = maBackCol
; // magenta -> background
349 GetRes( SVX_RES( RID_SVXSTR_BORDER_CONTROL
).SetRT( RSC_RESOURCE
) );
350 maILArrows
.InsertFromHorizontalBitmap(
351 SVX_RES( BMP_FRMSEL_ARROWS
), 16, NULL
, pColorAry1
, pColorAry2
, 3);
353 DBG_ASSERT( maILArrows
.GetImageSize().Height() == maILArrows
.GetImageSize().Width(),
354 "svx::FrameSelectorImpl::InitArrowImageList - images are not squarish" );
355 mnArrowSize
= maILArrows
.GetImageSize().Height();
358 void FrameSelectorImpl::InitGlobalGeometry()
360 Size
aCtrlSize( mrFrameSel
.CalcOutputSize( mrFrameSel
.GetSizePixel() ) );
361 /* nMinSize is the lower of width and height (control will always be squarish).
362 FRAMESEL_GEOM_OUTER is the minimal distance between inner control border
364 long nMinSize
= Min( aCtrlSize
.Width(), aCtrlSize
.Height() ) - 2 * FRAMESEL_GEOM_OUTER
;
365 /* nFixedSize is the size all existing elements need in one direction:
366 the diag. arrow, space betw. arrow and frame border, outer frame border,
367 inner frame border, other outer frame border, space betw. frame border
368 and arrow, the other arrow. */
369 long nFixedSize
= 2 * mnArrowSize
+ 2 * FRAMESEL_GEOM_INNER
+ 3 * FRAMESEL_GEOM_WIDTH
;
370 /* nBetwBordersSize contains the size between an outer and inner frame border (made odd). */
371 long nBetwBordersSize
= (((nMinSize
- nFixedSize
) / 2) - 1) | 1;
373 /* The final size of the usable area. */
374 mnCtrlSize
= 2 * nBetwBordersSize
+ nFixedSize
;
375 maVirDev
.SetOutputSizePixel( Size( mnCtrlSize
, mnCtrlSize
) );
377 /* Center the virtual device in the control. */
378 maVirDevPos
= Point( (aCtrlSize
.Width() - mnCtrlSize
) / 2, (aCtrlSize
.Height() - mnCtrlSize
) / 2 );
381 void FrameSelectorImpl::InitBorderGeometry()
383 size_t nCol
, nCols
, nRow
, nRows
;
385 // Global border geometry values ------------------------------------------
387 /* mnLine* is the middle point inside a frame border (i.e. mnLine1 is mid X inside left border). */
388 mnLine1
= mnArrowSize
+ FRAMESEL_GEOM_INNER
+ FRAMESEL_GEOM_WIDTH
/ 2;
389 mnLine2
= mnCtrlSize
/ 2;
390 mnLine3
= 2 * mnLine2
- mnLine1
;
392 // Frame helper array -----------------------------------------------------
394 maArray
.Initialize( mbVer
? 2 : 1, mbHor
? 2 : 1 );
395 maArray
.SetUseDiagDoubleClipping( true );
397 maArray
.SetXOffset( mnLine1
);
398 maArray
.SetAllColWidths( (mbVer
? mnLine2
: mnLine3
) - mnLine1
);
400 maArray
.SetYOffset( mnLine1
);
401 maArray
.SetAllRowHeights( (mbHor
? mnLine2
: mnLine3
) - mnLine1
);
403 Rectangle
aTLRect( maArray
.GetCellRect( 0, 0 ) );
405 // Focus polygons ---------------------------------------------------------
407 /* Width for focus rectangles from center of frame borders. */
408 mnFocusOffs
= FRAMESEL_GEOM_WIDTH
/ 2 + 1;
410 maLeft
.AddFocusPolygon( Rectangle( mnLine1
- mnFocusOffs
, mnLine1
- mnFocusOffs
, mnLine1
+ mnFocusOffs
, mnLine3
+ mnFocusOffs
) );
411 maVer
.AddFocusPolygon( Rectangle( mnLine2
- mnFocusOffs
, mnLine1
- mnFocusOffs
, mnLine2
+ mnFocusOffs
, mnLine3
+ mnFocusOffs
) );
412 maRight
.AddFocusPolygon( Rectangle( mnLine3
- mnFocusOffs
, mnLine1
- mnFocusOffs
, mnLine3
+ mnFocusOffs
, mnLine3
+ mnFocusOffs
) );
413 maTop
.AddFocusPolygon( Rectangle( mnLine1
- mnFocusOffs
, mnLine1
- mnFocusOffs
, mnLine3
+ mnFocusOffs
, mnLine1
+ mnFocusOffs
) );
414 maHor
.AddFocusPolygon( Rectangle( mnLine1
- mnFocusOffs
, mnLine2
- mnFocusOffs
, mnLine3
+ mnFocusOffs
, mnLine2
+ mnFocusOffs
) );
415 maBottom
.AddFocusPolygon( Rectangle( mnLine1
- mnFocusOffs
, mnLine3
- mnFocusOffs
, mnLine3
+ mnFocusOffs
, mnLine3
+ mnFocusOffs
) );
417 for( nCol
= 0, nCols
= maArray
.GetColCount(); nCol
< nCols
; ++nCol
)
419 for( nRow
= 0, nRows
= maArray
.GetRowCount(); nRow
< nRows
; ++nRow
)
421 Rectangle
aRect( maArray
.GetCellRect( nCol
, nRow
) );
422 long nDiagFocusOffsX
= frame::GetTLDiagOffset( -mnFocusOffs
, mnFocusOffs
, maArray
.GetHorDiagAngle( nCol
, nRow
) );
423 long nDiagFocusOffsY
= frame::GetTLDiagOffset( -mnFocusOffs
, mnFocusOffs
, maArray
.GetVerDiagAngle( nCol
, nRow
) );
425 std::vector
< Point
> aFocusVec
;
426 aFocusVec
.push_back( Point( aRect
.Left() - mnFocusOffs
, aRect
.Top() + nDiagFocusOffsY
) );
427 aFocusVec
.push_back( Point( aRect
.Left() - mnFocusOffs
, aRect
.Top() - mnFocusOffs
) );
428 aFocusVec
.push_back( Point( aRect
.Left() + nDiagFocusOffsX
, aRect
.Top() - mnFocusOffs
) );
429 aFocusVec
.push_back( Point( aRect
.Right() + mnFocusOffs
, aRect
.Bottom() - nDiagFocusOffsY
) );
430 aFocusVec
.push_back( Point( aRect
.Right() + mnFocusOffs
, aRect
.Bottom() + mnFocusOffs
) );
431 aFocusVec
.push_back( Point( aRect
.Right() - nDiagFocusOffsX
, aRect
.Bottom() + mnFocusOffs
) );
432 maTLBR
.AddFocusPolygon( Polygon( static_cast< USHORT
>( aFocusVec
.size() ), &aFocusVec
[ 0 ] ) );
435 aFocusVec
.push_back( Point( aRect
.Right() + mnFocusOffs
, aRect
.Top() + nDiagFocusOffsY
) );
436 aFocusVec
.push_back( Point( aRect
.Right() + mnFocusOffs
, aRect
.Top() - mnFocusOffs
) );
437 aFocusVec
.push_back( Point( aRect
.Right() - nDiagFocusOffsX
, aRect
.Top() - mnFocusOffs
) );
438 aFocusVec
.push_back( Point( aRect
.Left() - mnFocusOffs
, aRect
.Bottom() - nDiagFocusOffsY
) );
439 aFocusVec
.push_back( Point( aRect
.Left() - mnFocusOffs
, aRect
.Bottom() + mnFocusOffs
) );
440 aFocusVec
.push_back( Point( aRect
.Left() + nDiagFocusOffsX
, aRect
.Bottom() + mnFocusOffs
) );
441 maBLTR
.AddFocusPolygon( Polygon( static_cast< USHORT
>( aFocusVec
.size() ), &aFocusVec
[ 0 ] ) );
445 // Click areas ------------------------------------------------------------
447 for( FrameBorderIter
aIt( maAllBorders
); aIt
.Is(); ++aIt
)
448 (*aIt
)->ClearClickArea();
450 /* Additional space for click area: is added to the space available to draw
451 the frame borders. For instance left frame border:
452 - To left, top, and bottom always big additional space (outer area).
453 - To right: Dependent on existence of inner vertical frame border
454 (if enabled, use less space).
456 long nClO
= FRAMESEL_GEOM_WIDTH
/ 2 + FRAMESEL_GEOM_ADD_CLICK_OUTER
;
457 long nClI
= (mbTLBR
&& mbBLTR
) ? (FRAMESEL_GEOM_WIDTH
/ 2 + FRAMESEL_GEOM_ADD_CLICK_INNER
) : nClO
;
458 long nClH
= mbHor
? nClI
: nClO
; // additional space dependent of horizontal inner border
459 long nClV
= mbVer
? nClI
: nClO
; // additional space dependent of vertical inner border
461 maLeft
.AddClickRect( Rectangle( mnLine1
- nClO
, mnLine1
- nClO
, mnLine1
+ nClV
, mnLine3
+ nClO
) );
462 maVer
.AddClickRect( Rectangle( mnLine2
- nClI
, mnLine1
- nClO
, mnLine2
+ nClI
, mnLine3
+ nClO
) );
463 maRight
.AddClickRect( Rectangle( mnLine3
- nClV
, mnLine1
- nClO
, mnLine3
+ nClO
, mnLine3
+ nClO
) );
464 maTop
.AddClickRect( Rectangle( mnLine1
- nClO
, mnLine1
- nClO
, mnLine3
+ nClO
, mnLine1
+ nClH
) );
465 maHor
.AddClickRect( Rectangle( mnLine1
- nClO
, mnLine2
- nClI
, mnLine3
+ nClO
, mnLine2
+ nClI
) );
466 maBottom
.AddClickRect( Rectangle( mnLine1
- nClO
, mnLine3
- nClH
, mnLine3
+ nClO
, mnLine3
+ nClO
) );
468 /* Diagonal frame borders use the remaining space between outer and inner frame borders. */
469 if( mbTLBR
|| mbBLTR
)
471 for( nCol
= 0, nCols
= maArray
.GetColCount(); nCol
< nCols
; ++nCol
)
473 for( nRow
= 0, nRows
= maArray
.GetRowCount(); nRow
< nRows
; ++nRow
)
475 // the usable area between horizonal/vertical frame borders of current quadrant
476 Rectangle
aRect( maArray
.GetCellRect( nCol
, nRow
) );
477 aRect
.Left() += nClV
+ 1;
478 aRect
.Right() -= nClV
+ 1;
479 aRect
.Top() += nClH
+ 1;
480 aRect
.Bottom() -= nClH
+ 1;
482 /* Both diagonal frame borders enabled. */
483 if( mbTLBR
&& mbBLTR
)
486 Point
aMid( aRect
.Center() );
487 maTLBR
.AddClickRect( Rectangle( aRect
.TopLeft(), aMid
) );
488 maTLBR
.AddClickRect( Rectangle( aMid
+ Point( 1, 1 ), aRect
.BottomRight() ) );
489 maBLTR
.AddClickRect( Rectangle( aRect
.Left(), aMid
.Y() + 1, aMid
.X(), aRect
.Bottom() ) );
490 maBLTR
.AddClickRect( Rectangle( aMid
.X() + 1, aRect
.Top(), aRect
.Right(), aMid
.Y() ) );
491 // centered rectangle for both frame borders
492 Rectangle
aMidRect( aRect
.TopLeft(), Size( aRect
.GetWidth() / 3, aRect
.GetHeight() / 3 ) );
493 aMidRect
.Move( (aRect
.GetWidth() - aMidRect
.GetWidth()) / 2, (aRect
.GetHeight() - aMidRect
.GetHeight()) / 2 );
494 maTLBR
.AddClickRect( aMidRect
);
495 maBLTR
.AddClickRect( aMidRect
);
497 /* One of the diagonal frame borders enabled - use entire rectangle. */
498 else if( mbTLBR
&& !mbBLTR
) // top-left to bottom-right only
499 maTLBR
.AddClickRect( aRect
);
500 else if( !mbTLBR
&& mbBLTR
) // bottom-left to top-right only
501 maBLTR
.AddClickRect( aRect
);
507 void FrameSelectorImpl::InitVirtualDevice()
509 // initialize resources
511 InitArrowImageList();
513 // initialize geometry
514 InitGlobalGeometry();
515 InitBorderGeometry();
517 // correct background around the used area
518 mrFrameSel
.SetBackground( Wallpaper( maBackCol
) );
519 DoInvalidate( true );
522 // frame border access --------------------------------------------------------
524 const FrameBorder
& FrameSelectorImpl::GetBorder( FrameBorderType eBorder
) const
526 size_t nIndex
= GetIndexFromFrameBorderType( eBorder
);
527 if( nIndex
< maAllBorders
.size() )
528 return *maAllBorders
[ nIndex
];
529 DBG_ERRORFILE( "svx::FrameSelectorImpl::GetBorder - unknown border type" );
533 FrameBorder
& FrameSelectorImpl::GetBorderAccess( FrameBorderType eBorder
)
535 return const_cast< FrameBorder
& >( GetBorder( eBorder
) );
538 // drawing --------------------------------------------------------------------
540 void FrameSelectorImpl::DrawBackground()
543 maVirDev
.SetLineColor();
544 maVirDev
.SetFillColor( maBackCol
);
545 maVirDev
.DrawRect( Rectangle( Point( 0, 0 ), maVirDev
.GetOutputSizePixel() ) );
547 // draw the inner gray (or whatever color) rectangle
548 maVirDev
.SetLineColor();
549 maVirDev
.SetFillColor( maMarkCol
);
550 maVirDev
.DrawRect( Rectangle(
551 mnLine1
- mnFocusOffs
, mnLine1
- mnFocusOffs
, mnLine3
+ mnFocusOffs
, mnLine3
+ mnFocusOffs
) );
553 // draw the white space for enabled frame borders
555 for( FrameBorderCIter
aIt( maEnabBorders
); aIt
.Is(); ++aIt
)
556 (*aIt
)->MergeFocusToPolyPolygon( aPPoly
);
557 aPPoly
.Optimize( POLY_OPTIMIZE_CLOSE
);
558 maVirDev
.SetLineColor( maBackCol
);
559 maVirDev
.SetFillColor( maBackCol
);
560 maVirDev
.DrawPolyPolygon( aPPoly
);
563 void FrameSelectorImpl::DrawArrows( const FrameBorder
& rBorder
)
565 DBG_ASSERT( rBorder
.IsEnabled(), "svx::FrameSelectorImpl::DrawArrows - access to disabled border" );
568 switch( rBorder
.GetType() )
570 case FRAMEBORDER_LEFT
:
571 case FRAMEBORDER_TOP
: nLinePos
= mnLine1
; break;
572 case FRAMEBORDER_VER
:
573 case FRAMEBORDER_HOR
: nLinePos
= mnLine2
; break;
574 case FRAMEBORDER_RIGHT
:
575 case FRAMEBORDER_BOTTOM
: nLinePos
= mnLine3
; break;
576 default: ; //prevent warning
578 nLinePos
-= mnArrowSize
/ 2;
581 long nBRPos
= mnCtrlSize
- mnArrowSize
;
583 USHORT nImgId1
= 0, nImgId2
= 0;
584 switch( rBorder
.GetType() )
586 case FRAMEBORDER_LEFT
:
587 case FRAMEBORDER_RIGHT
:
588 case FRAMEBORDER_VER
:
589 aPos1
= Point( nLinePos
, nTLPos
); nImgId1
= 1;
590 aPos2
= Point( nLinePos
, nBRPos
); nImgId2
= 2;
593 case FRAMEBORDER_TOP
:
594 case FRAMEBORDER_BOTTOM
:
595 case FRAMEBORDER_HOR
:
596 aPos1
= Point( nTLPos
, nLinePos
); nImgId1
= 3;
597 aPos2
= Point( nBRPos
, nLinePos
); nImgId2
= 4;
600 case FRAMEBORDER_TLBR
:
601 aPos1
= Point( nTLPos
, nTLPos
); nImgId1
= 5;
602 aPos2
= Point( nBRPos
, nBRPos
); nImgId2
= 6;
604 case FRAMEBORDER_BLTR
:
605 aPos1
= Point( nTLPos
, nBRPos
); nImgId1
= 7;
606 aPos2
= Point( nBRPos
, nTLPos
); nImgId2
= 8;
608 default: ; //prevent warning
611 // Arrow or marker? Do not draw arrows into disabled control.
612 USHORT nSelectAdd
= (mrFrameSel
.IsEnabled() && rBorder
.IsSelected()) ? 0 : 8;
613 maVirDev
.DrawImage( aPos1
, maILArrows
.GetImage( nImgId1
+ nSelectAdd
) );
614 maVirDev
.DrawImage( aPos2
, maILArrows
.GetImage( nImgId2
+ nSelectAdd
) );
617 void FrameSelectorImpl::DrawAllArrows()
619 for( FrameBorderCIter
aIt( maEnabBorders
); aIt
.Is(); ++aIt
)
623 Color
FrameSelectorImpl::GetDrawLineColor( const Color
& rColor
) const
625 Color
aColor( mbHCMode
? maHCLineCol
: rColor
);
626 if( aColor
== maBackCol
)
631 void FrameSelectorImpl::DrawAllFrameBorders()
633 // Translate core colors to current UI colors (regards current background and HC mode).
634 for( FrameBorderIter
aIt( maEnabBorders
); aIt
.Is(); ++aIt
)
636 Color aCoreColor
= ((*aIt
)->GetState() == FRAMESTATE_DONTCARE
) ? maMarkCol
: (*aIt
)->GetCoreStyle().GetColor();
637 (*aIt
)->SetUIColor( GetDrawLineColor( aCoreColor
) );
640 // Copy all frame border styles to the helper array
641 maArray
.SetColumnStyleLeft( 0, maLeft
.GetUIStyle() );
642 if( mbVer
) maArray
.SetColumnStyleLeft( 1, maVer
.GetUIStyle() );
643 maArray
.SetColumnStyleRight( mbVer
? 1 : 0, maRight
.GetUIStyle() );
645 maArray
.SetRowStyleTop( 0, maTop
.GetUIStyle() );
646 if( mbHor
) maArray
.SetRowStyleTop( 1, maHor
.GetUIStyle() );
647 maArray
.SetRowStyleBottom( mbHor
? 1 : 0, maBottom
.GetUIStyle() );
649 for( size_t nCol
= 0; nCol
< maArray
.GetColCount(); ++nCol
)
650 for( size_t nRow
= 0; nRow
< maArray
.GetRowCount(); ++nRow
)
651 maArray
.SetCellStyleDiag( nCol
, nRow
, maTLBR
.GetUIStyle(), maBLTR
.GetUIStyle() );
653 // Let the helper array draw itself
654 maArray
.DrawArray( maVirDev
);
657 void FrameSelectorImpl::DrawVirtualDevice()
661 DrawAllFrameBorders();
662 mbFullRepaint
= false;
665 void FrameSelectorImpl::CopyVirDevToControl()
669 mrFrameSel
.DrawBitmap( maVirDevPos
, maVirDev
.GetBitmap( Point( 0, 0 ), maVirDev
.GetOutputSizePixel() ) );
672 void FrameSelectorImpl::DrawAllTrackingRects()
675 if( mrFrameSel
.IsAnyBorderSelected() )
677 for( SelFrameBorderCIter
aIt( maEnabBorders
); aIt
.Is(); ++aIt
)
678 (*aIt
)->MergeFocusToPolyPolygon( aPPoly
);
679 aPPoly
.Move( maVirDevPos
.X(), maVirDevPos
.Y() );
682 // no frame border selected -> draw tracking rectangle around entire control
683 aPPoly
.Insert( Polygon( Rectangle( maVirDevPos
, maVirDev
.GetOutputSizePixel() ) ) );
685 aPPoly
.Optimize( POLY_OPTIMIZE_CLOSE
);
686 for( USHORT nIdx
= 0, nCount
= aPPoly
.Count(); nIdx
< nCount
; ++nIdx
)
687 mrFrameSel
.InvertTracking( aPPoly
.GetObject( nIdx
), SHOWTRACK_SMALL
| SHOWTRACK_WINDOW
);
690 Point
FrameSelectorImpl::GetDevPosFromMousePos( const Point
& rMousePos
) const
692 return rMousePos
- maVirDevPos
;
695 void FrameSelectorImpl::DoInvalidate( bool bFullRepaint
)
697 mbFullRepaint
|= bFullRepaint
;
698 mrFrameSel
.Invalidate( INVALIDATE_NOERASE
);
701 // frame border state and style -----------------------------------------------
703 void FrameSelectorImpl::SetBorderState( FrameBorder
& rBorder
, FrameBorderState eState
)
705 DBG_ASSERT( rBorder
.IsEnabled(), "svx::FrameSelectorImpl::SetBorderState - access to disabled border" );
706 if( eState
== FRAMESTATE_SHOW
)
707 SetBorderCoreStyle( rBorder
, &maCurrStyle
);
709 rBorder
.SetState( eState
);
710 DoInvalidate( true );
713 void FrameSelectorImpl::SetBorderCoreStyle( FrameBorder
& rBorder
, const SvxBorderLine
* pStyle
)
715 DBG_ASSERT( rBorder
.IsEnabled(), "svx::FrameSelectorImpl::SetBorderCoreStyle - access to disabled border" );
716 rBorder
.SetCoreStyle( pStyle
);
717 DoInvalidate( true );
720 void FrameSelectorImpl::ToggleBorderState( FrameBorder
& rBorder
)
722 bool bDontCare
= mrFrameSel
.SupportsDontCareState();
723 switch( rBorder
.GetState() )
725 // same order as tristate check box: visible -> don't care -> hidden
726 case FRAMESTATE_SHOW
:
727 SetBorderState( rBorder
, bDontCare
? FRAMESTATE_DONTCARE
: FRAMESTATE_HIDE
);
729 case FRAMESTATE_HIDE
:
730 SetBorderState( rBorder
, FRAMESTATE_SHOW
);
732 case FRAMESTATE_DONTCARE
:
733 SetBorderState( rBorder
, FRAMESTATE_HIDE
);
738 // frame border selection -----------------------------------------------------
740 void FrameSelectorImpl::SelectBorder( FrameBorder
& rBorder
, bool bSelect
)
742 DBG_ASSERT( rBorder
.IsEnabled(), "svx::FrameSelectorImpl::SelectBorder - access to disabled border" );
743 rBorder
.Select( bSelect
);
744 DrawArrows( rBorder
);
745 DoInvalidate( false );
746 maSelectHdl
.Call( this );
749 void FrameSelectorImpl::SilentGrabFocus()
751 bool bOldAuto
= mbAutoSelect
;
752 mbAutoSelect
= false;
753 mrFrameSel
.GrabFocus();
754 mbAutoSelect
= bOldAuto
;
757 bool FrameSelectorImpl::SelectedBordersEqual() const
760 SelFrameBorderCIter
aIt( maEnabBorders
);
763 const SvxBorderLine
& rFirstStyle
= (*aIt
)->GetCoreStyle();
764 for( ++aIt
; bEqual
&& aIt
.Is(); ++aIt
)
765 bEqual
= ((*aIt
)->GetCoreStyle() == rFirstStyle
);
770 // ============================================================================
772 // ============================================================================
774 FrameSelector::FrameSelector( Window
* pParent
, const ResId
& rResId
) :
775 Control( pParent
, rResId
)
777 // not in c'tor init list (avoid warning about usage of *this)
778 mxImpl
.reset( new FrameSelectorImpl( *this ) );
779 EnableRTL( false ); // #107808# don't mirror the mouse handling
782 FrameSelector::~FrameSelector()
786 void FrameSelector::Initialize( FrameSelFlags nFlags
)
788 mxImpl
->Initialize( nFlags
);
792 // enabled frame borders ------------------------------------------------------
794 bool FrameSelector::IsBorderEnabled( FrameBorderType eBorder
) const
796 return mxImpl
->GetBorder( eBorder
).IsEnabled();
799 sal_Int32
FrameSelector::GetEnabledBorderCount() const
801 return static_cast< sal_Int32
>( mxImpl
->maEnabBorders
.size() );
804 FrameBorderType
FrameSelector::GetEnabledBorderType( sal_Int32 nIndex
) const
806 FrameBorderType eBorder
= FRAMEBORDER_NONE
;
809 size_t nVecIdx
= static_cast< size_t >( nIndex
);
810 if( nVecIdx
< mxImpl
->maEnabBorders
.size() )
811 eBorder
= mxImpl
->maEnabBorders
[ nVecIdx
]->GetType();
816 sal_Int32
FrameSelector::GetEnabledBorderIndex( FrameBorderType eBorder
) const
818 sal_Int32 nIndex
= 0;
819 for( FrameBorderCIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
, ++nIndex
)
820 if( (*aIt
)->GetType() == eBorder
)
825 // frame border state and style -----------------------------------------------
827 bool FrameSelector::SupportsDontCareState() const
829 return (mxImpl
->mnFlags
& FRAMESEL_DONTCARE
) != 0;
832 FrameBorderState
FrameSelector::GetFrameBorderState( FrameBorderType eBorder
) const
834 return mxImpl
->GetBorder( eBorder
).GetState();
837 const SvxBorderLine
* FrameSelector::GetFrameBorderStyle( FrameBorderType eBorder
) const
839 const SvxBorderLine
& rStyle
= mxImpl
->GetBorder( eBorder
).GetCoreStyle();
840 // rest of the world uses null pointer for invisible frame border
841 return rStyle
.GetOutWidth() ? &rStyle
: 0;
844 void FrameSelector::ShowBorder( FrameBorderType eBorder
, const SvxBorderLine
* pStyle
)
846 mxImpl
->SetBorderCoreStyle( mxImpl
->GetBorderAccess( eBorder
), pStyle
);
849 void FrameSelector::SetBorderDontCare( FrameBorderType eBorder
)
851 mxImpl
->SetBorderState( mxImpl
->GetBorderAccess( eBorder
), FRAMESTATE_DONTCARE
);
854 bool FrameSelector::IsAnyBorderVisible() const
857 for( FrameBorderCIter
aIt( mxImpl
->maEnabBorders
); !bIsSet
&& aIt
.Is(); ++aIt
)
858 bIsSet
= ((*aIt
)->GetState() == FRAMESTATE_SHOW
);
862 void FrameSelector::HideAllBorders()
864 for( FrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
865 mxImpl
->SetBorderState( **aIt
, FRAMESTATE_HIDE
);
868 bool FrameSelector::GetVisibleWidth( USHORT
& rnPrim
, USHORT
& rnDist
, USHORT
& rnSecn
) const
870 VisFrameBorderCIter
aIt( mxImpl
->maEnabBorders
);
874 const SvxBorderLine
& rStyle
= (*aIt
)->GetCoreStyle();
876 for( ++aIt
; bFound
&& aIt
.Is(); ++aIt
)
878 (rStyle
.GetOutWidth() == (*aIt
)->GetCoreStyle().GetOutWidth()) &&
879 (rStyle
.GetDistance() == (*aIt
)->GetCoreStyle().GetDistance()) &&
880 (rStyle
.GetInWidth() == (*aIt
)->GetCoreStyle().GetInWidth());
884 rnPrim
= rStyle
.GetOutWidth();
885 rnDist
= rStyle
.GetDistance();
886 rnSecn
= rStyle
.GetInWidth();
891 bool FrameSelector::GetVisibleColor( Color
& rColor
) const
893 VisFrameBorderCIter
aIt( mxImpl
->maEnabBorders
);
897 const SvxBorderLine
& rStyle
= (*aIt
)->GetCoreStyle();
899 for( ++aIt
; bFound
&& aIt
.Is(); ++aIt
)
900 bFound
= (rStyle
.GetColor() == (*aIt
)->GetCoreStyle().GetColor());
903 rColor
= rStyle
.GetColor();
907 // frame border selection -----------------------------------------------------
909 const Link
& FrameSelector::GetSelectHdl() const
911 return mxImpl
->maSelectHdl
;
914 void FrameSelector::SetSelectHdl( const Link
& rHdl
)
916 mxImpl
->maSelectHdl
= rHdl
;
919 bool FrameSelector::IsBorderSelected( FrameBorderType eBorder
) const
921 return mxImpl
->GetBorder( eBorder
).IsSelected();
924 void FrameSelector::SelectBorder( FrameBorderType eBorder
, bool bSelect
)
926 mxImpl
->SelectBorder( mxImpl
->GetBorderAccess( eBorder
), bSelect
);
929 bool FrameSelector::IsAnyBorderSelected() const
931 // Construct an iterator for selected borders. If it is valid, there is a selected border.
932 return SelFrameBorderCIter( mxImpl
->maEnabBorders
).Is();
935 void FrameSelector::SelectAllBorders( bool bSelect
)
937 for( FrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
938 mxImpl
->SelectBorder( **aIt
, bSelect
);
941 void FrameSelector::SelectAllVisibleBorders( bool bSelect
)
943 for( VisFrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
944 mxImpl
->SelectBorder( **aIt
, bSelect
);
947 void FrameSelector::SetStyleToSelection( USHORT nPrim
, USHORT nDist
, USHORT nSecn
)
949 mxImpl
->maCurrStyle
.SetOutWidth( nPrim
);
950 mxImpl
->maCurrStyle
.SetDistance( nDist
);
951 mxImpl
->maCurrStyle
.SetInWidth( nSecn
);
952 for( SelFrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
953 mxImpl
->SetBorderState( **aIt
, FRAMESTATE_SHOW
);
956 void FrameSelector::SetColorToSelection( const Color
& rColor
)
958 mxImpl
->maCurrStyle
.SetColor( rColor
);
959 for( SelFrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
960 mxImpl
->SetBorderState( **aIt
, FRAMESTATE_SHOW
);
963 // accessibility --------------------------------------------------------------
965 Reference
< XAccessible
> FrameSelector::CreateAccessible()
967 if( !mxImpl
->mxAccess
.is() )
968 mxImpl
->mxAccess
= mxImpl
->mpAccess
=
969 new a11y::AccFrameSelector( *this, FRAMEBORDER_NONE
);
970 return mxImpl
->mxAccess
;
973 Reference
< XAccessible
> FrameSelector::GetChildAccessible( FrameBorderType eBorder
)
975 Reference
< XAccessible
> xRet
;
976 size_t nVecIdx
= static_cast< size_t >( eBorder
);
977 if( IsBorderEnabled( eBorder
) && (1 <= nVecIdx
) && (nVecIdx
<= mxImpl
->maChildVec
.size()) )
980 if( !mxImpl
->maChildVec
[ nVecIdx
] )
981 mxImpl
->mxChildVec
[ nVecIdx
] = mxImpl
->maChildVec
[ nVecIdx
] =
982 new a11y::AccFrameSelector( *this, eBorder
);
983 xRet
= mxImpl
->mxChildVec
[ nVecIdx
];
988 Reference
< XAccessible
> FrameSelector::GetChildAccessible( sal_Int32 nIndex
)
990 return GetChildAccessible( GetEnabledBorderType( nIndex
) );
993 Reference
< XAccessible
> FrameSelector::GetChildAccessible( const Point
& rPos
)
995 Reference
< XAccessible
> xRet
;
996 for( FrameBorderCIter
aIt( mxImpl
->maEnabBorders
); !xRet
.is() && aIt
.Is(); ++aIt
)
997 if( (*aIt
)->ContainsClickPoint( rPos
) )
998 xRet
= GetChildAccessible( (*aIt
)->GetType() );
1002 bool FrameSelector::ContainsClickPoint( const Point
& rPos
) const
1004 bool bContains
= false;
1005 for( FrameBorderCIter
aIt( mxImpl
->maEnabBorders
); !bContains
&& aIt
.Is(); ++aIt
)
1006 bContains
= (*aIt
)->ContainsClickPoint( rPos
);
1010 Rectangle
FrameSelector::GetClickBoundRect( FrameBorderType eBorder
) const
1013 const FrameBorder
& rBorder
= mxImpl
->GetBorder( eBorder
);
1014 if( rBorder
.IsEnabled() )
1015 aRect
= rBorder
.GetClickBoundRect();
1019 // virtual functions from base class ------------------------------------------
1021 void FrameSelector::Paint( const Rectangle
& )
1023 mxImpl
->CopyVirDevToControl();
1025 mxImpl
->DrawAllTrackingRects();
1028 void FrameSelector::MouseButtonDown( const MouseEvent
& rMEvt
)
1031 * Click on an unselected frame border:
1032 Set current style/color, make frame border visible, deselect all
1033 other frame borders.
1034 * Click on a selected frame border:
1035 Toggle state of the frame border (visible -> don't care -> hidden),
1036 deselect all other frame borders.
1037 * SHIFT+Click or CTRL+Click on an unselected frame border:
1038 Extend selection, set current style/color to all selected frame
1039 borders independent of the state/style/color of the borders.
1040 * SHIFT+Click or CTRL+Click on a selected frame border:
1041 If all frame borders have same style/color, toggle state of all
1042 borders (see above), otherwise set current style/color to all
1044 * Click on unused area: Do not modify selection and selected frame
1048 // #107394# do not auto-select a frame border
1049 mxImpl
->SilentGrabFocus();
1051 if( rMEvt
.IsLeft() )
1053 Point
aPos( mxImpl
->GetDevPosFromMousePos( rMEvt
.GetPosPixel() ) );
1054 FrameBorderPtrVec aDeselectBorders
;
1056 bool bAnyClicked
= false; // Any frame border clicked?
1057 bool bNewSelected
= false; // Any unselected frame border selected?
1059 /* If frame borders are set to "don't care" and the control does not
1060 support this state, hide them on first mouse click.
1061 DR 2004-01-30: Why are the borders set to "don't care" then?!? */
1062 bool bHideDontCare
= !mxImpl
->mbClicked
&& !SupportsDontCareState();
1064 for( FrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
1066 if( (*aIt
)->ContainsClickPoint( aPos
) )
1068 // frame border is clicked
1070 if( !(*aIt
)->IsSelected() )
1072 bNewSelected
= true;
1073 mxImpl
->SelectBorder( **aIt
, true );
1078 // hide a "don't care" frame border only if it is not clicked
1079 if( bHideDontCare
&& ((*aIt
)->GetState() == FRAMESTATE_DONTCARE
) )
1080 mxImpl
->SetBorderState( **aIt
, FRAMESTATE_HIDE
);
1082 // deselect frame borders not clicked (if SHIFT or CTRL are not pressed)
1083 if( !rMEvt
.IsShift() && !rMEvt
.IsMod1() )
1084 aDeselectBorders
.push_back( *aIt
);
1090 // any valid frame border clicked? -> deselect other frame borders
1091 for( FrameBorderIter
aIt( aDeselectBorders
); aIt
.Is(); ++aIt
)
1092 mxImpl
->SelectBorder( **aIt
, false );
1094 if( bNewSelected
|| !mxImpl
->SelectedBordersEqual() )
1096 // new frame border selected, selection extended, or selected borders different? -> show
1097 for( SelFrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
1098 // SetBorderState() sets current style and color to the frame border
1099 mxImpl
->SetBorderState( **aIt
, FRAMESTATE_SHOW
);
1103 // all selected frame borders are equal -> toggle state
1104 for( SelFrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
1105 mxImpl
->ToggleBorderState( **aIt
);
1111 void FrameSelector::KeyInput( const KeyEvent
& rKEvt
)
1113 bool bHandled
= false;
1114 KeyCode aKeyCode
= rKEvt
.GetKeyCode();
1115 if( !aKeyCode
.GetModifier() )
1117 USHORT nCode
= aKeyCode
.GetCode();
1122 for( SelFrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
1123 mxImpl
->ToggleBorderState( **aIt
);
1133 if( !mxImpl
->maEnabBorders
.empty() )
1135 // start from first selected frame border
1136 SelFrameBorderCIter
aIt( mxImpl
->maEnabBorders
);
1137 FrameBorderType eBorder
= aIt
.Is() ? (*aIt
)->GetType() : mxImpl
->maEnabBorders
.front()->GetType();
1139 // search for next enabled frame border
1142 eBorder
= mxImpl
->GetBorder( eBorder
).GetKeyboardNeighbor( nCode
);
1144 while( (eBorder
!= FRAMEBORDER_NONE
) && !IsBorderEnabled( eBorder
) );
1146 // select the frame border
1147 if( eBorder
!= FRAMEBORDER_NONE
)
1149 DeselectAllBorders();
1150 SelectBorder( eBorder
);
1158 Window::KeyInput(rKEvt
);
1161 void FrameSelector::GetFocus()
1163 // auto-selection of a frame border, if focus reaches control, and nothing is selected
1164 if( mxImpl
->mbAutoSelect
&& !IsAnyBorderSelected() && !mxImpl
->maEnabBorders
.empty() )
1165 mxImpl
->SelectBorder( *mxImpl
->maEnabBorders
.front(), true );
1167 mxImpl
->DoInvalidate( false );
1168 if( mxImpl
->mxAccess
.is() )
1169 mxImpl
->mpAccess
->NotifyFocusListeners( sal_True
);
1170 Control::GetFocus();
1173 void FrameSelector::LoseFocus()
1175 mxImpl
->DoInvalidate( false );
1176 if( mxImpl
->mxAccess
.is() )
1177 mxImpl
->mpAccess
->NotifyFocusListeners( sal_False
);
1178 Control::LoseFocus();
1181 void FrameSelector::DataChanged( const DataChangedEvent
& rDCEvt
)
1183 Control::DataChanged( rDCEvt
);
1184 if( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) && (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
1185 mxImpl
->InitVirtualDevice();
1188 // ============================================================================
1190 template< typename Cont
, typename Iter
, typename Pred
>
1191 FrameBorderIterBase
< Cont
, Iter
, Pred
>::FrameBorderIterBase( container_type
& rCont
) :
1192 maIt( rCont
.begin() ),
1193 maEnd( rCont
.end() )
1195 while( Is() && !maPred( *maIt
) ) ++maIt
;
1198 template< typename Cont
, typename Iter
, typename Pred
>
1199 FrameBorderIterBase
< Cont
, Iter
, Pred
>& FrameBorderIterBase
< Cont
, Iter
, Pred
>::operator++()
1201 do { ++maIt
; } while( Is() && !maPred( *maIt
) );
1205 // ============================================================================