1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/frmsel.hxx>
21 #include <vcl/builder.hxx>
25 #include "frmselimpl.hxx"
26 #include "AccessibleFrameSelector.hxx"
27 #include <svx/dialmgr.hxx>
29 #include <svx/dialogs.hrc>
32 #include <tools/rcid.h>
34 using namespace ::com::sun::star
;
35 using namespace ::editeng
;
39 using ::com::sun::star::uno::Reference
;
40 using ::com::sun::star::accessibility::XAccessible
;
42 // ============================================================================
43 // global functions from framebordertype.hxx
45 FrameBorderType
GetFrameBorderTypeFromIndex( size_t nIndex
)
47 DBG_ASSERT( nIndex
< (size_t)FRAMEBORDERTYPE_COUNT
,
48 "svx::GetFrameBorderTypeFromIndex - invalid index" );
49 return static_cast< FrameBorderType
>( nIndex
+ 1 );
52 size_t GetIndexFromFrameBorderType( FrameBorderType eBorder
)
54 DBG_ASSERT( eBorder
!= FRAMEBORDER_NONE
,
55 "svx::GetIndexFromFrameBorderType - invalid frame border type" );
56 return static_cast< size_t >( eBorder
) - 1;
59 // ============================================================================
63 /** Space between outer control border and any graphical element of the control. */
64 const long FRAMESEL_GEOM_OUTER
= 2;
66 /** Space between arrows and usable inner area. */
67 const long FRAMESEL_GEOM_INNER
= 3;
69 /** Maximum width to draw a frame border style. */
70 const long FRAMESEL_GEOM_WIDTH
= 9;
72 /** Additional margin for click area of outer lines. */
73 const long FRAMESEL_GEOM_ADD_CLICK_OUTER
= 5;
75 /** Additional margin for click area of inner lines. */
76 const long FRAMESEL_GEOM_ADD_CLICK_INNER
= 2;
78 // ----------------------------------------------------------------------------
80 /** Returns the corresponding flag for a frame border. */
81 FrameSelFlags
lclGetFlagFromType( FrameBorderType eBorder
)
85 case FRAMEBORDER_LEFT
: return FRAMESEL_LEFT
;
86 case FRAMEBORDER_RIGHT
: return FRAMESEL_RIGHT
;
87 case FRAMEBORDER_TOP
: return FRAMESEL_TOP
;
88 case FRAMEBORDER_BOTTOM
: return FRAMESEL_BOTTOM
;
89 case FRAMEBORDER_HOR
: return FRAMESEL_INNER_HOR
;
90 case FRAMEBORDER_VER
: return FRAMESEL_INNER_VER
;
91 case FRAMEBORDER_TLBR
: return FRAMESEL_DIAG_TLBR
;
92 case FRAMEBORDER_BLTR
: return FRAMESEL_DIAG_BLTR
;
93 case FRAMEBORDER_NONE
: break;
98 /** Merges the rSource polypolygon into the rDest polypolygon. */
99 inline void lclPolyPolyUnion( PolyPolygon
& rDest
, const PolyPolygon
& rSource
)
101 const PolyPolygon
aTmp( rDest
);
102 aTmp
.GetUnion( rSource
, rDest
);
107 // ============================================================================
109 // ============================================================================
111 FrameBorder::FrameBorder( FrameBorderType eType
) :
113 meState( FRAMESTATE_HIDE
),
114 meKeyLeft( FRAMEBORDER_NONE
),
115 meKeyRight( FRAMEBORDER_NONE
),
116 meKeyTop( FRAMEBORDER_NONE
),
117 meKeyBottom( FRAMEBORDER_NONE
),
123 void FrameBorder::Enable( FrameSelFlags nFlags
)
125 mbEnabled
= (nFlags
& lclGetFlagFromType( meType
)) != 0;
127 SetState( FRAMESTATE_HIDE
);
130 void FrameBorder::SetCoreStyle( const SvxBorderLine
* pStyle
)
133 maCoreStyle
= *pStyle
;
135 maCoreStyle
= SvxBorderLine();
137 // from twips to points
138 maUIStyle
.Set( maCoreStyle
, 0.05, FRAMESEL_GEOM_WIDTH
);
139 meState
= maUIStyle
.Prim() ? FRAMESTATE_SHOW
: FRAMESTATE_HIDE
;
142 void FrameBorder::SetState( FrameBorderState eState
)
147 case FRAMESTATE_SHOW
:
148 SAL_WARN( "svx.dialog", "svx::FrameBorder::SetState - use SetCoreStyle to make border visible" );
150 case FRAMESTATE_HIDE
:
151 maCoreStyle
= SvxBorderLine();
154 case FRAMESTATE_DONTCARE
:
155 maCoreStyle
= SvxBorderLine();
156 maUIStyle
= frame::Style(3, 0, 0, table::BorderLineStyle::SOLID
); //OBJ_FRAMESTYLE_DONTCARE
161 void FrameBorder::AddFocusPolygon( const Polygon
& rFocus
)
163 lclPolyPolyUnion( maFocusArea
, rFocus
);
166 void FrameBorder::MergeFocusToPolyPolygon( PolyPolygon
& rPPoly
) const
168 lclPolyPolyUnion( rPPoly
, maFocusArea
);
171 void FrameBorder::AddClickRect( const Rectangle
& rRect
)
173 lclPolyPolyUnion( maClickArea
, Polygon( rRect
) );
176 bool FrameBorder::ContainsClickPoint( const Point
& rPos
) const
178 return Region( maClickArea
).IsInside( rPos
);
181 Rectangle
FrameBorder::GetClickBoundRect() const
183 return maClickArea
.GetBoundRect();
186 void FrameBorder::SetKeyboardNeighbors(
187 FrameBorderType eLeft
, FrameBorderType eRight
, FrameBorderType eTop
, FrameBorderType eBottom
)
192 meKeyBottom
= eBottom
;
195 FrameBorderType
FrameBorder::GetKeyboardNeighbor( sal_uInt16 nKeyCode
) const
197 FrameBorderType eBorder
= FRAMEBORDER_NONE
;
200 case KEY_LEFT
: eBorder
= meKeyLeft
; break;
201 case KEY_RIGHT
: eBorder
= meKeyRight
; break;
202 case KEY_UP
: eBorder
= meKeyTop
; break;
203 case KEY_DOWN
: eBorder
= meKeyBottom
; break;
204 default: SAL_WARN( "svx.dialog", "svx::FrameBorder::GetKeyboardNeighbor - unknown key code" );
209 // ============================================================================
211 // ============================================================================
213 FrameSelectorImpl::FrameSelectorImpl( FrameSelector
& rFrameSel
) :
214 Resource( SVX_RES( RID_SVXSTR_BORDER_CONTROL
) ),
215 mrFrameSel( rFrameSel
),
217 maLeft( FRAMEBORDER_LEFT
),
218 maRight( FRAMEBORDER_RIGHT
),
219 maTop( FRAMEBORDER_TOP
),
220 maBottom( FRAMEBORDER_BOTTOM
),
221 maHor( FRAMEBORDER_HOR
),
222 maVer( FRAMEBORDER_VER
),
223 maTLBR( FRAMEBORDER_TLBR
),
224 maBLTR( FRAMEBORDER_BLTR
),
225 mnFlags( FRAMESEL_OUTER
),
236 mbFullRepaint( true ),
237 mbAutoSelect( true ),
241 maChildVec( 8, static_cast< a11y::AccFrameSelector
* >( 0 ) ),
246 maAllBorders
.resize( FRAMEBORDERTYPE_COUNT
, 0 );
247 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_LEFT
) ] = &maLeft
;
248 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_RIGHT
) ] = &maRight
;
249 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_TOP
) ] = &maTop
;
250 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_BOTTOM
) ] = &maBottom
;
251 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_HOR
) ] = &maHor
;
252 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_VER
) ] = &maVer
;
253 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_TLBR
) ] = &maTLBR
;
254 maAllBorders
[ GetIndexFromFrameBorderType( FRAMEBORDER_BLTR
) ] = &maBLTR
;
255 #if OSL_DEBUG_LEVEL >= 2
258 for( FrameBorderCIter
aIt( maAllBorders
); bOk
&& aIt
.Is(); bOk
= (*aIt
!= 0), ++aIt
);
259 DBG_ASSERT( bOk
, "svx::FrameSelectorImpl::FrameSelectorImpl - missing entry in maAllBorders" );
262 // left neighbor right neighbor upper neighbor lower neighbor
263 maLeft
.SetKeyboardNeighbors( FRAMEBORDER_NONE
, FRAMEBORDER_TLBR
, FRAMEBORDER_TOP
, FRAMEBORDER_BOTTOM
);
264 maRight
.SetKeyboardNeighbors( FRAMEBORDER_BLTR
, FRAMEBORDER_NONE
, FRAMEBORDER_TOP
, FRAMEBORDER_BOTTOM
);
265 maTop
.SetKeyboardNeighbors( FRAMEBORDER_LEFT
, FRAMEBORDER_RIGHT
, FRAMEBORDER_NONE
, FRAMEBORDER_TLBR
);
266 maBottom
.SetKeyboardNeighbors( FRAMEBORDER_LEFT
, FRAMEBORDER_RIGHT
, FRAMEBORDER_BLTR
, FRAMEBORDER_NONE
);
267 maHor
.SetKeyboardNeighbors( FRAMEBORDER_LEFT
, FRAMEBORDER_RIGHT
, FRAMEBORDER_TLBR
, FRAMEBORDER_BLTR
);
268 maVer
.SetKeyboardNeighbors( FRAMEBORDER_TLBR
, FRAMEBORDER_BLTR
, FRAMEBORDER_TOP
, FRAMEBORDER_BOTTOM
);
269 maTLBR
.SetKeyboardNeighbors( FRAMEBORDER_LEFT
, FRAMEBORDER_VER
, FRAMEBORDER_TOP
, FRAMEBORDER_HOR
);
270 maBLTR
.SetKeyboardNeighbors( FRAMEBORDER_VER
, FRAMEBORDER_RIGHT
, FRAMEBORDER_HOR
, FRAMEBORDER_BOTTOM
);
275 FrameSelectorImpl::~FrameSelectorImpl()
278 mpAccess
->Invalidate();
279 for( AccessibleImplVec::iterator aIt
= maChildVec
.begin(), aEnd
= maChildVec
.end(); aIt
!= aEnd
; ++aIt
)
281 (*aIt
)->Invalidate();
284 // initialization -------------------------------------------------------------
286 void FrameSelectorImpl::Initialize( FrameSelFlags nFlags
)
290 maEnabBorders
.clear();
291 for( FrameBorderIter
aIt( maAllBorders
); aIt
.Is(); ++aIt
)
293 (*aIt
)->Enable( mnFlags
);
294 if( (*aIt
)->IsEnabled() )
295 maEnabBorders
.push_back( *aIt
);
297 mbHor
= maHor
.IsEnabled();
298 mbVer
= maVer
.IsEnabled();
299 mbTLBR
= maTLBR
.IsEnabled();
300 mbBLTR
= maBLTR
.IsEnabled();
305 void FrameSelectorImpl::InitColors()
307 const StyleSettings
& rSett
= mrFrameSel
.GetSettings().GetStyleSettings();
308 maBackCol
= rSett
.GetFieldColor();
309 mbHCMode
= rSett
.GetHighContrastMode();
310 maArrowCol
= rSett
.GetFieldTextColor();
311 maMarkCol
.operator=( maBackCol
).Merge( maArrowCol
, mbHCMode
? 0x80 : 0xC0 );
312 maHCLineCol
= rSett
.GetLabelTextColor();
315 void FrameSelectorImpl::InitArrowImageList()
317 /* Build the arrow images bitmap with current colors. */
320 pColorAry1
[0] = Color( 0, 0, 0 );
321 pColorAry2
[0] = maArrowCol
; // black -> arrow color
322 pColorAry1
[1] = Color( 0, 255, 0 );
323 pColorAry2
[1] = maMarkCol
; // green -> marker color
324 pColorAry1
[2] = Color( 255, 0, 255 );
325 pColorAry2
[2] = maBackCol
; // magenta -> background
327 GetRes( SVX_RES( RID_SVXSTR_BORDER_CONTROL
).SetRT( RSC_RESOURCE
) );
328 maILArrows
.InsertFromHorizontalBitmap(
329 SVX_RES( BMP_FRMSEL_ARROWS
), 16, NULL
, pColorAry1
, pColorAry2
, 3);
331 DBG_ASSERT( maILArrows
.GetImageSize().Height() == maILArrows
.GetImageSize().Width(),
332 "svx::FrameSelectorImpl::InitArrowImageList - images are not squarish" );
333 mnArrowSize
= maILArrows
.GetImageSize().Height();
336 void FrameSelectorImpl::InitGlobalGeometry()
338 Size
aCtrlSize( mrFrameSel
.CalcOutputSize( mrFrameSel
.GetSizePixel() ) );
339 /* nMinSize is the lower of width and height (control will always be squarish).
340 FRAMESEL_GEOM_OUTER is the minimal distance between inner control border
342 long nMinSize
= std::min( aCtrlSize
.Width(), aCtrlSize
.Height() ) - 2 * FRAMESEL_GEOM_OUTER
;
343 /* nFixedSize is the size all existing elements need in one direction:
344 the diag. arrow, space betw. arrow and frame border, outer frame border,
345 inner frame border, other outer frame border, space betw. frame border
346 and arrow, the other arrow. */
347 long nFixedSize
= 2 * mnArrowSize
+ 2 * FRAMESEL_GEOM_INNER
+ 3 * FRAMESEL_GEOM_WIDTH
;
348 /* nBetwBordersSize contains the size between an outer and inner frame border (made odd). */
349 long nBetwBordersSize
= (((nMinSize
- nFixedSize
) / 2) - 1) | 1;
351 /* The final size of the usable area. */
352 mnCtrlSize
= 2 * nBetwBordersSize
+ nFixedSize
;
353 maVirDev
.SetOutputSizePixel( Size( mnCtrlSize
, mnCtrlSize
) );
355 /* Center the virtual device in the control. */
356 maVirDevPos
= Point( (aCtrlSize
.Width() - mnCtrlSize
) / 2, (aCtrlSize
.Height() - mnCtrlSize
) / 2 );
359 void FrameSelectorImpl::InitBorderGeometry()
361 size_t nCol
, nCols
, nRow
, nRows
;
363 // Global border geometry values ------------------------------------------
365 /* mnLine* is the middle point inside a frame border (i.e. mnLine1 is mid X inside left border). */
366 mnLine1
= mnArrowSize
+ FRAMESEL_GEOM_INNER
+ FRAMESEL_GEOM_WIDTH
/ 2;
367 mnLine2
= mnCtrlSize
/ 2;
368 mnLine3
= 2 * mnLine2
- mnLine1
;
370 // Frame helper array -----------------------------------------------------
372 maArray
.Initialize( mbVer
? 2 : 1, mbHor
? 2 : 1 );
373 maArray
.SetUseDiagDoubleClipping( true );
375 maArray
.SetXOffset( mnLine1
);
376 maArray
.SetAllColWidths( (mbVer
? mnLine2
: mnLine3
) - mnLine1
);
378 maArray
.SetYOffset( mnLine1
);
379 maArray
.SetAllRowHeights( (mbHor
? mnLine2
: mnLine3
) - mnLine1
);
381 // Focus polygons ---------------------------------------------------------
383 /* Width for focus rectangles from center of frame borders. */
384 mnFocusOffs
= FRAMESEL_GEOM_WIDTH
/ 2 + 1;
386 maLeft
.ClearFocusArea();
387 maVer
.ClearFocusArea();
388 maRight
.ClearFocusArea();
389 maTop
.ClearFocusArea();
390 maHor
.ClearFocusArea();
391 maBottom
.ClearFocusArea();
393 maLeft
.AddFocusPolygon( Rectangle( mnLine1
- mnFocusOffs
, mnLine1
- mnFocusOffs
, mnLine1
+ mnFocusOffs
, mnLine3
+ mnFocusOffs
) );
394 maVer
.AddFocusPolygon( Rectangle( mnLine2
- mnFocusOffs
, mnLine1
- mnFocusOffs
, mnLine2
+ mnFocusOffs
, mnLine3
+ mnFocusOffs
) );
395 maRight
.AddFocusPolygon( Rectangle( mnLine3
- mnFocusOffs
, mnLine1
- mnFocusOffs
, mnLine3
+ mnFocusOffs
, mnLine3
+ mnFocusOffs
) );
396 maTop
.AddFocusPolygon( Rectangle( mnLine1
- mnFocusOffs
, mnLine1
- mnFocusOffs
, mnLine3
+ mnFocusOffs
, mnLine1
+ mnFocusOffs
) );
397 maHor
.AddFocusPolygon( Rectangle( mnLine1
- mnFocusOffs
, mnLine2
- mnFocusOffs
, mnLine3
+ mnFocusOffs
, mnLine2
+ mnFocusOffs
) );
398 maBottom
.AddFocusPolygon( Rectangle( mnLine1
- mnFocusOffs
, mnLine3
- mnFocusOffs
, mnLine3
+ mnFocusOffs
, mnLine3
+ mnFocusOffs
) );
400 for( nCol
= 0, nCols
= maArray
.GetColCount(); nCol
< nCols
; ++nCol
)
402 for( nRow
= 0, nRows
= maArray
.GetRowCount(); nRow
< nRows
; ++nRow
)
404 Rectangle
aRect( maArray
.GetCellRect( nCol
, nRow
) );
405 long nDiagFocusOffsX
= frame::GetTLDiagOffset( -mnFocusOffs
, mnFocusOffs
, maArray
.GetHorDiagAngle( nCol
, nRow
) );
406 long nDiagFocusOffsY
= frame::GetTLDiagOffset( -mnFocusOffs
, mnFocusOffs
, maArray
.GetVerDiagAngle( nCol
, nRow
) );
408 std::vector
< Point
> aFocusVec
;
409 aFocusVec
.push_back( Point( aRect
.Left() - mnFocusOffs
, aRect
.Top() + nDiagFocusOffsY
) );
410 aFocusVec
.push_back( Point( aRect
.Left() - mnFocusOffs
, aRect
.Top() - mnFocusOffs
) );
411 aFocusVec
.push_back( Point( aRect
.Left() + nDiagFocusOffsX
, aRect
.Top() - mnFocusOffs
) );
412 aFocusVec
.push_back( Point( aRect
.Right() + mnFocusOffs
, aRect
.Bottom() - nDiagFocusOffsY
) );
413 aFocusVec
.push_back( Point( aRect
.Right() + mnFocusOffs
, aRect
.Bottom() + mnFocusOffs
) );
414 aFocusVec
.push_back( Point( aRect
.Right() - nDiagFocusOffsX
, aRect
.Bottom() + mnFocusOffs
) );
415 maTLBR
.AddFocusPolygon( Polygon( static_cast< sal_uInt16
>( aFocusVec
.size() ), &aFocusVec
[ 0 ] ) );
418 aFocusVec
.push_back( Point( aRect
.Right() + mnFocusOffs
, aRect
.Top() + nDiagFocusOffsY
) );
419 aFocusVec
.push_back( Point( aRect
.Right() + mnFocusOffs
, aRect
.Top() - mnFocusOffs
) );
420 aFocusVec
.push_back( Point( aRect
.Right() - nDiagFocusOffsX
, aRect
.Top() - mnFocusOffs
) );
421 aFocusVec
.push_back( Point( aRect
.Left() - mnFocusOffs
, aRect
.Bottom() - nDiagFocusOffsY
) );
422 aFocusVec
.push_back( Point( aRect
.Left() - mnFocusOffs
, aRect
.Bottom() + mnFocusOffs
) );
423 aFocusVec
.push_back( Point( aRect
.Left() + nDiagFocusOffsX
, aRect
.Bottom() + mnFocusOffs
) );
424 maBLTR
.AddFocusPolygon( Polygon( static_cast< sal_uInt16
>( aFocusVec
.size() ), &aFocusVec
[ 0 ] ) );
428 // Click areas ------------------------------------------------------------
430 for( FrameBorderIter
aIt( maAllBorders
); aIt
.Is(); ++aIt
)
431 (*aIt
)->ClearClickArea();
433 /* Additional space for click area: is added to the space available to draw
434 the frame borders. For instance left frame border:
435 - To left, top, and bottom always big additional space (outer area).
436 - To right: Dependent on existence of inner vertical frame border
437 (if enabled, use less space).
439 long nClO
= FRAMESEL_GEOM_WIDTH
/ 2 + FRAMESEL_GEOM_ADD_CLICK_OUTER
;
440 long nClI
= (mbTLBR
&& mbBLTR
) ? (FRAMESEL_GEOM_WIDTH
/ 2 + FRAMESEL_GEOM_ADD_CLICK_INNER
) : nClO
;
441 long nClH
= mbHor
? nClI
: nClO
; // additional space dependent of horizontal inner border
442 long nClV
= mbVer
? nClI
: nClO
; // additional space dependent of vertical inner border
444 maLeft
.AddClickRect( Rectangle( mnLine1
- nClO
, mnLine1
- nClO
, mnLine1
+ nClV
, mnLine3
+ nClO
) );
445 maVer
.AddClickRect( Rectangle( mnLine2
- nClI
, mnLine1
- nClO
, mnLine2
+ nClI
, mnLine3
+ nClO
) );
446 maRight
.AddClickRect( Rectangle( mnLine3
- nClV
, mnLine1
- nClO
, mnLine3
+ nClO
, mnLine3
+ nClO
) );
447 maTop
.AddClickRect( Rectangle( mnLine1
- nClO
, mnLine1
- nClO
, mnLine3
+ nClO
, mnLine1
+ nClH
) );
448 maHor
.AddClickRect( Rectangle( mnLine1
- nClO
, mnLine2
- nClI
, mnLine3
+ nClO
, mnLine2
+ nClI
) );
449 maBottom
.AddClickRect( Rectangle( mnLine1
- nClO
, mnLine3
- nClH
, mnLine3
+ nClO
, mnLine3
+ nClO
) );
451 /* Diagonal frame borders use the remaining space between outer and inner frame borders. */
452 if( mbTLBR
|| mbBLTR
)
454 for( nCol
= 0, nCols
= maArray
.GetColCount(); nCol
< nCols
; ++nCol
)
456 for( nRow
= 0, nRows
= maArray
.GetRowCount(); nRow
< nRows
; ++nRow
)
458 // the usable area between horizonal/vertical frame borders of current quadrant
459 Rectangle
aRect( maArray
.GetCellRect( nCol
, nRow
) );
460 aRect
.Left() += nClV
+ 1;
461 aRect
.Right() -= nClV
+ 1;
462 aRect
.Top() += nClH
+ 1;
463 aRect
.Bottom() -= nClH
+ 1;
465 /* Both diagonal frame borders enabled. */
466 if( mbTLBR
&& mbBLTR
)
469 Point
aMid( aRect
.Center() );
470 maTLBR
.AddClickRect( Rectangle( aRect
.TopLeft(), aMid
) );
471 maTLBR
.AddClickRect( Rectangle( aMid
+ Point( 1, 1 ), aRect
.BottomRight() ) );
472 maBLTR
.AddClickRect( Rectangle( aRect
.Left(), aMid
.Y() + 1, aMid
.X(), aRect
.Bottom() ) );
473 maBLTR
.AddClickRect( Rectangle( aMid
.X() + 1, aRect
.Top(), aRect
.Right(), aMid
.Y() ) );
474 // centered rectangle for both frame borders
475 Rectangle
aMidRect( aRect
.TopLeft(), Size( aRect
.GetWidth() / 3, aRect
.GetHeight() / 3 ) );
476 aMidRect
.Move( (aRect
.GetWidth() - aMidRect
.GetWidth()) / 2, (aRect
.GetHeight() - aMidRect
.GetHeight()) / 2 );
477 maTLBR
.AddClickRect( aMidRect
);
478 maBLTR
.AddClickRect( aMidRect
);
480 /* One of the diagonal frame borders enabled - use entire rectangle. */
481 else if( mbTLBR
&& !mbBLTR
) // top-left to bottom-right only
482 maTLBR
.AddClickRect( aRect
);
483 else if( !mbTLBR
&& mbBLTR
) // bottom-left to top-right only
484 maBLTR
.AddClickRect( aRect
);
490 void FrameSelectorImpl::InitVirtualDevice()
492 // initialize resources
494 InitArrowImageList();
499 void FrameSelectorImpl::sizeChanged()
501 // initialize geometry
502 InitGlobalGeometry();
503 InitBorderGeometry();
505 // correct background around the used area
506 mrFrameSel
.SetBackground( Wallpaper( maBackCol
) );
507 DoInvalidate( true );
510 // frame border access --------------------------------------------------------
512 const FrameBorder
& FrameSelectorImpl::GetBorder( FrameBorderType eBorder
) const
514 size_t nIndex
= GetIndexFromFrameBorderType( eBorder
);
515 if( nIndex
< maAllBorders
.size() )
516 return *maAllBorders
[ nIndex
];
517 SAL_WARN( "svx.dialog", "svx::FrameSelectorImpl::GetBorder - unknown border type" );
521 FrameBorder
& FrameSelectorImpl::GetBorderAccess( FrameBorderType eBorder
)
523 return const_cast< FrameBorder
& >( GetBorder( eBorder
) );
526 // drawing --------------------------------------------------------------------
528 void FrameSelectorImpl::DrawBackground()
531 maVirDev
.SetLineColor();
532 maVirDev
.SetFillColor( maBackCol
);
533 maVirDev
.DrawRect( Rectangle( Point( 0, 0 ), maVirDev
.GetOutputSizePixel() ) );
535 // draw the inner gray (or whatever color) rectangle
536 maVirDev
.SetLineColor();
537 maVirDev
.SetFillColor( maMarkCol
);
538 maVirDev
.DrawRect( Rectangle(
539 mnLine1
- mnFocusOffs
, mnLine1
- mnFocusOffs
, mnLine3
+ mnFocusOffs
, mnLine3
+ mnFocusOffs
) );
541 // draw the white space for enabled frame borders
543 for( FrameBorderCIter
aIt( maEnabBorders
); aIt
.Is(); ++aIt
)
544 (*aIt
)->MergeFocusToPolyPolygon( aPPoly
);
545 aPPoly
.Optimize( POLY_OPTIMIZE_CLOSE
);
546 maVirDev
.SetLineColor( maBackCol
);
547 maVirDev
.SetFillColor( maBackCol
);
548 maVirDev
.DrawPolyPolygon( aPPoly
);
551 void FrameSelectorImpl::DrawArrows( const FrameBorder
& rBorder
)
553 DBG_ASSERT( rBorder
.IsEnabled(), "svx::FrameSelectorImpl::DrawArrows - access to disabled border" );
556 switch( rBorder
.GetType() )
558 case FRAMEBORDER_LEFT
:
559 case FRAMEBORDER_TOP
: nLinePos
= mnLine1
; break;
560 case FRAMEBORDER_VER
:
561 case FRAMEBORDER_HOR
: nLinePos
= mnLine2
; break;
562 case FRAMEBORDER_RIGHT
:
563 case FRAMEBORDER_BOTTOM
: nLinePos
= mnLine3
; break;
564 default: ; //prevent warning
566 nLinePos
-= mnArrowSize
/ 2;
569 long nBRPos
= mnCtrlSize
- mnArrowSize
;
571 sal_uInt16 nImgId1
= 0, nImgId2
= 0;
572 switch( rBorder
.GetType() )
574 case FRAMEBORDER_LEFT
:
575 case FRAMEBORDER_RIGHT
:
576 case FRAMEBORDER_VER
:
577 aPos1
= Point( nLinePos
, nTLPos
); nImgId1
= 1;
578 aPos2
= Point( nLinePos
, nBRPos
); nImgId2
= 2;
581 case FRAMEBORDER_TOP
:
582 case FRAMEBORDER_BOTTOM
:
583 case FRAMEBORDER_HOR
:
584 aPos1
= Point( nTLPos
, nLinePos
); nImgId1
= 3;
585 aPos2
= Point( nBRPos
, nLinePos
); nImgId2
= 4;
588 case FRAMEBORDER_TLBR
:
589 aPos1
= Point( nTLPos
, nTLPos
); nImgId1
= 5;
590 aPos2
= Point( nBRPos
, nBRPos
); nImgId2
= 6;
592 case FRAMEBORDER_BLTR
:
593 aPos1
= Point( nTLPos
, nBRPos
); nImgId1
= 7;
594 aPos2
= Point( nBRPos
, nTLPos
); nImgId2
= 8;
596 default: ; //prevent warning
599 // Arrow or marker? Do not draw arrows into disabled control.
600 sal_uInt16 nSelectAdd
= (mrFrameSel
.IsEnabled() && rBorder
.IsSelected()) ? 0 : 8;
601 maVirDev
.DrawImage( aPos1
, maILArrows
.GetImage( nImgId1
+ nSelectAdd
) );
602 maVirDev
.DrawImage( aPos2
, maILArrows
.GetImage( nImgId2
+ nSelectAdd
) );
605 void FrameSelectorImpl::DrawAllArrows()
607 for( FrameBorderCIter
aIt( maEnabBorders
); aIt
.Is(); ++aIt
)
611 Color
FrameSelectorImpl::GetDrawLineColor( const Color
& rColor
) const
613 Color
aColor( mbHCMode
? maHCLineCol
: rColor
);
614 if( aColor
== maBackCol
)
619 void FrameSelectorImpl::DrawAllFrameBorders()
621 // Translate core colors to current UI colors (regards current background and HC mode).
622 for( FrameBorderIter
aIt( maEnabBorders
); aIt
.Is(); ++aIt
)
624 Color aCoreColorPrim
= ((*aIt
)->GetState() == FRAMESTATE_DONTCARE
) ? maMarkCol
: (*aIt
)->GetCoreStyle().GetColorOut();
625 Color aCoreColorSecn
= ((*aIt
)->GetState() == FRAMESTATE_DONTCARE
) ? maMarkCol
: (*aIt
)->GetCoreStyle().GetColorIn();
626 (*aIt
)->SetUIColorPrim( GetDrawLineColor( aCoreColorPrim
) );
627 (*aIt
)->SetUIColorSecn( GetDrawLineColor( aCoreColorSecn
) );
630 // Copy all frame border styles to the helper array
631 maArray
.SetColumnStyleLeft( 0, maLeft
.GetUIStyle() );
632 if( mbVer
) maArray
.SetColumnStyleLeft( 1, maVer
.GetUIStyle() );
634 // Invert the style for the right line
635 const frame::Style rRightStyle
= maRight
.GetUIStyle( );
636 frame::Style
rInvertedRight( rRightStyle
.GetColorPrim(),
637 rRightStyle
.GetColorSecn(), rRightStyle
.GetColorGap(),
638 rRightStyle
.UseGapColor(),
639 rRightStyle
.Secn(), rRightStyle
.Dist(), rRightStyle
.Prim( ),
640 rRightStyle
.Type( ) );
641 maArray
.SetColumnStyleRight( mbVer
? 1 : 0, rInvertedRight
);
643 maArray
.SetRowStyleTop( 0, maTop
.GetUIStyle() );
646 // Invert the style for the hor line to match the real borders
647 const frame::Style rHorStyle
= maHor
.GetUIStyle();
648 frame::Style
rInvertedHor( rHorStyle
.GetColorPrim(),
649 rHorStyle
.GetColorSecn(), rHorStyle
.GetColorGap(),
650 rHorStyle
.UseGapColor(),
651 rHorStyle
.Secn(), rHorStyle
.Dist(), rHorStyle
.Prim( ),
653 maArray
.SetRowStyleTop( 1, rInvertedHor
);
656 // Invert the style for the bottom line
657 const frame::Style rBottomStyle
= maBottom
.GetUIStyle( );
658 frame::Style
rInvertedBottom( rBottomStyle
.GetColorPrim(),
659 rBottomStyle
.GetColorSecn(), rBottomStyle
.GetColorGap(),
660 rBottomStyle
.UseGapColor(),
661 rBottomStyle
.Secn(), rBottomStyle
.Dist(), rBottomStyle
.Prim( ),
662 rBottomStyle
.Type() );
663 maArray
.SetRowStyleBottom( mbHor
? 1 : 0, rInvertedBottom
);
665 for( size_t nCol
= 0; nCol
< maArray
.GetColCount(); ++nCol
)
666 for( size_t nRow
= 0; nRow
< maArray
.GetRowCount(); ++nRow
)
667 maArray
.SetCellStyleDiag( nCol
, nRow
, maTLBR
.GetUIStyle(), maBLTR
.GetUIStyle() );
669 // Let the helper array draw itself
670 maArray
.DrawArray( maVirDev
);
673 void FrameSelectorImpl::DrawVirtualDevice()
677 DrawAllFrameBorders();
678 mbFullRepaint
= false;
681 void FrameSelectorImpl::CopyVirDevToControl()
685 mrFrameSel
.DrawBitmap( maVirDevPos
, maVirDev
.GetBitmap( Point( 0, 0 ), maVirDev
.GetOutputSizePixel() ) );
688 void FrameSelectorImpl::DrawAllTrackingRects()
691 if( mrFrameSel
.IsAnyBorderSelected() )
693 for( SelFrameBorderCIter
aIt( maEnabBorders
); aIt
.Is(); ++aIt
)
694 (*aIt
)->MergeFocusToPolyPolygon( aPPoly
);
695 aPPoly
.Move( maVirDevPos
.X(), maVirDevPos
.Y() );
698 // no frame border selected -> draw tracking rectangle around entire control
699 aPPoly
.Insert( Polygon( Rectangle( maVirDevPos
, maVirDev
.GetOutputSizePixel() ) ) );
701 aPPoly
.Optimize( POLY_OPTIMIZE_CLOSE
);
702 for( sal_uInt16 nIdx
= 0, nCount
= aPPoly
.Count(); nIdx
< nCount
; ++nIdx
)
703 mrFrameSel
.InvertTracking( aPPoly
.GetObject( nIdx
), SHOWTRACK_SMALL
| SHOWTRACK_WINDOW
);
706 Point
FrameSelectorImpl::GetDevPosFromMousePos( const Point
& rMousePos
) const
708 return rMousePos
- maVirDevPos
;
711 void FrameSelectorImpl::DoInvalidate( bool bFullRepaint
)
713 mbFullRepaint
|= bFullRepaint
;
714 mrFrameSel
.Invalidate( INVALIDATE_NOERASE
);
717 // frame border state and style -----------------------------------------------
719 void FrameSelectorImpl::SetBorderState( FrameBorder
& rBorder
, FrameBorderState eState
)
721 DBG_ASSERT( rBorder
.IsEnabled(), "svx::FrameSelectorImpl::SetBorderState - access to disabled border" );
722 if( eState
== FRAMESTATE_SHOW
)
723 SetBorderCoreStyle( rBorder
, &maCurrStyle
);
725 rBorder
.SetState( eState
);
726 DoInvalidate( true );
729 void FrameSelectorImpl::SetBorderCoreStyle( FrameBorder
& rBorder
, const SvxBorderLine
* pStyle
)
731 DBG_ASSERT( rBorder
.IsEnabled(), "svx::FrameSelectorImpl::SetBorderCoreStyle - access to disabled border" );
732 rBorder
.SetCoreStyle( pStyle
);
733 DoInvalidate( true );
736 void FrameSelectorImpl::ToggleBorderState( FrameBorder
& rBorder
)
738 bool bDontCare
= mrFrameSel
.SupportsDontCareState();
739 switch( rBorder
.GetState() )
741 // same order as tristate check box: visible -> don't care -> hidden
742 case FRAMESTATE_SHOW
:
743 SetBorderState( rBorder
, bDontCare
? FRAMESTATE_DONTCARE
: FRAMESTATE_HIDE
);
745 case FRAMESTATE_HIDE
:
746 SetBorderState( rBorder
, FRAMESTATE_SHOW
);
748 case FRAMESTATE_DONTCARE
:
749 SetBorderState( rBorder
, FRAMESTATE_HIDE
);
754 // frame border selection -----------------------------------------------------
756 void FrameSelectorImpl::SelectBorder( FrameBorder
& rBorder
, bool bSelect
)
758 DBG_ASSERT( rBorder
.IsEnabled(), "svx::FrameSelectorImpl::SelectBorder - access to disabled border" );
759 rBorder
.Select( bSelect
);
760 DrawArrows( rBorder
);
761 DoInvalidate( false );
764 void FrameSelectorImpl::SilentGrabFocus()
766 bool bOldAuto
= mbAutoSelect
;
767 mbAutoSelect
= false;
768 mrFrameSel
.GrabFocus();
769 mbAutoSelect
= bOldAuto
;
772 bool FrameSelectorImpl::SelectedBordersEqual() const
775 SelFrameBorderCIter
aIt( maEnabBorders
);
778 const SvxBorderLine
& rFirstStyle
= (*aIt
)->GetCoreStyle();
779 for( ++aIt
; bEqual
&& aIt
.Is(); ++aIt
)
780 bEqual
= ((*aIt
)->GetCoreStyle() == rFirstStyle
);
785 // ============================================================================
787 // ============================================================================
789 FrameSelector::FrameSelector(Window
* pParent
)
790 : Control(pParent
, WB_BORDER
|WB_TABSTOP
)
792 // not in c'tor init list (avoid warning about usage of *this)
793 mxImpl
.reset( new FrameSelectorImpl( *this ) );
794 EnableRTL( false ); // #107808# don't mirror the mouse handling
797 extern "C" SAL_DLLPUBLIC_EXPORT Window
* SAL_CALL
makeSvxFrameSelector(Window
*pParent
, VclBuilder::stringmap
&)
799 return new FrameSelector(pParent
);
802 FrameSelector::~FrameSelector()
806 void FrameSelector::Initialize( FrameSelFlags nFlags
)
808 mxImpl
->Initialize( nFlags
);
812 // enabled frame borders ------------------------------------------------------
814 bool FrameSelector::IsBorderEnabled( FrameBorderType eBorder
) const
816 return mxImpl
->GetBorder( eBorder
).IsEnabled();
819 sal_Int32
FrameSelector::GetEnabledBorderCount() const
821 return static_cast< sal_Int32
>( mxImpl
->maEnabBorders
.size() );
824 FrameBorderType
FrameSelector::GetEnabledBorderType( sal_Int32 nIndex
) const
826 FrameBorderType eBorder
= FRAMEBORDER_NONE
;
829 size_t nVecIdx
= static_cast< size_t >( nIndex
);
830 if( nVecIdx
< mxImpl
->maEnabBorders
.size() )
831 eBorder
= mxImpl
->maEnabBorders
[ nVecIdx
]->GetType();
836 sal_Int32
FrameSelector::GetEnabledBorderIndex( FrameBorderType eBorder
) const
838 sal_Int32 nIndex
= 0;
839 for( FrameBorderCIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
, ++nIndex
)
840 if( (*aIt
)->GetType() == eBorder
)
845 // frame border state and style -----------------------------------------------
847 bool FrameSelector::SupportsDontCareState() const
849 return (mxImpl
->mnFlags
& FRAMESEL_DONTCARE
) != 0;
852 FrameBorderState
FrameSelector::GetFrameBorderState( FrameBorderType eBorder
) const
854 return mxImpl
->GetBorder( eBorder
).GetState();
857 const SvxBorderLine
* FrameSelector::GetFrameBorderStyle( FrameBorderType eBorder
) const
859 const SvxBorderLine
& rStyle
= mxImpl
->GetBorder( eBorder
).GetCoreStyle();
860 // rest of the world uses null pointer for invisible frame border
861 return rStyle
.GetOutWidth() ? &rStyle
: 0;
864 void FrameSelector::ShowBorder( FrameBorderType eBorder
, const SvxBorderLine
* pStyle
)
866 mxImpl
->SetBorderCoreStyle( mxImpl
->GetBorderAccess( eBorder
), pStyle
);
869 void FrameSelector::SetBorderDontCare( FrameBorderType eBorder
)
871 mxImpl
->SetBorderState( mxImpl
->GetBorderAccess( eBorder
), FRAMESTATE_DONTCARE
);
874 bool FrameSelector::IsAnyBorderVisible() const
877 for( FrameBorderCIter
aIt( mxImpl
->maEnabBorders
); !bIsSet
&& aIt
.Is(); ++aIt
)
878 bIsSet
= ((*aIt
)->GetState() == FRAMESTATE_SHOW
);
882 void FrameSelector::HideAllBorders()
884 for( FrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
885 mxImpl
->SetBorderState( **aIt
, FRAMESTATE_HIDE
);
888 bool FrameSelector::GetVisibleWidth( long& rnWidth
, SvxBorderStyle
& rnStyle
) const
890 VisFrameBorderCIter
aIt( mxImpl
->maEnabBorders
);
894 const SvxBorderLine
& rStyle
= (*aIt
)->GetCoreStyle();
896 for( ++aIt
; bFound
&& aIt
.Is(); ++aIt
)
899 (rStyle
.GetWidth() == (*aIt
)->GetCoreStyle().GetWidth()) &&
900 (rStyle
.GetBorderLineStyle() ==
901 (*aIt
)->GetCoreStyle().GetBorderLineStyle());
906 rnWidth
= rStyle
.GetWidth();
907 rnStyle
= rStyle
.GetBorderLineStyle();
912 bool FrameSelector::GetVisibleColor( Color
& rColor
) const
914 VisFrameBorderCIter
aIt( mxImpl
->maEnabBorders
);
918 const SvxBorderLine
& rStyle
= (*aIt
)->GetCoreStyle();
920 for( ++aIt
; bFound
&& aIt
.Is(); ++aIt
)
921 bFound
= (rStyle
.GetColor() == (*aIt
)->GetCoreStyle().GetColor());
924 rColor
= rStyle
.GetColor();
928 // frame border selection -----------------------------------------------------
930 const Link
& FrameSelector::GetSelectHdl() const
932 return mxImpl
->maSelectHdl
;
935 void FrameSelector::SetSelectHdl( const Link
& rHdl
)
937 mxImpl
->maSelectHdl
= rHdl
;
940 bool FrameSelector::IsBorderSelected( FrameBorderType eBorder
) const
942 return mxImpl
->GetBorder( eBorder
).IsSelected();
945 void FrameSelector::SelectBorder( FrameBorderType eBorder
, bool bSelect
)
947 mxImpl
->SelectBorder( mxImpl
->GetBorderAccess( eBorder
), bSelect
);
950 bool FrameSelector::IsAnyBorderSelected() const
952 // Construct an iterator for selected borders. If it is valid, there is a selected border.
953 return SelFrameBorderCIter( mxImpl
->maEnabBorders
).Is();
956 void FrameSelector::SelectAllBorders( bool bSelect
)
958 for( FrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
959 mxImpl
->SelectBorder( **aIt
, bSelect
);
962 void FrameSelector::SelectAllVisibleBorders( bool bSelect
)
964 for( VisFrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
965 mxImpl
->SelectBorder( **aIt
, bSelect
);
968 void FrameSelector::SetStyleToSelection( long nWidth
, SvxBorderStyle nStyle
)
970 mxImpl
->maCurrStyle
.SetBorderLineStyle( nStyle
);
971 mxImpl
->maCurrStyle
.SetWidth( nWidth
);
972 for( SelFrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
973 mxImpl
->SetBorderState( **aIt
, FRAMESTATE_SHOW
);
976 void FrameSelector::SetColorToSelection( const Color
& rColor
)
978 mxImpl
->maCurrStyle
.SetColor( rColor
);
979 for( SelFrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
980 mxImpl
->SetBorderState( **aIt
, FRAMESTATE_SHOW
);
983 // accessibility --------------------------------------------------------------
985 Reference
< XAccessible
> FrameSelector::CreateAccessible()
987 if( !mxImpl
->mxAccess
.is() )
988 mxImpl
->mxAccess
= mxImpl
->mpAccess
=
989 new a11y::AccFrameSelector( *this, FRAMEBORDER_NONE
);
990 return mxImpl
->mxAccess
;
993 Reference
< XAccessible
> FrameSelector::GetChildAccessible( FrameBorderType eBorder
)
995 Reference
< XAccessible
> xRet
;
996 size_t nVecIdx
= static_cast< size_t >( eBorder
);
997 if( IsBorderEnabled( eBorder
) && (1 <= nVecIdx
) && (nVecIdx
<= mxImpl
->maChildVec
.size()) )
1000 if( !mxImpl
->maChildVec
[ nVecIdx
] )
1001 mxImpl
->mxChildVec
[ nVecIdx
] = mxImpl
->maChildVec
[ nVecIdx
] =
1002 new a11y::AccFrameSelector( *this, eBorder
);
1003 xRet
= mxImpl
->mxChildVec
[ nVecIdx
];
1008 Reference
< XAccessible
> FrameSelector::GetChildAccessible( sal_Int32 nIndex
)
1010 return GetChildAccessible( GetEnabledBorderType( nIndex
) );
1013 Reference
< XAccessible
> FrameSelector::GetChildAccessible( const Point
& rPos
)
1015 Reference
< XAccessible
> xRet
;
1016 for( FrameBorderCIter
aIt( mxImpl
->maEnabBorders
); !xRet
.is() && aIt
.Is(); ++aIt
)
1017 if( (*aIt
)->ContainsClickPoint( rPos
) )
1018 xRet
= GetChildAccessible( (*aIt
)->GetType() );
1022 bool FrameSelector::ContainsClickPoint( const Point
& rPos
) const
1024 bool bContains
= false;
1025 for( FrameBorderCIter
aIt( mxImpl
->maEnabBorders
); !bContains
&& aIt
.Is(); ++aIt
)
1026 bContains
= (*aIt
)->ContainsClickPoint( rPos
);
1030 Rectangle
FrameSelector::GetClickBoundRect( FrameBorderType eBorder
) const
1033 const FrameBorder
& rBorder
= mxImpl
->GetBorder( eBorder
);
1034 if( rBorder
.IsEnabled() )
1035 aRect
= rBorder
.GetClickBoundRect();
1039 // virtual functions from base class ------------------------------------------
1041 void FrameSelector::Paint( const Rectangle
& )
1043 mxImpl
->CopyVirDevToControl();
1045 mxImpl
->DrawAllTrackingRects();
1048 void FrameSelector::MouseButtonDown( const MouseEvent
& rMEvt
)
1051 * Click on an unselected frame border:
1052 Set current style/color, make frame border visible, deselect all
1053 other frame borders.
1054 * Click on a selected frame border:
1055 Toggle state of the frame border (visible -> don't care -> hidden),
1056 deselect all other frame borders.
1057 * SHIFT+Click or CTRL+Click on an unselected frame border:
1058 Extend selection, set current style/color to all selected frame
1059 borders independent of the state/style/color of the borders.
1060 * SHIFT+Click or CTRL+Click on a selected frame border:
1061 If all frame borders have same style/color, toggle state of all
1062 borders (see above), otherwise set current style/color to all
1064 * Click on unused area: Do not modify selection and selected frame
1068 // #107394# do not auto-select a frame border
1069 mxImpl
->SilentGrabFocus();
1071 if( rMEvt
.IsLeft() )
1073 Point
aPos( mxImpl
->GetDevPosFromMousePos( rMEvt
.GetPosPixel() ) );
1074 FrameBorderPtrVec aDeselectBorders
;
1076 bool bAnyClicked
= false; // Any frame border clicked?
1077 bool bNewSelected
= false; // Any unselected frame border selected?
1079 /* If frame borders are set to "don't care" and the control does not
1080 support this state, hide them on first mouse click.
1081 DR 2004-01-30: Why are the borders set to "don't care" then?!? */
1082 bool bHideDontCare
= !mxImpl
->mbClicked
&& !SupportsDontCareState();
1084 for( FrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
1086 if( (*aIt
)->ContainsClickPoint( aPos
) )
1088 // frame border is clicked
1090 if( !(*aIt
)->IsSelected() )
1092 bNewSelected
= true;
1093 mxImpl
->SelectBorder( **aIt
, true );
1098 // hide a "don't care" frame border only if it is not clicked
1099 if( bHideDontCare
&& ((*aIt
)->GetState() == FRAMESTATE_DONTCARE
) )
1100 mxImpl
->SetBorderState( **aIt
, FRAMESTATE_HIDE
);
1102 // deselect frame borders not clicked (if SHIFT or CTRL are not pressed)
1103 if( !rMEvt
.IsShift() && !rMEvt
.IsMod1() )
1104 aDeselectBorders
.push_back( *aIt
);
1110 // any valid frame border clicked? -> deselect other frame borders
1111 for( FrameBorderIter
aIt( aDeselectBorders
); aIt
.Is(); ++aIt
)
1112 mxImpl
->SelectBorder( **aIt
, false );
1114 if( bNewSelected
|| !mxImpl
->SelectedBordersEqual() )
1116 // new frame border selected, selection extended, or selected borders different? -> show
1117 for( SelFrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
1118 // SetBorderState() sets current style and color to the frame border
1119 mxImpl
->SetBorderState( **aIt
, FRAMESTATE_SHOW
);
1123 // all selected frame borders are equal -> toggle state
1124 for( SelFrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
1125 mxImpl
->ToggleBorderState( **aIt
);
1128 GetSelectHdl().Call( this );
1133 void FrameSelector::KeyInput( const KeyEvent
& rKEvt
)
1135 bool bHandled
= false;
1136 KeyCode aKeyCode
= rKEvt
.GetKeyCode();
1137 if( !aKeyCode
.GetModifier() )
1139 sal_uInt16 nCode
= aKeyCode
.GetCode();
1144 for( SelFrameBorderIter
aIt( mxImpl
->maEnabBorders
); aIt
.Is(); ++aIt
)
1145 mxImpl
->ToggleBorderState( **aIt
);
1155 if( !mxImpl
->maEnabBorders
.empty() )
1157 // start from first selected frame border
1158 SelFrameBorderCIter
aIt( mxImpl
->maEnabBorders
);
1159 FrameBorderType eBorder
= aIt
.Is() ? (*aIt
)->GetType() : mxImpl
->maEnabBorders
.front()->GetType();
1161 // search for next enabled frame border
1164 eBorder
= mxImpl
->GetBorder( eBorder
).GetKeyboardNeighbor( nCode
);
1166 while( (eBorder
!= FRAMEBORDER_NONE
) && !IsBorderEnabled( eBorder
) );
1168 // select the frame border
1169 if( eBorder
!= FRAMEBORDER_NONE
)
1171 DeselectAllBorders();
1172 SelectBorder( eBorder
);
1180 Window::KeyInput(rKEvt
);
1183 void FrameSelector::GetFocus()
1185 // auto-selection of a frame border, if focus reaches control, and nothing is selected
1186 if( mxImpl
->mbAutoSelect
&& !IsAnyBorderSelected() && !mxImpl
->maEnabBorders
.empty() )
1187 mxImpl
->SelectBorder( *mxImpl
->maEnabBorders
.front(), true );
1189 mxImpl
->DoInvalidate( false );
1190 if( mxImpl
->mxAccess
.is() )
1191 mxImpl
->mpAccess
->NotifyFocusListeners( sal_True
);
1192 Control::GetFocus();
1195 void FrameSelector::LoseFocus()
1197 mxImpl
->DoInvalidate( false );
1198 if( mxImpl
->mxAccess
.is() )
1199 mxImpl
->mpAccess
->NotifyFocusListeners( sal_False
);
1200 Control::LoseFocus();
1203 void FrameSelector::DataChanged( const DataChangedEvent
& rDCEvt
)
1205 Control::DataChanged( rDCEvt
);
1206 if( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) && (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
1207 mxImpl
->InitVirtualDevice();
1210 void FrameSelector::Resize()
1213 mxImpl
->sizeChanged();
1216 Size
FrameSelector::GetOptimalSize() const
1218 return LogicToPixel(Size(61, 65), MAP_APPFONT
);
1221 // ============================================================================
1223 template< typename Cont
, typename Iter
, typename Pred
>
1224 FrameBorderIterBase
< Cont
, Iter
, Pred
>::FrameBorderIterBase( container_type
& rCont
) :
1225 maIt( rCont
.begin() ),
1226 maEnd( rCont
.end() )
1228 while( Is() && !maPred( *maIt
) ) ++maIt
;
1231 template< typename Cont
, typename Iter
, typename Pred
>
1232 FrameBorderIterBase
< Cont
, Iter
, Pred
>& FrameBorderIterBase
< Cont
, Iter
, Pred
>::operator++()
1234 do { ++maIt
; } while( Is() && !maPred( *maIt
) );
1238 // ============================================================================
1242 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */