1f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3f6e50924SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4f6e50924SAndrew Rist * or more contributor license agreements. See the NOTICE file
5f6e50924SAndrew Rist * distributed with this work for additional information
6f6e50924SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7f6e50924SAndrew Rist * to you under the Apache License, Version 2.0 (the
8f6e50924SAndrew Rist * "License"); you may not use this file except in compliance
9f6e50924SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11f6e50924SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13f6e50924SAndrew Rist * Unless required by applicable law or agreed to in writing,
14f6e50924SAndrew Rist * software distributed under the License is distributed on an
15f6e50924SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16f6e50924SAndrew Rist * KIND, either express or implied. See the License for the
17f6e50924SAndrew Rist * specific language governing permissions and limitations
18f6e50924SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20f6e50924SAndrew Rist *************************************************************/
21f6e50924SAndrew Rist
22f6e50924SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir #include <svx/frmsel.hxx>
27cdf0e10cSrcweir
28cdf0e10cSrcweir #include <algorithm>
29cdf0e10cSrcweir #include <math.h>
30cdf0e10cSrcweir #include "frmselimpl.hxx"
31cdf0e10cSrcweir #include "AccessibleFrameSelector.hxx"
32cdf0e10cSrcweir #include <svx/dialmgr.hxx>
339b8096d0SSteve Yin #include <com/sun/star/accessibility/AccessibleEventId.hpp>
349b8096d0SSteve Yin #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLESTATETYPE_HDL_
359b8096d0SSteve Yin #include <com/sun/star/accessibility/AccessibleStateType.hpp>
369b8096d0SSteve Yin #endif
37cdf0e10cSrcweir
38cdf0e10cSrcweir #ifndef _SVX_DIALOGS_HRC
39cdf0e10cSrcweir #include <svx/dialogs.hrc>
40cdf0e10cSrcweir #endif
41cdf0e10cSrcweir #ifndef SVX_FRMSEL_HRC
42cdf0e10cSrcweir #include "frmsel.hrc"
43cdf0e10cSrcweir #endif
44cdf0e10cSrcweir
45cdf0e10cSrcweir #include <tools/rcid.h>
46cdf0e10cSrcweir
47cdf0e10cSrcweir namespace svx {
48cdf0e10cSrcweir
49cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
509b8096d0SSteve Yin using ::com::sun::star::uno::Any;
51cdf0e10cSrcweir using ::com::sun::star::accessibility::XAccessible;
529b8096d0SSteve Yin using namespace ::com::sun::star::accessibility;
53cdf0e10cSrcweir // ============================================================================
54cdf0e10cSrcweir // global functions from framebordertype.hxx
55cdf0e10cSrcweir
GetFrameBorderTypeFromIndex(size_t nIndex)56cdf0e10cSrcweir FrameBorderType GetFrameBorderTypeFromIndex( size_t nIndex )
57cdf0e10cSrcweir {
58cdf0e10cSrcweir DBG_ASSERT( nIndex < (size_t)FRAMEBORDERTYPE_COUNT,
59cdf0e10cSrcweir "svx::GetFrameBorderTypeFromIndex - invalid index" );
60cdf0e10cSrcweir return static_cast< FrameBorderType >( nIndex + 1 );
61cdf0e10cSrcweir }
62cdf0e10cSrcweir
GetIndexFromFrameBorderType(FrameBorderType eBorder)63cdf0e10cSrcweir size_t GetIndexFromFrameBorderType( FrameBorderType eBorder )
64cdf0e10cSrcweir {
65cdf0e10cSrcweir DBG_ASSERT( eBorder != FRAMEBORDER_NONE,
66cdf0e10cSrcweir "svx::GetIndexFromFrameBorderType - invalid frame border type" );
67cdf0e10cSrcweir return static_cast< size_t >( eBorder ) - 1;
68cdf0e10cSrcweir }
69cdf0e10cSrcweir
70cdf0e10cSrcweir // ============================================================================
71cdf0e10cSrcweir
72cdf0e10cSrcweir namespace {
73cdf0e10cSrcweir
74cdf0e10cSrcweir /** Space between outer control border and any graphical element of the control. */
75cdf0e10cSrcweir const long FRAMESEL_GEOM_OUTER = 2;
76cdf0e10cSrcweir
77cdf0e10cSrcweir /** Space between arrows and usable inner area. */
78cdf0e10cSrcweir const long FRAMESEL_GEOM_INNER = 3;
79cdf0e10cSrcweir
80cdf0e10cSrcweir /** Maximum width to draw a frame border style. */
81cdf0e10cSrcweir const long FRAMESEL_GEOM_WIDTH = 9;
82cdf0e10cSrcweir
83cdf0e10cSrcweir /** Additional margin for click area of outer lines. */
84cdf0e10cSrcweir const long FRAMESEL_GEOM_ADD_CLICK_OUTER = 5;
85cdf0e10cSrcweir
86cdf0e10cSrcweir /** Additional margin for click area of inner lines. */
87cdf0e10cSrcweir const long FRAMESEL_GEOM_ADD_CLICK_INNER = 2;
88cdf0e10cSrcweir
89cdf0e10cSrcweir // ----------------------------------------------------------------------------
90cdf0e10cSrcweir
91cdf0e10cSrcweir static const frame::Style OBJ_FRAMESTYLE_DONTCARE( 3, 0, 0 );
92cdf0e10cSrcweir static const FrameBorder OBJ_FRAMEBORDER_NONE( FRAMEBORDER_NONE );
93cdf0e10cSrcweir
94cdf0e10cSrcweir // ----------------------------------------------------------------------------
95cdf0e10cSrcweir
96cdf0e10cSrcweir /** Returns the corresponding flag for a frame border. */
lclGetFlagFromType(FrameBorderType eBorder)97cdf0e10cSrcweir FrameSelFlags lclGetFlagFromType( FrameBorderType eBorder )
98cdf0e10cSrcweir {
99cdf0e10cSrcweir switch( eBorder )
100cdf0e10cSrcweir {
101cdf0e10cSrcweir case FRAMEBORDER_LEFT: return FRAMESEL_LEFT;
102cdf0e10cSrcweir case FRAMEBORDER_RIGHT: return FRAMESEL_RIGHT;
103cdf0e10cSrcweir case FRAMEBORDER_TOP: return FRAMESEL_TOP;
104cdf0e10cSrcweir case FRAMEBORDER_BOTTOM: return FRAMESEL_BOTTOM;
105cdf0e10cSrcweir case FRAMEBORDER_HOR: return FRAMESEL_INNER_HOR;
106cdf0e10cSrcweir case FRAMEBORDER_VER: return FRAMESEL_INNER_VER;
107cdf0e10cSrcweir case FRAMEBORDER_TLBR: return FRAMESEL_DIAG_TLBR;
108cdf0e10cSrcweir case FRAMEBORDER_BLTR: return FRAMESEL_DIAG_BLTR;
109cdf0e10cSrcweir case FRAMEBORDER_NONE : break;
110cdf0e10cSrcweir }
111cdf0e10cSrcweir return FRAMESEL_NONE;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir
114cdf0e10cSrcweir /** Converts an SvxBorderLine line width (in twips) to a pixel line width. */
lclGetPixel(sal_uInt16 nWidth)115cdf0e10cSrcweir inline sal_uInt16 lclGetPixel( sal_uInt16 nWidth )
116cdf0e10cSrcweir {
117cdf0e10cSrcweir // convert all core styles expect 0 to a visible UI style (at least 1 pixel), map 1pt to 1pixel
118cdf0e10cSrcweir return nWidth ? std::min< sal_uInt16 >( std::max< sal_uInt16 >( (nWidth + 5) / 20, 1 ), FRAMESEL_GEOM_WIDTH ) : 0;
119cdf0e10cSrcweir }
120cdf0e10cSrcweir
121cdf0e10cSrcweir /** Merges the rSource polypolygon into the rDest polypolygon. */
lclPolyPolyUnion(PolyPolygon & rDest,const PolyPolygon & rSource)122cdf0e10cSrcweir inline void lclPolyPolyUnion( PolyPolygon& rDest, const PolyPolygon& rSource )
123cdf0e10cSrcweir {
124cdf0e10cSrcweir const PolyPolygon aTmp( rDest );
125cdf0e10cSrcweir aTmp.GetUnion( rSource, rDest );
126cdf0e10cSrcweir }
127cdf0e10cSrcweir
128cdf0e10cSrcweir } // namespace
129cdf0e10cSrcweir
130cdf0e10cSrcweir // ============================================================================
131cdf0e10cSrcweir // FrameBorder
132cdf0e10cSrcweir // ============================================================================
133cdf0e10cSrcweir
FrameBorder(FrameBorderType eType)134cdf0e10cSrcweir FrameBorder::FrameBorder( FrameBorderType eType ) :
135cdf0e10cSrcweir meType( eType ),
136cdf0e10cSrcweir meState( FRAMESTATE_HIDE ),
137cdf0e10cSrcweir meKeyLeft( FRAMEBORDER_NONE ),
138cdf0e10cSrcweir meKeyRight( FRAMEBORDER_NONE ),
139cdf0e10cSrcweir meKeyTop( FRAMEBORDER_NONE ),
140cdf0e10cSrcweir meKeyBottom( FRAMEBORDER_NONE ),
141cdf0e10cSrcweir mbEnabled( false ),
142cdf0e10cSrcweir mbSelected( false )
143cdf0e10cSrcweir {
144cdf0e10cSrcweir }
145cdf0e10cSrcweir
Enable(FrameSelFlags nFlags)146cdf0e10cSrcweir void FrameBorder::Enable( FrameSelFlags nFlags )
147cdf0e10cSrcweir {
148cdf0e10cSrcweir mbEnabled = (nFlags & lclGetFlagFromType( meType )) != 0;
149cdf0e10cSrcweir if( !mbEnabled )
150cdf0e10cSrcweir SetState( FRAMESTATE_HIDE );
151cdf0e10cSrcweir }
152cdf0e10cSrcweir
SetCoreStyle(const SvxBorderLine * pStyle)153cdf0e10cSrcweir void FrameBorder::SetCoreStyle( const SvxBorderLine* pStyle )
154cdf0e10cSrcweir {
155cdf0e10cSrcweir if( pStyle )
156cdf0e10cSrcweir maCoreStyle = *pStyle;
157cdf0e10cSrcweir else
158cdf0e10cSrcweir maCoreStyle = SvxBorderLine();
159cdf0e10cSrcweir
160cdf0e10cSrcweir // from twips to points
161cdf0e10cSrcweir maUIStyle.Set( maCoreStyle, 0.05, FRAMESEL_GEOM_WIDTH, true );
162cdf0e10cSrcweir meState = maUIStyle.Prim() ? FRAMESTATE_SHOW : FRAMESTATE_HIDE;
163cdf0e10cSrcweir }
164cdf0e10cSrcweir
SetState(FrameBorderState eState)165cdf0e10cSrcweir void FrameBorder::SetState( FrameBorderState eState )
166cdf0e10cSrcweir {
167cdf0e10cSrcweir meState = eState;
168cdf0e10cSrcweir switch( meState )
169cdf0e10cSrcweir {
170cdf0e10cSrcweir case FRAMESTATE_SHOW:
171cdf0e10cSrcweir DBG_ERRORFILE( "svx::FrameBorder::SetState - use SetCoreStyle to make border visible" );
172cdf0e10cSrcweir break;
173cdf0e10cSrcweir case FRAMESTATE_HIDE:
174cdf0e10cSrcweir maCoreStyle = SvxBorderLine();
175cdf0e10cSrcweir maUIStyle.Clear();
176cdf0e10cSrcweir break;
177cdf0e10cSrcweir case FRAMESTATE_DONTCARE:
178cdf0e10cSrcweir maCoreStyle = SvxBorderLine();
179cdf0e10cSrcweir maUIStyle = OBJ_FRAMESTYLE_DONTCARE;
180cdf0e10cSrcweir break;
181cdf0e10cSrcweir }
182cdf0e10cSrcweir }
183cdf0e10cSrcweir
AddFocusPolygon(const Polygon & rFocus)184cdf0e10cSrcweir void FrameBorder::AddFocusPolygon( const Polygon& rFocus )
185cdf0e10cSrcweir {
186cdf0e10cSrcweir lclPolyPolyUnion( maFocusArea, rFocus );
187cdf0e10cSrcweir }
188cdf0e10cSrcweir
MergeFocusToPolyPolygon(PolyPolygon & rPPoly) const189cdf0e10cSrcweir void FrameBorder::MergeFocusToPolyPolygon( PolyPolygon& rPPoly ) const
190cdf0e10cSrcweir {
191cdf0e10cSrcweir lclPolyPolyUnion( rPPoly, maFocusArea );
192cdf0e10cSrcweir }
193cdf0e10cSrcweir
AddClickRect(const Rectangle & rRect)194cdf0e10cSrcweir void FrameBorder::AddClickRect( const Rectangle& rRect )
195cdf0e10cSrcweir {
196cdf0e10cSrcweir lclPolyPolyUnion( maClickArea, Polygon( rRect ) );
197cdf0e10cSrcweir }
198cdf0e10cSrcweir
ContainsClickPoint(const Point & rPos) const199cdf0e10cSrcweir bool FrameBorder::ContainsClickPoint( const Point& rPos ) const
200cdf0e10cSrcweir {
201cdf0e10cSrcweir return Region( maClickArea ).IsInside( rPos );
202cdf0e10cSrcweir }
203cdf0e10cSrcweir
MergeClickAreaToPolyPolygon(PolyPolygon & rPPoly) const204cdf0e10cSrcweir void FrameBorder::MergeClickAreaToPolyPolygon( PolyPolygon& rPPoly ) const
205cdf0e10cSrcweir {
206cdf0e10cSrcweir lclPolyPolyUnion( rPPoly, maClickArea );
207cdf0e10cSrcweir }
208cdf0e10cSrcweir
GetClickBoundRect() const209cdf0e10cSrcweir Rectangle FrameBorder::GetClickBoundRect() const
210cdf0e10cSrcweir {
211cdf0e10cSrcweir return maClickArea.GetBoundRect();
212cdf0e10cSrcweir }
213cdf0e10cSrcweir
SetKeyboardNeighbors(FrameBorderType eLeft,FrameBorderType eRight,FrameBorderType eTop,FrameBorderType eBottom)214cdf0e10cSrcweir void FrameBorder::SetKeyboardNeighbors(
215cdf0e10cSrcweir FrameBorderType eLeft, FrameBorderType eRight, FrameBorderType eTop, FrameBorderType eBottom )
216cdf0e10cSrcweir {
217cdf0e10cSrcweir meKeyLeft = eLeft;
218cdf0e10cSrcweir meKeyRight = eRight;
219cdf0e10cSrcweir meKeyTop = eTop;
220cdf0e10cSrcweir meKeyBottom = eBottom;
221cdf0e10cSrcweir }
222cdf0e10cSrcweir
GetKeyboardNeighbor(sal_uInt16 nKeyCode) const223cdf0e10cSrcweir FrameBorderType FrameBorder::GetKeyboardNeighbor( sal_uInt16 nKeyCode ) const
224cdf0e10cSrcweir {
225cdf0e10cSrcweir FrameBorderType eBorder = FRAMEBORDER_NONE;
226cdf0e10cSrcweir switch( nKeyCode )
227cdf0e10cSrcweir {
228cdf0e10cSrcweir case KEY_LEFT: eBorder = meKeyLeft; break;
229cdf0e10cSrcweir case KEY_RIGHT: eBorder = meKeyRight; break;
230cdf0e10cSrcweir case KEY_UP: eBorder = meKeyTop; break;
231cdf0e10cSrcweir case KEY_DOWN: eBorder = meKeyBottom; break;
232cdf0e10cSrcweir default: DBG_ERRORFILE( "svx::FrameBorder::GetKeyboardNeighbor - unknown key code" );
233cdf0e10cSrcweir }
234cdf0e10cSrcweir return eBorder;
235cdf0e10cSrcweir }
236cdf0e10cSrcweir
237cdf0e10cSrcweir // ============================================================================
238cdf0e10cSrcweir // FrameSelectorImpl
239cdf0e10cSrcweir // ============================================================================
240cdf0e10cSrcweir
FrameSelectorImpl(FrameSelector & rFrameSel)241cdf0e10cSrcweir FrameSelectorImpl::FrameSelectorImpl( FrameSelector& rFrameSel ) :
242cdf0e10cSrcweir Resource( SVX_RES( RID_SVXSTR_BORDER_CONTROL ) ),
243cdf0e10cSrcweir mrFrameSel( rFrameSel ),
244cdf0e10cSrcweir maILArrows( 16 ),
245cdf0e10cSrcweir maLeft( FRAMEBORDER_LEFT ),
246cdf0e10cSrcweir maRight( FRAMEBORDER_RIGHT ),
247cdf0e10cSrcweir maTop( FRAMEBORDER_TOP ),
248cdf0e10cSrcweir maBottom( FRAMEBORDER_BOTTOM ),
249cdf0e10cSrcweir maHor( FRAMEBORDER_HOR ),
250cdf0e10cSrcweir maVer( FRAMEBORDER_VER ),
251cdf0e10cSrcweir maTLBR( FRAMEBORDER_TLBR ),
252cdf0e10cSrcweir maBLTR( FRAMEBORDER_BLTR ),
253cdf0e10cSrcweir mnFlags( FRAMESEL_OUTER ),
254cdf0e10cSrcweir mbHor( false ),
255cdf0e10cSrcweir mbVer( false ),
256cdf0e10cSrcweir mbTLBR( false ),
257cdf0e10cSrcweir mbBLTR( false ),
258cdf0e10cSrcweir mbFullRepaint( true ),
259cdf0e10cSrcweir mbAutoSelect( true ),
260cdf0e10cSrcweir mbClicked( false ),
261cdf0e10cSrcweir mbHCMode( false ),
262cdf0e10cSrcweir mpAccess( 0 ),
263cdf0e10cSrcweir maChildVec( 8, static_cast< a11y::AccFrameSelector* >( 0 ) ),
264cdf0e10cSrcweir mxChildVec( 8 )
265cdf0e10cSrcweir {
266cdf0e10cSrcweir FreeResource();
267cdf0e10cSrcweir
268cdf0e10cSrcweir maAllBorders.resize( FRAMEBORDERTYPE_COUNT, 0 );
269cdf0e10cSrcweir maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_LEFT ) ] = &maLeft;
270cdf0e10cSrcweir maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_RIGHT ) ] = &maRight;
271cdf0e10cSrcweir maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_TOP ) ] = &maTop;
272cdf0e10cSrcweir maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_BOTTOM ) ] = &maBottom;
273cdf0e10cSrcweir maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_HOR ) ] = &maHor;
274cdf0e10cSrcweir maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_VER ) ] = &maVer;
275cdf0e10cSrcweir maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_TLBR ) ] = &maTLBR;
276cdf0e10cSrcweir maAllBorders[ GetIndexFromFrameBorderType( FRAMEBORDER_BLTR ) ] = &maBLTR;
277cdf0e10cSrcweir #if OSL_DEBUG_LEVEL >= 2
278cdf0e10cSrcweir {
279cdf0e10cSrcweir bool bOk = true;
280cdf0e10cSrcweir for( FrameBorderCIter aIt( maAllBorders ); bOk && aIt.Is(); bOk = (*aIt != 0), ++aIt );
281cdf0e10cSrcweir DBG_ASSERT( bOk, "svx::FrameSelectorImpl::FrameSelectorImpl - missing entry in maAllBorders" );
282cdf0e10cSrcweir }
283cdf0e10cSrcweir #endif
284cdf0e10cSrcweir // left neighbor right neighbor upper neighbor lower neighbor
285cdf0e10cSrcweir maLeft.SetKeyboardNeighbors( FRAMEBORDER_NONE, FRAMEBORDER_TLBR, FRAMEBORDER_TOP, FRAMEBORDER_BOTTOM );
286cdf0e10cSrcweir maRight.SetKeyboardNeighbors( FRAMEBORDER_BLTR, FRAMEBORDER_NONE, FRAMEBORDER_TOP, FRAMEBORDER_BOTTOM );
287cdf0e10cSrcweir maTop.SetKeyboardNeighbors( FRAMEBORDER_LEFT, FRAMEBORDER_RIGHT, FRAMEBORDER_NONE, FRAMEBORDER_TLBR );
288cdf0e10cSrcweir maBottom.SetKeyboardNeighbors( FRAMEBORDER_LEFT, FRAMEBORDER_RIGHT, FRAMEBORDER_BLTR, FRAMEBORDER_NONE );
289cdf0e10cSrcweir maHor.SetKeyboardNeighbors( FRAMEBORDER_LEFT, FRAMEBORDER_RIGHT, FRAMEBORDER_TLBR, FRAMEBORDER_BLTR );
290cdf0e10cSrcweir maVer.SetKeyboardNeighbors( FRAMEBORDER_TLBR, FRAMEBORDER_BLTR, FRAMEBORDER_TOP, FRAMEBORDER_BOTTOM );
291cdf0e10cSrcweir maTLBR.SetKeyboardNeighbors( FRAMEBORDER_LEFT, FRAMEBORDER_VER, FRAMEBORDER_TOP, FRAMEBORDER_HOR );
292cdf0e10cSrcweir maBLTR.SetKeyboardNeighbors( FRAMEBORDER_VER, FRAMEBORDER_RIGHT, FRAMEBORDER_HOR, FRAMEBORDER_BOTTOM );
293cdf0e10cSrcweir }
294cdf0e10cSrcweir
~FrameSelectorImpl()295cdf0e10cSrcweir FrameSelectorImpl::~FrameSelectorImpl()
296cdf0e10cSrcweir {
297cdf0e10cSrcweir if( mpAccess )
298cdf0e10cSrcweir mpAccess->Invalidate();
299cdf0e10cSrcweir for( AccessibleImplVec::iterator aIt = maChildVec.begin(), aEnd = maChildVec.end(); aIt != aEnd; ++aIt )
300cdf0e10cSrcweir if( *aIt )
301cdf0e10cSrcweir (*aIt)->Invalidate();
302cdf0e10cSrcweir }
303cdf0e10cSrcweir
304cdf0e10cSrcweir // initialization -------------------------------------------------------------
305cdf0e10cSrcweir
Initialize(FrameSelFlags nFlags)306cdf0e10cSrcweir void FrameSelectorImpl::Initialize( FrameSelFlags nFlags )
307cdf0e10cSrcweir {
308cdf0e10cSrcweir mnFlags = nFlags;
309cdf0e10cSrcweir
310cdf0e10cSrcweir maEnabBorders.clear();
311cdf0e10cSrcweir for( FrameBorderIter aIt( maAllBorders ); aIt.Is(); ++aIt )
312cdf0e10cSrcweir {
313cdf0e10cSrcweir (*aIt)->Enable( mnFlags );
314cdf0e10cSrcweir if( (*aIt)->IsEnabled() )
315cdf0e10cSrcweir maEnabBorders.push_back( *aIt );
316cdf0e10cSrcweir }
317cdf0e10cSrcweir mbHor = maHor.IsEnabled();
318cdf0e10cSrcweir mbVer = maVer.IsEnabled();
319cdf0e10cSrcweir mbTLBR = maTLBR.IsEnabled();
320cdf0e10cSrcweir mbBLTR = maBLTR.IsEnabled();
321cdf0e10cSrcweir
322cdf0e10cSrcweir InitVirtualDevice();
323cdf0e10cSrcweir }
324cdf0e10cSrcweir
InitColors()325cdf0e10cSrcweir void FrameSelectorImpl::InitColors()
326cdf0e10cSrcweir {
327cdf0e10cSrcweir const StyleSettings& rSett = mrFrameSel.GetSettings().GetStyleSettings();
328cdf0e10cSrcweir maBackCol = rSett.GetFieldColor();
329cdf0e10cSrcweir mbHCMode = rSett.GetHighContrastMode();
330cdf0e10cSrcweir maArrowCol = rSett.GetFieldTextColor();
331cdf0e10cSrcweir maMarkCol.operator=( maBackCol ).Merge( maArrowCol, mbHCMode ? 0x80 : 0xC0 );
332cdf0e10cSrcweir maHCLineCol = rSett.GetLabelTextColor();
333cdf0e10cSrcweir }
334cdf0e10cSrcweir
InitArrowImageList()335cdf0e10cSrcweir void FrameSelectorImpl::InitArrowImageList()
336cdf0e10cSrcweir {
337cdf0e10cSrcweir /* Build the arrow images bitmap with current colors. */
338cdf0e10cSrcweir Color pColorAry1[3];
339cdf0e10cSrcweir Color pColorAry2[3];
340cdf0e10cSrcweir pColorAry1[0] = Color( 0, 0, 0 );
341cdf0e10cSrcweir pColorAry2[0] = maArrowCol; // black -> arrow color
342cdf0e10cSrcweir pColorAry1[1] = Color( 0, 255, 0 );
343cdf0e10cSrcweir pColorAry2[1] = maMarkCol; // green -> marker color
344cdf0e10cSrcweir pColorAry1[2] = Color( 255, 0, 255 );
345cdf0e10cSrcweir pColorAry2[2] = maBackCol; // magenta -> background
346cdf0e10cSrcweir
347cdf0e10cSrcweir GetRes( SVX_RES( RID_SVXSTR_BORDER_CONTROL ).SetRT( RSC_RESOURCE ) );
348cdf0e10cSrcweir maILArrows.InsertFromHorizontalBitmap(
349cdf0e10cSrcweir SVX_RES( BMP_FRMSEL_ARROWS ), 16, NULL, pColorAry1, pColorAry2, 3);
350cdf0e10cSrcweir FreeResource();
351cdf0e10cSrcweir DBG_ASSERT( maILArrows.GetImageSize().Height() == maILArrows.GetImageSize().Width(),
352cdf0e10cSrcweir "svx::FrameSelectorImpl::InitArrowImageList - images are not squarish" );
353cdf0e10cSrcweir mnArrowSize = maILArrows.GetImageSize().Height();
354cdf0e10cSrcweir }
355cdf0e10cSrcweir
InitGlobalGeometry()356cdf0e10cSrcweir void FrameSelectorImpl::InitGlobalGeometry()
357cdf0e10cSrcweir {
358cdf0e10cSrcweir Size aCtrlSize( mrFrameSel.CalcOutputSize( mrFrameSel.GetSizePixel() ) );
359cdf0e10cSrcweir /* nMinSize is the lower of width and height (control will always be squarish).
360cdf0e10cSrcweir FRAMESEL_GEOM_OUTER is the minimal distance between inner control border
361cdf0e10cSrcweir and any element. */
362cdf0e10cSrcweir long nMinSize = Min( aCtrlSize.Width(), aCtrlSize.Height() ) - 2 * FRAMESEL_GEOM_OUTER;
363cdf0e10cSrcweir /* nFixedSize is the size all existing elements need in one direction:
364cdf0e10cSrcweir the diag. arrow, space betw. arrow and frame border, outer frame border,
365cdf0e10cSrcweir inner frame border, other outer frame border, space betw. frame border
366cdf0e10cSrcweir and arrow, the other arrow. */
367cdf0e10cSrcweir long nFixedSize = 2 * mnArrowSize + 2 * FRAMESEL_GEOM_INNER + 3 * FRAMESEL_GEOM_WIDTH;
368cdf0e10cSrcweir /* nBetwBordersSize contains the size between an outer and inner frame border (made odd). */
369cdf0e10cSrcweir long nBetwBordersSize = (((nMinSize - nFixedSize) / 2) - 1) | 1;
370cdf0e10cSrcweir
371cdf0e10cSrcweir /* The final size of the usable area. */
372cdf0e10cSrcweir mnCtrlSize = 2 * nBetwBordersSize + nFixedSize;
373cdf0e10cSrcweir maVirDev.SetOutputSizePixel( Size( mnCtrlSize, mnCtrlSize ) );
374cdf0e10cSrcweir
375cdf0e10cSrcweir /* Center the virtual device in the control. */
376cdf0e10cSrcweir maVirDevPos = Point( (aCtrlSize.Width() - mnCtrlSize) / 2, (aCtrlSize.Height() - mnCtrlSize) / 2 );
377cdf0e10cSrcweir }
378cdf0e10cSrcweir
InitBorderGeometry()379cdf0e10cSrcweir void FrameSelectorImpl::InitBorderGeometry()
380cdf0e10cSrcweir {
381cdf0e10cSrcweir size_t nCol, nCols, nRow, nRows;
382cdf0e10cSrcweir
383cdf0e10cSrcweir // Global border geometry values ------------------------------------------
384cdf0e10cSrcweir
385cdf0e10cSrcweir /* mnLine* is the middle point inside a frame border (i.e. mnLine1 is mid X inside left border). */
386cdf0e10cSrcweir mnLine1 = mnArrowSize + FRAMESEL_GEOM_INNER + FRAMESEL_GEOM_WIDTH / 2;
387cdf0e10cSrcweir mnLine2 = mnCtrlSize / 2;
388cdf0e10cSrcweir mnLine3 = 2 * mnLine2 - mnLine1;
389cdf0e10cSrcweir
390cdf0e10cSrcweir // Frame helper array -----------------------------------------------------
391cdf0e10cSrcweir
392cdf0e10cSrcweir maArray.Initialize( mbVer ? 2 : 1, mbHor ? 2 : 1 );
393cdf0e10cSrcweir maArray.SetUseDiagDoubleClipping( true );
394cdf0e10cSrcweir
395cdf0e10cSrcweir maArray.SetXOffset( mnLine1 );
396cdf0e10cSrcweir maArray.SetAllColWidths( (mbVer ? mnLine2 : mnLine3) - mnLine1 );
397cdf0e10cSrcweir
398cdf0e10cSrcweir maArray.SetYOffset( mnLine1 );
399cdf0e10cSrcweir maArray.SetAllRowHeights( (mbHor ? mnLine2 : mnLine3) - mnLine1 );
400cdf0e10cSrcweir
401cdf0e10cSrcweir Rectangle aTLRect( maArray.GetCellRect( 0, 0 ) );
402cdf0e10cSrcweir
403cdf0e10cSrcweir // Focus polygons ---------------------------------------------------------
404cdf0e10cSrcweir
405cdf0e10cSrcweir /* Width for focus rectangles from center of frame borders. */
406cdf0e10cSrcweir mnFocusOffs = FRAMESEL_GEOM_WIDTH / 2 + 1;
407cdf0e10cSrcweir
408cdf0e10cSrcweir maLeft.AddFocusPolygon( Rectangle( mnLine1 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine1 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
409cdf0e10cSrcweir maVer.AddFocusPolygon( Rectangle( mnLine2 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine2 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
410cdf0e10cSrcweir maRight.AddFocusPolygon( Rectangle( mnLine3 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
411cdf0e10cSrcweir maTop.AddFocusPolygon( Rectangle( mnLine1 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine1 + mnFocusOffs ) );
412cdf0e10cSrcweir maHor.AddFocusPolygon( Rectangle( mnLine1 - mnFocusOffs, mnLine2 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine2 + mnFocusOffs ) );
413cdf0e10cSrcweir maBottom.AddFocusPolygon( Rectangle( mnLine1 - mnFocusOffs, mnLine3 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
414cdf0e10cSrcweir
415cdf0e10cSrcweir for( nCol = 0, nCols = maArray.GetColCount(); nCol < nCols; ++nCol )
416cdf0e10cSrcweir {
417cdf0e10cSrcweir for( nRow = 0, nRows = maArray.GetRowCount(); nRow < nRows; ++nRow )
418cdf0e10cSrcweir {
419cdf0e10cSrcweir Rectangle aRect( maArray.GetCellRect( nCol, nRow ) );
420cdf0e10cSrcweir long nDiagFocusOffsX = frame::GetTLDiagOffset( -mnFocusOffs, mnFocusOffs, maArray.GetHorDiagAngle( nCol, nRow ) );
421cdf0e10cSrcweir long nDiagFocusOffsY = frame::GetTLDiagOffset( -mnFocusOffs, mnFocusOffs, maArray.GetVerDiagAngle( nCol, nRow ) );
422cdf0e10cSrcweir
423cdf0e10cSrcweir std::vector< Point > aFocusVec;
424cdf0e10cSrcweir aFocusVec.push_back( Point( aRect.Left() - mnFocusOffs, aRect.Top() + nDiagFocusOffsY ) );
425cdf0e10cSrcweir aFocusVec.push_back( Point( aRect.Left() - mnFocusOffs, aRect.Top() - mnFocusOffs ) );
426cdf0e10cSrcweir aFocusVec.push_back( Point( aRect.Left() + nDiagFocusOffsX, aRect.Top() - mnFocusOffs ) );
427cdf0e10cSrcweir aFocusVec.push_back( Point( aRect.Right() + mnFocusOffs, aRect.Bottom() - nDiagFocusOffsY ) );
428cdf0e10cSrcweir aFocusVec.push_back( Point( aRect.Right() + mnFocusOffs, aRect.Bottom() + mnFocusOffs ) );
429cdf0e10cSrcweir aFocusVec.push_back( Point( aRect.Right() - nDiagFocusOffsX, aRect.Bottom() + mnFocusOffs ) );
430cdf0e10cSrcweir maTLBR.AddFocusPolygon( Polygon( static_cast< sal_uInt16 >( aFocusVec.size() ), &aFocusVec[ 0 ] ) );
431cdf0e10cSrcweir
432cdf0e10cSrcweir aFocusVec.clear();
433cdf0e10cSrcweir aFocusVec.push_back( Point( aRect.Right() + mnFocusOffs, aRect.Top() + nDiagFocusOffsY ) );
434cdf0e10cSrcweir aFocusVec.push_back( Point( aRect.Right() + mnFocusOffs, aRect.Top() - mnFocusOffs ) );
435cdf0e10cSrcweir aFocusVec.push_back( Point( aRect.Right() - nDiagFocusOffsX, aRect.Top() - mnFocusOffs ) );
436cdf0e10cSrcweir aFocusVec.push_back( Point( aRect.Left() - mnFocusOffs, aRect.Bottom() - nDiagFocusOffsY ) );
437cdf0e10cSrcweir aFocusVec.push_back( Point( aRect.Left() - mnFocusOffs, aRect.Bottom() + mnFocusOffs ) );
438cdf0e10cSrcweir aFocusVec.push_back( Point( aRect.Left() + nDiagFocusOffsX, aRect.Bottom() + mnFocusOffs ) );
439cdf0e10cSrcweir maBLTR.AddFocusPolygon( Polygon( static_cast< sal_uInt16 >( aFocusVec.size() ), &aFocusVec[ 0 ] ) );
440cdf0e10cSrcweir }
441cdf0e10cSrcweir }
442cdf0e10cSrcweir
443cdf0e10cSrcweir // Click areas ------------------------------------------------------------
444cdf0e10cSrcweir
445cdf0e10cSrcweir for( FrameBorderIter aIt( maAllBorders ); aIt.Is(); ++aIt )
446cdf0e10cSrcweir (*aIt)->ClearClickArea();
447cdf0e10cSrcweir
448cdf0e10cSrcweir /* Additional space for click area: is added to the space available to draw
449cdf0e10cSrcweir the frame borders. For instance left frame border:
450cdf0e10cSrcweir - To left, top, and bottom always big additional space (outer area).
451cdf0e10cSrcweir - To right: Dependent on existence of inner vertical frame border
452cdf0e10cSrcweir (if enabled, use less space).
453cdf0e10cSrcweir */
454cdf0e10cSrcweir long nClO = FRAMESEL_GEOM_WIDTH / 2 + FRAMESEL_GEOM_ADD_CLICK_OUTER;
455cdf0e10cSrcweir long nClI = (mbTLBR && mbBLTR) ? (FRAMESEL_GEOM_WIDTH / 2 + FRAMESEL_GEOM_ADD_CLICK_INNER) : nClO;
456cdf0e10cSrcweir long nClH = mbHor ? nClI : nClO; // additional space dependent of horizontal inner border
457cdf0e10cSrcweir long nClV = mbVer ? nClI : nClO; // additional space dependent of vertical inner border
458cdf0e10cSrcweir
459cdf0e10cSrcweir maLeft.AddClickRect( Rectangle( mnLine1 - nClO, mnLine1 - nClO, mnLine1 + nClV, mnLine3 + nClO ) );
460cdf0e10cSrcweir maVer.AddClickRect( Rectangle( mnLine2 - nClI, mnLine1 - nClO, mnLine2 + nClI, mnLine3 + nClO ) );
461cdf0e10cSrcweir maRight.AddClickRect( Rectangle( mnLine3 - nClV, mnLine1 - nClO, mnLine3 + nClO, mnLine3 + nClO ) );
462cdf0e10cSrcweir maTop.AddClickRect( Rectangle( mnLine1 - nClO, mnLine1 - nClO, mnLine3 + nClO, mnLine1 + nClH ) );
463cdf0e10cSrcweir maHor.AddClickRect( Rectangle( mnLine1 - nClO, mnLine2 - nClI, mnLine3 + nClO, mnLine2 + nClI ) );
464cdf0e10cSrcweir maBottom.AddClickRect( Rectangle( mnLine1 - nClO, mnLine3 - nClH, mnLine3 + nClO, mnLine3 + nClO ) );
465cdf0e10cSrcweir
466cdf0e10cSrcweir /* Diagonal frame borders use the remaining space between outer and inner frame borders. */
467cdf0e10cSrcweir if( mbTLBR || mbBLTR )
468cdf0e10cSrcweir {
469cdf0e10cSrcweir for( nCol = 0, nCols = maArray.GetColCount(); nCol < nCols; ++nCol )
470cdf0e10cSrcweir {
471cdf0e10cSrcweir for( nRow = 0, nRows = maArray.GetRowCount(); nRow < nRows; ++nRow )
472cdf0e10cSrcweir {
473*85f16e68SMatthias Seidel // the usable area between horizontal/vertical frame borders of current quadrant
474cdf0e10cSrcweir Rectangle aRect( maArray.GetCellRect( nCol, nRow ) );
475cdf0e10cSrcweir aRect.Left() += nClV + 1;
476cdf0e10cSrcweir aRect.Right() -= nClV + 1;
477cdf0e10cSrcweir aRect.Top() += nClH + 1;
478cdf0e10cSrcweir aRect.Bottom() -= nClH + 1;
479cdf0e10cSrcweir
480cdf0e10cSrcweir /* Both diagonal frame borders enabled. */
481cdf0e10cSrcweir if( mbTLBR && mbBLTR )
482cdf0e10cSrcweir {
483cdf0e10cSrcweir // single areas
484cdf0e10cSrcweir Point aMid( aRect.Center() );
485cdf0e10cSrcweir maTLBR.AddClickRect( Rectangle( aRect.TopLeft(), aMid ) );
486cdf0e10cSrcweir maTLBR.AddClickRect( Rectangle( aMid + Point( 1, 1 ), aRect.BottomRight() ) );
487cdf0e10cSrcweir maBLTR.AddClickRect( Rectangle( aRect.Left(), aMid.Y() + 1, aMid.X(), aRect.Bottom() ) );
488cdf0e10cSrcweir maBLTR.AddClickRect( Rectangle( aMid.X() + 1, aRect.Top(), aRect.Right(), aMid.Y() ) );
489cdf0e10cSrcweir // centered rectangle for both frame borders
490cdf0e10cSrcweir Rectangle aMidRect( aRect.TopLeft(), Size( aRect.GetWidth() / 3, aRect.GetHeight() / 3 ) );
491cdf0e10cSrcweir aMidRect.Move( (aRect.GetWidth() - aMidRect.GetWidth()) / 2, (aRect.GetHeight() - aMidRect.GetHeight()) / 2 );
492cdf0e10cSrcweir maTLBR.AddClickRect( aMidRect );
493cdf0e10cSrcweir maBLTR.AddClickRect( aMidRect );
494cdf0e10cSrcweir }
495cdf0e10cSrcweir /* One of the diagonal frame borders enabled - use entire rectangle. */
496cdf0e10cSrcweir else if( mbTLBR && !mbBLTR ) // top-left to bottom-right only
497cdf0e10cSrcweir maTLBR.AddClickRect( aRect );
498cdf0e10cSrcweir else if( !mbTLBR && mbBLTR ) // bottom-left to top-right only
499cdf0e10cSrcweir maBLTR.AddClickRect( aRect );
500cdf0e10cSrcweir }
501cdf0e10cSrcweir }
502cdf0e10cSrcweir }
503cdf0e10cSrcweir }
504cdf0e10cSrcweir
InitVirtualDevice()505cdf0e10cSrcweir void FrameSelectorImpl::InitVirtualDevice()
506cdf0e10cSrcweir {
507cdf0e10cSrcweir // initialize resources
508cdf0e10cSrcweir InitColors();
509cdf0e10cSrcweir InitArrowImageList();
510cdf0e10cSrcweir
511cdf0e10cSrcweir // initialize geometry
512cdf0e10cSrcweir InitGlobalGeometry();
513cdf0e10cSrcweir InitBorderGeometry();
514cdf0e10cSrcweir
515cdf0e10cSrcweir // correct background around the used area
516cdf0e10cSrcweir mrFrameSel.SetBackground( Wallpaper( maBackCol ) );
517cdf0e10cSrcweir DoInvalidate( true );
518cdf0e10cSrcweir }
519cdf0e10cSrcweir
520cdf0e10cSrcweir // frame border access --------------------------------------------------------
521cdf0e10cSrcweir
GetBorder(FrameBorderType eBorder) const522cdf0e10cSrcweir const FrameBorder& FrameSelectorImpl::GetBorder( FrameBorderType eBorder ) const
523cdf0e10cSrcweir {
524cdf0e10cSrcweir size_t nIndex = GetIndexFromFrameBorderType( eBorder );
525cdf0e10cSrcweir if( nIndex < maAllBorders.size() )
526cdf0e10cSrcweir return *maAllBorders[ nIndex ];
527cdf0e10cSrcweir DBG_ERRORFILE( "svx::FrameSelectorImpl::GetBorder - unknown border type" );
528cdf0e10cSrcweir return maTop;
529cdf0e10cSrcweir }
530cdf0e10cSrcweir
GetBorderAccess(FrameBorderType eBorder)531cdf0e10cSrcweir FrameBorder& FrameSelectorImpl::GetBorderAccess( FrameBorderType eBorder )
532cdf0e10cSrcweir {
533cdf0e10cSrcweir return const_cast< FrameBorder& >( GetBorder( eBorder ) );
534cdf0e10cSrcweir }
535cdf0e10cSrcweir
536cdf0e10cSrcweir // drawing --------------------------------------------------------------------
537cdf0e10cSrcweir
DrawBackground()538cdf0e10cSrcweir void FrameSelectorImpl::DrawBackground()
539cdf0e10cSrcweir {
540cdf0e10cSrcweir // clear the area
541cdf0e10cSrcweir maVirDev.SetLineColor();
542cdf0e10cSrcweir maVirDev.SetFillColor( maBackCol );
543cdf0e10cSrcweir maVirDev.DrawRect( Rectangle( Point( 0, 0 ), maVirDev.GetOutputSizePixel() ) );
544cdf0e10cSrcweir
545cdf0e10cSrcweir // draw the inner gray (or whatever color) rectangle
546cdf0e10cSrcweir maVirDev.SetLineColor();
547cdf0e10cSrcweir maVirDev.SetFillColor( maMarkCol );
548cdf0e10cSrcweir maVirDev.DrawRect( Rectangle(
549cdf0e10cSrcweir mnLine1 - mnFocusOffs, mnLine1 - mnFocusOffs, mnLine3 + mnFocusOffs, mnLine3 + mnFocusOffs ) );
550cdf0e10cSrcweir
551cdf0e10cSrcweir // draw the white space for enabled frame borders
552cdf0e10cSrcweir PolyPolygon aPPoly;
553cdf0e10cSrcweir for( FrameBorderCIter aIt( maEnabBorders ); aIt.Is(); ++aIt )
554cdf0e10cSrcweir (*aIt)->MergeFocusToPolyPolygon( aPPoly );
555cdf0e10cSrcweir aPPoly.Optimize( POLY_OPTIMIZE_CLOSE );
556cdf0e10cSrcweir maVirDev.SetLineColor( maBackCol );
557cdf0e10cSrcweir maVirDev.SetFillColor( maBackCol );
558cdf0e10cSrcweir maVirDev.DrawPolyPolygon( aPPoly );
559cdf0e10cSrcweir }
560cdf0e10cSrcweir
DrawArrows(const FrameBorder & rBorder)561cdf0e10cSrcweir void FrameSelectorImpl::DrawArrows( const FrameBorder& rBorder )
562cdf0e10cSrcweir {
563cdf0e10cSrcweir DBG_ASSERT( rBorder.IsEnabled(), "svx::FrameSelectorImpl::DrawArrows - access to disabled border" );
564cdf0e10cSrcweir
565cdf0e10cSrcweir long nLinePos = 0;
566cdf0e10cSrcweir switch( rBorder.GetType() )
567cdf0e10cSrcweir {
568cdf0e10cSrcweir case FRAMEBORDER_LEFT:
569cdf0e10cSrcweir case FRAMEBORDER_TOP: nLinePos = mnLine1; break;
570cdf0e10cSrcweir case FRAMEBORDER_VER:
571cdf0e10cSrcweir case FRAMEBORDER_HOR: nLinePos = mnLine2; break;
572cdf0e10cSrcweir case FRAMEBORDER_RIGHT:
573cdf0e10cSrcweir case FRAMEBORDER_BOTTOM: nLinePos = mnLine3; break;
574cdf0e10cSrcweir default: ; //prevent warning
575cdf0e10cSrcweir }
576cdf0e10cSrcweir nLinePos -= mnArrowSize / 2;
577cdf0e10cSrcweir
578cdf0e10cSrcweir long nTLPos = 0;
579cdf0e10cSrcweir long nBRPos = mnCtrlSize - mnArrowSize;
580cdf0e10cSrcweir Point aPos1, aPos2;
581cdf0e10cSrcweir sal_uInt16 nImgId1 = 0, nImgId2 = 0;
582cdf0e10cSrcweir switch( rBorder.GetType() )
583cdf0e10cSrcweir {
584cdf0e10cSrcweir case FRAMEBORDER_LEFT:
585cdf0e10cSrcweir case FRAMEBORDER_RIGHT:
586cdf0e10cSrcweir case FRAMEBORDER_VER:
587cdf0e10cSrcweir aPos1 = Point( nLinePos, nTLPos ); nImgId1 = 1;
588cdf0e10cSrcweir aPos2 = Point( nLinePos, nBRPos ); nImgId2 = 2;
589cdf0e10cSrcweir break;
590cdf0e10cSrcweir
591cdf0e10cSrcweir case FRAMEBORDER_TOP:
592cdf0e10cSrcweir case FRAMEBORDER_BOTTOM:
593cdf0e10cSrcweir case FRAMEBORDER_HOR:
594cdf0e10cSrcweir aPos1 = Point( nTLPos, nLinePos ); nImgId1 = 3;
595cdf0e10cSrcweir aPos2 = Point( nBRPos, nLinePos ); nImgId2 = 4;
596cdf0e10cSrcweir break;
597cdf0e10cSrcweir
598cdf0e10cSrcweir case FRAMEBORDER_TLBR:
599cdf0e10cSrcweir aPos1 = Point( nTLPos, nTLPos ); nImgId1 = 5;
600cdf0e10cSrcweir aPos2 = Point( nBRPos, nBRPos ); nImgId2 = 6;
601cdf0e10cSrcweir break;
602cdf0e10cSrcweir case FRAMEBORDER_BLTR:
603cdf0e10cSrcweir aPos1 = Point( nTLPos, nBRPos ); nImgId1 = 7;
604cdf0e10cSrcweir aPos2 = Point( nBRPos, nTLPos ); nImgId2 = 8;
605cdf0e10cSrcweir break;
606cdf0e10cSrcweir default: ; //prevent warning
607cdf0e10cSrcweir }
608cdf0e10cSrcweir
609cdf0e10cSrcweir // Arrow or marker? Do not draw arrows into disabled control.
610cdf0e10cSrcweir sal_uInt16 nSelectAdd = (mrFrameSel.IsEnabled() && rBorder.IsSelected()) ? 0 : 8;
611cdf0e10cSrcweir maVirDev.DrawImage( aPos1, maILArrows.GetImage( nImgId1 + nSelectAdd ) );
612cdf0e10cSrcweir maVirDev.DrawImage( aPos2, maILArrows.GetImage( nImgId2 + nSelectAdd ) );
613cdf0e10cSrcweir }
614cdf0e10cSrcweir
DrawAllArrows()615cdf0e10cSrcweir void FrameSelectorImpl::DrawAllArrows()
616cdf0e10cSrcweir {
617cdf0e10cSrcweir for( FrameBorderCIter aIt( maEnabBorders ); aIt.Is(); ++aIt )
618cdf0e10cSrcweir DrawArrows( **aIt );
619cdf0e10cSrcweir }
620cdf0e10cSrcweir
GetDrawLineColor(const Color & rColor) const621cdf0e10cSrcweir Color FrameSelectorImpl::GetDrawLineColor( const Color& rColor ) const
622cdf0e10cSrcweir {
623cdf0e10cSrcweir Color aColor( mbHCMode ? maHCLineCol : rColor );
624cdf0e10cSrcweir if( aColor == maBackCol )
625cdf0e10cSrcweir aColor.Invert();
626cdf0e10cSrcweir return aColor;
627cdf0e10cSrcweir }
628cdf0e10cSrcweir
DrawAllFrameBorders()629cdf0e10cSrcweir void FrameSelectorImpl::DrawAllFrameBorders()
630cdf0e10cSrcweir {
631cdf0e10cSrcweir // Translate core colors to current UI colors (regards current background and HC mode).
632cdf0e10cSrcweir for( FrameBorderIter aIt( maEnabBorders ); aIt.Is(); ++aIt )
633cdf0e10cSrcweir {
634cdf0e10cSrcweir Color aCoreColor = ((*aIt)->GetState() == FRAMESTATE_DONTCARE) ? maMarkCol : (*aIt)->GetCoreStyle().GetColor();
635cdf0e10cSrcweir (*aIt)->SetUIColor( GetDrawLineColor( aCoreColor ) );
636cdf0e10cSrcweir }
637cdf0e10cSrcweir
638cdf0e10cSrcweir // Copy all frame border styles to the helper array
639cdf0e10cSrcweir maArray.SetColumnStyleLeft( 0, maLeft.GetUIStyle() );
640cdf0e10cSrcweir if( mbVer ) maArray.SetColumnStyleLeft( 1, maVer.GetUIStyle() );
641cdf0e10cSrcweir maArray.SetColumnStyleRight( mbVer ? 1 : 0, maRight.GetUIStyle() );
642cdf0e10cSrcweir
643cdf0e10cSrcweir maArray.SetRowStyleTop( 0, maTop.GetUIStyle() );
644cdf0e10cSrcweir if( mbHor ) maArray.SetRowStyleTop( 1, maHor.GetUIStyle() );
645cdf0e10cSrcweir maArray.SetRowStyleBottom( mbHor ? 1 : 0, maBottom.GetUIStyle() );
646cdf0e10cSrcweir
647cdf0e10cSrcweir for( size_t nCol = 0; nCol < maArray.GetColCount(); ++nCol )
648cdf0e10cSrcweir for( size_t nRow = 0; nRow < maArray.GetRowCount(); ++nRow )
649cdf0e10cSrcweir maArray.SetCellStyleDiag( nCol, nRow, maTLBR.GetUIStyle(), maBLTR.GetUIStyle() );
650cdf0e10cSrcweir
651cdf0e10cSrcweir // Let the helper array draw itself
652cdf0e10cSrcweir maArray.DrawArray( maVirDev );
653cdf0e10cSrcweir }
654cdf0e10cSrcweir
DrawVirtualDevice()655cdf0e10cSrcweir void FrameSelectorImpl::DrawVirtualDevice()
656cdf0e10cSrcweir {
657cdf0e10cSrcweir DrawBackground();
658cdf0e10cSrcweir DrawAllArrows();
659cdf0e10cSrcweir DrawAllFrameBorders();
660cdf0e10cSrcweir mbFullRepaint = false;
661cdf0e10cSrcweir }
662cdf0e10cSrcweir
CopyVirDevToControl()663cdf0e10cSrcweir void FrameSelectorImpl::CopyVirDevToControl()
664cdf0e10cSrcweir {
665cdf0e10cSrcweir if( mbFullRepaint )
666cdf0e10cSrcweir DrawVirtualDevice();
667cdf0e10cSrcweir mrFrameSel.DrawBitmap( maVirDevPos, maVirDev.GetBitmap( Point( 0, 0 ), maVirDev.GetOutputSizePixel() ) );
668cdf0e10cSrcweir }
669cdf0e10cSrcweir
DrawAllTrackingRects()670cdf0e10cSrcweir void FrameSelectorImpl::DrawAllTrackingRects()
671cdf0e10cSrcweir {
672cdf0e10cSrcweir PolyPolygon aPPoly;
673cdf0e10cSrcweir if( mrFrameSel.IsAnyBorderSelected() )
674cdf0e10cSrcweir {
675cdf0e10cSrcweir for( SelFrameBorderCIter aIt( maEnabBorders ); aIt.Is(); ++aIt )
676cdf0e10cSrcweir (*aIt)->MergeFocusToPolyPolygon( aPPoly );
677cdf0e10cSrcweir aPPoly.Move( maVirDevPos.X(), maVirDevPos.Y() );
678cdf0e10cSrcweir }
679cdf0e10cSrcweir else
680cdf0e10cSrcweir // no frame border selected -> draw tracking rectangle around entire control
681cdf0e10cSrcweir aPPoly.Insert( Polygon( Rectangle( maVirDevPos, maVirDev.GetOutputSizePixel() ) ) );
682cdf0e10cSrcweir
683cdf0e10cSrcweir aPPoly.Optimize( POLY_OPTIMIZE_CLOSE );
684cdf0e10cSrcweir for( sal_uInt16 nIdx = 0, nCount = aPPoly.Count(); nIdx < nCount; ++nIdx )
685cdf0e10cSrcweir mrFrameSel.InvertTracking( aPPoly.GetObject( nIdx ), SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
686cdf0e10cSrcweir }
687cdf0e10cSrcweir
GetDevPosFromMousePos(const Point & rMousePos) const688cdf0e10cSrcweir Point FrameSelectorImpl::GetDevPosFromMousePos( const Point& rMousePos ) const
689cdf0e10cSrcweir {
690cdf0e10cSrcweir return rMousePos - maVirDevPos;
691cdf0e10cSrcweir }
692cdf0e10cSrcweir
DoInvalidate(bool bFullRepaint)693cdf0e10cSrcweir void FrameSelectorImpl::DoInvalidate( bool bFullRepaint )
694cdf0e10cSrcweir {
695cdf0e10cSrcweir mbFullRepaint |= bFullRepaint;
696cdf0e10cSrcweir mrFrameSel.Invalidate( INVALIDATE_NOERASE );
697cdf0e10cSrcweir }
698cdf0e10cSrcweir
699cdf0e10cSrcweir // frame border state and style -----------------------------------------------
700cdf0e10cSrcweir
SetBorderState(FrameBorder & rBorder,FrameBorderState eState)701cdf0e10cSrcweir void FrameSelectorImpl::SetBorderState( FrameBorder& rBorder, FrameBorderState eState )
702cdf0e10cSrcweir {
703cdf0e10cSrcweir DBG_ASSERT( rBorder.IsEnabled(), "svx::FrameSelectorImpl::SetBorderState - access to disabled border" );
7049b8096d0SSteve Yin Any aOld;
7059b8096d0SSteve Yin Any aNew;
7069b8096d0SSteve Yin Any& rMod = eState == FRAMESTATE_SHOW ? aNew : aOld;
7079b8096d0SSteve Yin rMod <<= AccessibleStateType::CHECKED;
7089b8096d0SSteve Yin Reference< XAccessible > xRet;
7099b8096d0SSteve Yin size_t nVecIdx = static_cast< size_t >( rBorder.GetType() );
7109b8096d0SSteve Yin if( GetBorder(rBorder.GetType()).IsEnabled() && (1 <= nVecIdx) && (nVecIdx <= maChildVec.size()) )
7119b8096d0SSteve Yin xRet = mxChildVec[ --nVecIdx ];
7129b8096d0SSteve Yin a11y::AccFrameSelector* pFrameSelector = static_cast<a11y::AccFrameSelector*>(xRet.get());
7139b8096d0SSteve Yin
714cdf0e10cSrcweir if( eState == FRAMESTATE_SHOW )
715cdf0e10cSrcweir SetBorderCoreStyle( rBorder, &maCurrStyle );
716cdf0e10cSrcweir else
717cdf0e10cSrcweir rBorder.SetState( eState );
7189b8096d0SSteve Yin if (pFrameSelector)
7199b8096d0SSteve Yin pFrameSelector->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOld, aNew );
720cdf0e10cSrcweir DoInvalidate( true );
721cdf0e10cSrcweir }
722cdf0e10cSrcweir
SetBorderCoreStyle(FrameBorder & rBorder,const SvxBorderLine * pStyle)723cdf0e10cSrcweir void FrameSelectorImpl::SetBorderCoreStyle( FrameBorder& rBorder, const SvxBorderLine* pStyle )
724cdf0e10cSrcweir {
725cdf0e10cSrcweir DBG_ASSERT( rBorder.IsEnabled(), "svx::FrameSelectorImpl::SetBorderCoreStyle - access to disabled border" );
726cdf0e10cSrcweir rBorder.SetCoreStyle( pStyle );
727cdf0e10cSrcweir DoInvalidate( true );
728cdf0e10cSrcweir }
729cdf0e10cSrcweir
ToggleBorderState(FrameBorder & rBorder)730cdf0e10cSrcweir void FrameSelectorImpl::ToggleBorderState( FrameBorder& rBorder )
731cdf0e10cSrcweir {
732cdf0e10cSrcweir bool bDontCare = mrFrameSel.SupportsDontCareState();
733cdf0e10cSrcweir switch( rBorder.GetState() )
734cdf0e10cSrcweir {
735cdf0e10cSrcweir // same order as tristate check box: visible -> don't care -> hidden
736cdf0e10cSrcweir case FRAMESTATE_SHOW:
737cdf0e10cSrcweir SetBorderState( rBorder, bDontCare ? FRAMESTATE_DONTCARE : FRAMESTATE_HIDE );
738cdf0e10cSrcweir break;
739cdf0e10cSrcweir case FRAMESTATE_HIDE:
740cdf0e10cSrcweir SetBorderState( rBorder, FRAMESTATE_SHOW );
741cdf0e10cSrcweir break;
742cdf0e10cSrcweir case FRAMESTATE_DONTCARE:
743cdf0e10cSrcweir SetBorderState( rBorder, FRAMESTATE_HIDE );
744cdf0e10cSrcweir break;
745cdf0e10cSrcweir }
746cdf0e10cSrcweir }
747cdf0e10cSrcweir
748cdf0e10cSrcweir // frame border selection -----------------------------------------------------
749cdf0e10cSrcweir
SelectBorder(FrameBorder & rBorder,bool bSelect)750cdf0e10cSrcweir void FrameSelectorImpl::SelectBorder( FrameBorder& rBorder, bool bSelect )
751cdf0e10cSrcweir {
752cdf0e10cSrcweir DBG_ASSERT( rBorder.IsEnabled(), "svx::FrameSelectorImpl::SelectBorder - access to disabled border" );
753cdf0e10cSrcweir rBorder.Select( bSelect );
754cdf0e10cSrcweir DrawArrows( rBorder );
755cdf0e10cSrcweir DoInvalidate( false );
756cdf0e10cSrcweir maSelectHdl.Call( this );
757cdf0e10cSrcweir }
758cdf0e10cSrcweir
SilentGrabFocus()759cdf0e10cSrcweir void FrameSelectorImpl::SilentGrabFocus()
760cdf0e10cSrcweir {
761cdf0e10cSrcweir bool bOldAuto = mbAutoSelect;
762cdf0e10cSrcweir mbAutoSelect = false;
763cdf0e10cSrcweir mrFrameSel.GrabFocus();
764cdf0e10cSrcweir mbAutoSelect = bOldAuto;
765cdf0e10cSrcweir }
766cdf0e10cSrcweir
SelectedBordersEqual() const767cdf0e10cSrcweir bool FrameSelectorImpl::SelectedBordersEqual() const
768cdf0e10cSrcweir {
769cdf0e10cSrcweir bool bEqual = true;
770cdf0e10cSrcweir SelFrameBorderCIter aIt( maEnabBorders );
771cdf0e10cSrcweir if( aIt.Is() )
772cdf0e10cSrcweir {
773cdf0e10cSrcweir const SvxBorderLine& rFirstStyle = (*aIt)->GetCoreStyle();
774cdf0e10cSrcweir for( ++aIt; bEqual && aIt.Is(); ++aIt )
775cdf0e10cSrcweir bEqual = ((*aIt)->GetCoreStyle() == rFirstStyle);
776cdf0e10cSrcweir }
777cdf0e10cSrcweir return bEqual;
778cdf0e10cSrcweir }
779cdf0e10cSrcweir
780cdf0e10cSrcweir // ============================================================================
781cdf0e10cSrcweir // FrameSelector
782cdf0e10cSrcweir // ============================================================================
783cdf0e10cSrcweir
FrameSelector(Window * pParent,const ResId & rResId)784cdf0e10cSrcweir FrameSelector::FrameSelector( Window* pParent, const ResId& rResId ) :
785cdf0e10cSrcweir Control( pParent, rResId )
786cdf0e10cSrcweir {
787cdf0e10cSrcweir // not in c'tor init list (avoid warning about usage of *this)
788cdf0e10cSrcweir mxImpl.reset( new FrameSelectorImpl( *this ) );
789cdf0e10cSrcweir EnableRTL( false ); // #107808# don't mirror the mouse handling
790cdf0e10cSrcweir }
791cdf0e10cSrcweir
~FrameSelector()792cdf0e10cSrcweir FrameSelector::~FrameSelector()
793cdf0e10cSrcweir {
794cdf0e10cSrcweir }
795cdf0e10cSrcweir
Initialize(FrameSelFlags nFlags)796cdf0e10cSrcweir void FrameSelector::Initialize( FrameSelFlags nFlags )
797cdf0e10cSrcweir {
798cdf0e10cSrcweir mxImpl->Initialize( nFlags );
799cdf0e10cSrcweir Show();
800cdf0e10cSrcweir }
801cdf0e10cSrcweir
802cdf0e10cSrcweir // enabled frame borders ------------------------------------------------------
803cdf0e10cSrcweir
IsBorderEnabled(FrameBorderType eBorder) const804cdf0e10cSrcweir bool FrameSelector::IsBorderEnabled( FrameBorderType eBorder ) const
805cdf0e10cSrcweir {
806cdf0e10cSrcweir return mxImpl->GetBorder( eBorder ).IsEnabled();
807cdf0e10cSrcweir }
808cdf0e10cSrcweir
GetEnabledBorderCount() const809cdf0e10cSrcweir sal_Int32 FrameSelector::GetEnabledBorderCount() const
810cdf0e10cSrcweir {
811cdf0e10cSrcweir return static_cast< sal_Int32 >( mxImpl->maEnabBorders.size() );
812cdf0e10cSrcweir }
813cdf0e10cSrcweir
GetEnabledBorderType(sal_Int32 nIndex) const814cdf0e10cSrcweir FrameBorderType FrameSelector::GetEnabledBorderType( sal_Int32 nIndex ) const
815cdf0e10cSrcweir {
816cdf0e10cSrcweir FrameBorderType eBorder = FRAMEBORDER_NONE;
817cdf0e10cSrcweir if( nIndex >= 0 )
818cdf0e10cSrcweir {
819cdf0e10cSrcweir size_t nVecIdx = static_cast< size_t >( nIndex );
820cdf0e10cSrcweir if( nVecIdx < mxImpl->maEnabBorders.size() )
821cdf0e10cSrcweir eBorder = mxImpl->maEnabBorders[ nVecIdx ]->GetType();
822cdf0e10cSrcweir }
823cdf0e10cSrcweir return eBorder;
824cdf0e10cSrcweir }
825cdf0e10cSrcweir
GetEnabledBorderIndex(FrameBorderType eBorder) const826cdf0e10cSrcweir sal_Int32 FrameSelector::GetEnabledBorderIndex( FrameBorderType eBorder ) const
827cdf0e10cSrcweir {
828cdf0e10cSrcweir sal_Int32 nIndex = 0;
829cdf0e10cSrcweir for( FrameBorderCIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt, ++nIndex )
830cdf0e10cSrcweir if( (*aIt)->GetType() == eBorder )
831cdf0e10cSrcweir return nIndex;
832cdf0e10cSrcweir return -1;
833cdf0e10cSrcweir }
834cdf0e10cSrcweir
835cdf0e10cSrcweir // frame border state and style -----------------------------------------------
836cdf0e10cSrcweir
SupportsDontCareState() const837cdf0e10cSrcweir bool FrameSelector::SupportsDontCareState() const
838cdf0e10cSrcweir {
839cdf0e10cSrcweir return (mxImpl->mnFlags & FRAMESEL_DONTCARE) != 0;
840cdf0e10cSrcweir }
841cdf0e10cSrcweir
GetFrameBorderState(FrameBorderType eBorder) const842cdf0e10cSrcweir FrameBorderState FrameSelector::GetFrameBorderState( FrameBorderType eBorder ) const
843cdf0e10cSrcweir {
844cdf0e10cSrcweir return mxImpl->GetBorder( eBorder ).GetState();
845cdf0e10cSrcweir }
846cdf0e10cSrcweir
GetFrameBorderStyle(FrameBorderType eBorder) const847cdf0e10cSrcweir const SvxBorderLine* FrameSelector::GetFrameBorderStyle( FrameBorderType eBorder ) const
848cdf0e10cSrcweir {
849cdf0e10cSrcweir const SvxBorderLine& rStyle = mxImpl->GetBorder( eBorder ).GetCoreStyle();
850cdf0e10cSrcweir // rest of the world uses null pointer for invisible frame border
851cdf0e10cSrcweir return rStyle.GetOutWidth() ? &rStyle : 0;
852cdf0e10cSrcweir }
853cdf0e10cSrcweir
ShowBorder(FrameBorderType eBorder,const SvxBorderLine * pStyle)854cdf0e10cSrcweir void FrameSelector::ShowBorder( FrameBorderType eBorder, const SvxBorderLine* pStyle )
855cdf0e10cSrcweir {
856cdf0e10cSrcweir mxImpl->SetBorderCoreStyle( mxImpl->GetBorderAccess( eBorder ), pStyle );
857cdf0e10cSrcweir }
858cdf0e10cSrcweir
SetBorderDontCare(FrameBorderType eBorder)859cdf0e10cSrcweir void FrameSelector::SetBorderDontCare( FrameBorderType eBorder )
860cdf0e10cSrcweir {
861cdf0e10cSrcweir mxImpl->SetBorderState( mxImpl->GetBorderAccess( eBorder ), FRAMESTATE_DONTCARE );
862cdf0e10cSrcweir }
863cdf0e10cSrcweir
IsAnyBorderVisible() const864cdf0e10cSrcweir bool FrameSelector::IsAnyBorderVisible() const
865cdf0e10cSrcweir {
866cdf0e10cSrcweir bool bIsSet = false;
867cdf0e10cSrcweir for( FrameBorderCIter aIt( mxImpl->maEnabBorders ); !bIsSet && aIt.Is(); ++aIt )
868cdf0e10cSrcweir bIsSet = ((*aIt)->GetState() == FRAMESTATE_SHOW);
869cdf0e10cSrcweir return bIsSet;
870cdf0e10cSrcweir }
871cdf0e10cSrcweir
HideAllBorders()872cdf0e10cSrcweir void FrameSelector::HideAllBorders()
873cdf0e10cSrcweir {
874cdf0e10cSrcweir for( FrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
875cdf0e10cSrcweir mxImpl->SetBorderState( **aIt, FRAMESTATE_HIDE );
876cdf0e10cSrcweir }
877cdf0e10cSrcweir
GetVisibleWidth(sal_uInt16 & rnPrim,sal_uInt16 & rnDist,sal_uInt16 & rnSecn) const878cdf0e10cSrcweir bool FrameSelector::GetVisibleWidth( sal_uInt16& rnPrim, sal_uInt16& rnDist, sal_uInt16& rnSecn ) const
879cdf0e10cSrcweir {
880cdf0e10cSrcweir VisFrameBorderCIter aIt( mxImpl->maEnabBorders );
881cdf0e10cSrcweir if( !aIt.Is() )
882cdf0e10cSrcweir return false;
883cdf0e10cSrcweir
884cdf0e10cSrcweir const SvxBorderLine& rStyle = (*aIt)->GetCoreStyle();
885cdf0e10cSrcweir bool bFound = true;
886cdf0e10cSrcweir for( ++aIt; bFound && aIt.Is(); ++aIt )
887cdf0e10cSrcweir bFound =
888cdf0e10cSrcweir (rStyle.GetOutWidth() == (*aIt)->GetCoreStyle().GetOutWidth()) &&
889cdf0e10cSrcweir (rStyle.GetDistance() == (*aIt)->GetCoreStyle().GetDistance()) &&
890cdf0e10cSrcweir (rStyle.GetInWidth() == (*aIt)->GetCoreStyle().GetInWidth());
891cdf0e10cSrcweir
892cdf0e10cSrcweir if( bFound )
893cdf0e10cSrcweir {
894cdf0e10cSrcweir rnPrim = rStyle.GetOutWidth();
895cdf0e10cSrcweir rnDist = rStyle.GetDistance();
896cdf0e10cSrcweir rnSecn = rStyle.GetInWidth();
897cdf0e10cSrcweir }
898cdf0e10cSrcweir return bFound;
899cdf0e10cSrcweir }
900cdf0e10cSrcweir
GetVisibleColor(Color & rColor) const901cdf0e10cSrcweir bool FrameSelector::GetVisibleColor( Color& rColor ) const
902cdf0e10cSrcweir {
903cdf0e10cSrcweir VisFrameBorderCIter aIt( mxImpl->maEnabBorders );
904cdf0e10cSrcweir if( !aIt.Is() )
905cdf0e10cSrcweir return false;
906cdf0e10cSrcweir
907cdf0e10cSrcweir const SvxBorderLine& rStyle = (*aIt)->GetCoreStyle();
908cdf0e10cSrcweir bool bFound = true;
909cdf0e10cSrcweir for( ++aIt; bFound && aIt.Is(); ++aIt )
910cdf0e10cSrcweir bFound = (rStyle.GetColor() == (*aIt)->GetCoreStyle().GetColor());
911cdf0e10cSrcweir
912cdf0e10cSrcweir if( bFound )
913cdf0e10cSrcweir rColor = rStyle.GetColor();
914cdf0e10cSrcweir return bFound;
915cdf0e10cSrcweir }
916cdf0e10cSrcweir
917cdf0e10cSrcweir // frame border selection -----------------------------------------------------
918cdf0e10cSrcweir
GetSelectHdl() const919cdf0e10cSrcweir const Link& FrameSelector::GetSelectHdl() const
920cdf0e10cSrcweir {
921cdf0e10cSrcweir return mxImpl->maSelectHdl;
922cdf0e10cSrcweir }
923cdf0e10cSrcweir
SetSelectHdl(const Link & rHdl)924cdf0e10cSrcweir void FrameSelector::SetSelectHdl( const Link& rHdl )
925cdf0e10cSrcweir {
926cdf0e10cSrcweir mxImpl->maSelectHdl = rHdl;
927cdf0e10cSrcweir }
928cdf0e10cSrcweir
IsBorderSelected(FrameBorderType eBorder) const929cdf0e10cSrcweir bool FrameSelector::IsBorderSelected( FrameBorderType eBorder ) const
930cdf0e10cSrcweir {
931cdf0e10cSrcweir return mxImpl->GetBorder( eBorder ).IsSelected();
932cdf0e10cSrcweir }
933cdf0e10cSrcweir
SelectBorder(FrameBorderType eBorder,bool bSelect)9349b8096d0SSteve Yin void FrameSelector::SelectBorder( FrameBorderType eBorder, bool bSelect /*, bool bFocus */ )
935cdf0e10cSrcweir {
936cdf0e10cSrcweir mxImpl->SelectBorder( mxImpl->GetBorderAccess( eBorder ), bSelect );
9379b8096d0SSteve Yin // MT: bFireFox as API parameter is ugly...
9389b8096d0SSteve Yin // if (bFocus)
9399b8096d0SSteve Yin {
9409b8096d0SSteve Yin Reference< XAccessible > xRet = GetChildAccessible(eBorder);
9419b8096d0SSteve Yin a11y::AccFrameSelector* pFrameSelector = static_cast<a11y::AccFrameSelector*>(xRet.get());
9429b8096d0SSteve Yin if (pFrameSelector)
9439b8096d0SSteve Yin {
9449b8096d0SSteve Yin Any aOldValue, aNewValue;
9459b8096d0SSteve Yin aNewValue <<= AccessibleStateType::FOCUSED;
9469b8096d0SSteve Yin pFrameSelector->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
9479b8096d0SSteve Yin }
9489b8096d0SSteve Yin }
949cdf0e10cSrcweir }
950cdf0e10cSrcweir
IsAnyBorderSelected() const951cdf0e10cSrcweir bool FrameSelector::IsAnyBorderSelected() const
952cdf0e10cSrcweir {
953cdf0e10cSrcweir // Construct an iterator for selected borders. If it is valid, there is a selected border.
954cdf0e10cSrcweir return SelFrameBorderCIter( mxImpl->maEnabBorders ).Is();
955cdf0e10cSrcweir }
956cdf0e10cSrcweir
SelectAllBorders(bool bSelect)957cdf0e10cSrcweir void FrameSelector::SelectAllBorders( bool bSelect )
958cdf0e10cSrcweir {
959cdf0e10cSrcweir for( FrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
960cdf0e10cSrcweir mxImpl->SelectBorder( **aIt, bSelect );
961cdf0e10cSrcweir }
962cdf0e10cSrcweir
SelectAllVisibleBorders(bool bSelect)963cdf0e10cSrcweir void FrameSelector::SelectAllVisibleBorders( bool bSelect )
964cdf0e10cSrcweir {
965cdf0e10cSrcweir for( VisFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
966cdf0e10cSrcweir mxImpl->SelectBorder( **aIt, bSelect );
967cdf0e10cSrcweir }
968cdf0e10cSrcweir
SetStyleToSelection(sal_uInt16 nPrim,sal_uInt16 nDist,sal_uInt16 nSecn)969cdf0e10cSrcweir void FrameSelector::SetStyleToSelection( sal_uInt16 nPrim, sal_uInt16 nDist, sal_uInt16 nSecn )
970cdf0e10cSrcweir {
971cdf0e10cSrcweir mxImpl->maCurrStyle.SetOutWidth( nPrim );
972cdf0e10cSrcweir mxImpl->maCurrStyle.SetDistance( nDist );
973cdf0e10cSrcweir mxImpl->maCurrStyle.SetInWidth( nSecn );
974cdf0e10cSrcweir for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
975cdf0e10cSrcweir mxImpl->SetBorderState( **aIt, FRAMESTATE_SHOW );
976cdf0e10cSrcweir }
977cdf0e10cSrcweir
SetColorToSelection(const Color & rColor)978cdf0e10cSrcweir void FrameSelector::SetColorToSelection( const Color& rColor )
979cdf0e10cSrcweir {
980cdf0e10cSrcweir mxImpl->maCurrStyle.SetColor( rColor );
981cdf0e10cSrcweir for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
982cdf0e10cSrcweir mxImpl->SetBorderState( **aIt, FRAMESTATE_SHOW );
983cdf0e10cSrcweir }
984cdf0e10cSrcweir
985cdf0e10cSrcweir // accessibility --------------------------------------------------------------
986cdf0e10cSrcweir
CreateAccessible()987cdf0e10cSrcweir Reference< XAccessible > FrameSelector::CreateAccessible()
988cdf0e10cSrcweir {
989cdf0e10cSrcweir if( !mxImpl->mxAccess.is() )
990cdf0e10cSrcweir mxImpl->mxAccess = mxImpl->mpAccess =
991cdf0e10cSrcweir new a11y::AccFrameSelector( *this, FRAMEBORDER_NONE );
992cdf0e10cSrcweir return mxImpl->mxAccess;
993cdf0e10cSrcweir }
994cdf0e10cSrcweir
GetChildAccessible(FrameBorderType eBorder)995cdf0e10cSrcweir Reference< XAccessible > FrameSelector::GetChildAccessible( FrameBorderType eBorder )
996cdf0e10cSrcweir {
997cdf0e10cSrcweir Reference< XAccessible > xRet;
998cdf0e10cSrcweir size_t nVecIdx = static_cast< size_t >( eBorder );
999cdf0e10cSrcweir if( IsBorderEnabled( eBorder ) && (1 <= nVecIdx) && (nVecIdx <= mxImpl->maChildVec.size()) )
1000cdf0e10cSrcweir {
1001cdf0e10cSrcweir --nVecIdx;
1002cdf0e10cSrcweir if( !mxImpl->maChildVec[ nVecIdx ] )
1003cdf0e10cSrcweir mxImpl->mxChildVec[ nVecIdx ] = mxImpl->maChildVec[ nVecIdx ] =
1004cdf0e10cSrcweir new a11y::AccFrameSelector( *this, eBorder );
1005cdf0e10cSrcweir xRet = mxImpl->mxChildVec[ nVecIdx ];
1006cdf0e10cSrcweir }
1007cdf0e10cSrcweir return xRet;
1008cdf0e10cSrcweir }
1009cdf0e10cSrcweir
GetChildAccessible(sal_Int32 nIndex)1010cdf0e10cSrcweir Reference< XAccessible > FrameSelector::GetChildAccessible( sal_Int32 nIndex )
1011cdf0e10cSrcweir {
1012cdf0e10cSrcweir return GetChildAccessible( GetEnabledBorderType( nIndex ) );
1013cdf0e10cSrcweir }
1014cdf0e10cSrcweir
GetChildAccessible(const Point & rPos)1015cdf0e10cSrcweir Reference< XAccessible > FrameSelector::GetChildAccessible( const Point& rPos )
1016cdf0e10cSrcweir {
1017cdf0e10cSrcweir Reference< XAccessible > xRet;
1018cdf0e10cSrcweir for( FrameBorderCIter aIt( mxImpl->maEnabBorders ); !xRet.is() && aIt.Is(); ++aIt )
1019cdf0e10cSrcweir if( (*aIt)->ContainsClickPoint( rPos ) )
1020cdf0e10cSrcweir xRet = GetChildAccessible( (*aIt)->GetType() );
1021cdf0e10cSrcweir return xRet;
1022cdf0e10cSrcweir }
1023cdf0e10cSrcweir
ContainsClickPoint(const Point & rPos) const1024cdf0e10cSrcweir bool FrameSelector::ContainsClickPoint( const Point& rPos ) const
1025cdf0e10cSrcweir {
1026cdf0e10cSrcweir bool bContains = false;
1027cdf0e10cSrcweir for( FrameBorderCIter aIt( mxImpl->maEnabBorders ); !bContains && aIt.Is(); ++aIt )
1028cdf0e10cSrcweir bContains = (*aIt)->ContainsClickPoint( rPos );
1029cdf0e10cSrcweir return bContains;
1030cdf0e10cSrcweir }
1031cdf0e10cSrcweir
GetClickBoundRect(FrameBorderType eBorder) const1032cdf0e10cSrcweir Rectangle FrameSelector::GetClickBoundRect( FrameBorderType eBorder ) const
1033cdf0e10cSrcweir {
1034cdf0e10cSrcweir Rectangle aRect;
1035cdf0e10cSrcweir const FrameBorder& rBorder = mxImpl->GetBorder( eBorder );
1036cdf0e10cSrcweir if( rBorder.IsEnabled() )
1037cdf0e10cSrcweir aRect = rBorder.GetClickBoundRect();
1038cdf0e10cSrcweir return aRect;
1039cdf0e10cSrcweir }
1040cdf0e10cSrcweir
1041cdf0e10cSrcweir // virtual functions from base class ------------------------------------------
1042cdf0e10cSrcweir
Paint(const Rectangle &)1043cdf0e10cSrcweir void FrameSelector::Paint( const Rectangle& )
1044cdf0e10cSrcweir {
1045cdf0e10cSrcweir mxImpl->CopyVirDevToControl();
1046cdf0e10cSrcweir if( HasFocus() )
1047cdf0e10cSrcweir mxImpl->DrawAllTrackingRects();
1048cdf0e10cSrcweir }
1049cdf0e10cSrcweir
MouseButtonDown(const MouseEvent & rMEvt)1050cdf0e10cSrcweir void FrameSelector::MouseButtonDown( const MouseEvent& rMEvt )
1051cdf0e10cSrcweir {
1052cdf0e10cSrcweir /* Mouse handling:
1053cdf0e10cSrcweir * Click on an unselected frame border:
1054cdf0e10cSrcweir Set current style/color, make frame border visible, deselect all
1055cdf0e10cSrcweir other frame borders.
1056cdf0e10cSrcweir * Click on a selected frame border:
1057cdf0e10cSrcweir Toggle state of the frame border (visible -> don't care -> hidden),
1058cdf0e10cSrcweir deselect all other frame borders.
1059cdf0e10cSrcweir * SHIFT+Click or CTRL+Click on an unselected frame border:
1060cdf0e10cSrcweir Extend selection, set current style/color to all selected frame
1061cdf0e10cSrcweir borders independent of the state/style/color of the borders.
1062cdf0e10cSrcweir * SHIFT+Click or CTRL+Click on a selected frame border:
1063cdf0e10cSrcweir If all frame borders have same style/color, toggle state of all
1064cdf0e10cSrcweir borders (see above), otherwise set current style/color to all
1065cdf0e10cSrcweir borders.
1066cdf0e10cSrcweir * Click on unused area: Do not modify selection and selected frame
1067cdf0e10cSrcweir borders.
1068cdf0e10cSrcweir */
1069cdf0e10cSrcweir
1070cdf0e10cSrcweir // #107394# do not auto-select a frame border
1071cdf0e10cSrcweir mxImpl->SilentGrabFocus();
1072cdf0e10cSrcweir
1073cdf0e10cSrcweir if( rMEvt.IsLeft() )
1074cdf0e10cSrcweir {
1075cdf0e10cSrcweir Point aPos( mxImpl->GetDevPosFromMousePos( rMEvt.GetPosPixel() ) );
1076cdf0e10cSrcweir FrameBorderPtrVec aDeselectBorders;
1077cdf0e10cSrcweir
1078cdf0e10cSrcweir bool bAnyClicked = false; // Any frame border clicked?
1079cdf0e10cSrcweir bool bNewSelected = false; // Any unselected frame border selected?
1080cdf0e10cSrcweir
1081cdf0e10cSrcweir /* If frame borders are set to "don't care" and the control does not
1082cdf0e10cSrcweir support this state, hide them on first mouse click.
1083cdf0e10cSrcweir DR 2004-01-30: Why are the borders set to "don't care" then?!? */
1084cdf0e10cSrcweir bool bHideDontCare = !mxImpl->mbClicked && !SupportsDontCareState();
1085cdf0e10cSrcweir
1086cdf0e10cSrcweir for( FrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
1087cdf0e10cSrcweir {
1088cdf0e10cSrcweir if( (*aIt)->ContainsClickPoint( aPos ) )
1089cdf0e10cSrcweir {
1090cdf0e10cSrcweir // frame border is clicked
1091cdf0e10cSrcweir bAnyClicked = true;
1092cdf0e10cSrcweir if( !(*aIt)->IsSelected() )
1093cdf0e10cSrcweir {
1094cdf0e10cSrcweir bNewSelected = true;
10959b8096d0SSteve Yin //mxImpl->SelectBorder( **aIt, true );
10969b8096d0SSteve Yin SelectBorder((**aIt).GetType(), true);
1097cdf0e10cSrcweir }
1098cdf0e10cSrcweir }
1099cdf0e10cSrcweir else
1100cdf0e10cSrcweir {
1101cdf0e10cSrcweir // hide a "don't care" frame border only if it is not clicked
1102cdf0e10cSrcweir if( bHideDontCare && ((*aIt)->GetState() == FRAMESTATE_DONTCARE) )
1103cdf0e10cSrcweir mxImpl->SetBorderState( **aIt, FRAMESTATE_HIDE );
1104cdf0e10cSrcweir
1105cdf0e10cSrcweir // deselect frame borders not clicked (if SHIFT or CTRL are not pressed)
1106cdf0e10cSrcweir if( !rMEvt.IsShift() && !rMEvt.IsMod1() )
1107cdf0e10cSrcweir aDeselectBorders.push_back( *aIt );
1108cdf0e10cSrcweir }
1109cdf0e10cSrcweir }
1110cdf0e10cSrcweir
1111cdf0e10cSrcweir if( bAnyClicked )
1112cdf0e10cSrcweir {
1113cdf0e10cSrcweir // any valid frame border clicked? -> deselect other frame borders
1114cdf0e10cSrcweir for( FrameBorderIter aIt( aDeselectBorders ); aIt.Is(); ++aIt )
1115cdf0e10cSrcweir mxImpl->SelectBorder( **aIt, false );
1116cdf0e10cSrcweir
1117cdf0e10cSrcweir if( bNewSelected || !mxImpl->SelectedBordersEqual() )
1118cdf0e10cSrcweir {
1119cdf0e10cSrcweir // new frame border selected, selection extended, or selected borders different? -> show
1120cdf0e10cSrcweir for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
1121cdf0e10cSrcweir // SetBorderState() sets current style and color to the frame border
1122cdf0e10cSrcweir mxImpl->SetBorderState( **aIt, FRAMESTATE_SHOW );
1123cdf0e10cSrcweir }
1124cdf0e10cSrcweir else
1125cdf0e10cSrcweir {
1126cdf0e10cSrcweir // all selected frame borders are equal -> toggle state
1127cdf0e10cSrcweir for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
1128cdf0e10cSrcweir mxImpl->ToggleBorderState( **aIt );
1129cdf0e10cSrcweir }
1130cdf0e10cSrcweir }
1131cdf0e10cSrcweir }
1132cdf0e10cSrcweir }
1133cdf0e10cSrcweir
KeyInput(const KeyEvent & rKEvt)1134cdf0e10cSrcweir void FrameSelector::KeyInput( const KeyEvent& rKEvt )
1135cdf0e10cSrcweir {
1136cdf0e10cSrcweir bool bHandled = false;
1137cdf0e10cSrcweir KeyCode aKeyCode = rKEvt.GetKeyCode();
1138cdf0e10cSrcweir if( !aKeyCode.GetModifier() )
1139cdf0e10cSrcweir {
1140cdf0e10cSrcweir sal_uInt16 nCode = aKeyCode.GetCode();
1141cdf0e10cSrcweir switch( nCode )
1142cdf0e10cSrcweir {
1143cdf0e10cSrcweir case KEY_SPACE:
1144cdf0e10cSrcweir {
1145cdf0e10cSrcweir for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
1146cdf0e10cSrcweir mxImpl->ToggleBorderState( **aIt );
1147cdf0e10cSrcweir bHandled = true;
1148cdf0e10cSrcweir }
1149cdf0e10cSrcweir break;
1150cdf0e10cSrcweir
1151cdf0e10cSrcweir case KEY_UP:
1152cdf0e10cSrcweir case KEY_DOWN:
1153cdf0e10cSrcweir case KEY_LEFT:
1154cdf0e10cSrcweir case KEY_RIGHT:
1155cdf0e10cSrcweir {
1156cdf0e10cSrcweir if( !mxImpl->maEnabBorders.empty() )
1157cdf0e10cSrcweir {
1158cdf0e10cSrcweir // start from first selected frame border
1159cdf0e10cSrcweir SelFrameBorderCIter aIt( mxImpl->maEnabBorders );
1160cdf0e10cSrcweir FrameBorderType eBorder = aIt.Is() ? (*aIt)->GetType() : mxImpl->maEnabBorders.front()->GetType();
1161cdf0e10cSrcweir
1162cdf0e10cSrcweir // search for next enabled frame border
1163cdf0e10cSrcweir do
1164cdf0e10cSrcweir {
1165cdf0e10cSrcweir eBorder = mxImpl->GetBorder( eBorder ).GetKeyboardNeighbor( nCode );
1166cdf0e10cSrcweir }
1167cdf0e10cSrcweir while( (eBorder != FRAMEBORDER_NONE) && !IsBorderEnabled( eBorder ) );
1168cdf0e10cSrcweir
1169cdf0e10cSrcweir // select the frame border
1170cdf0e10cSrcweir if( eBorder != FRAMEBORDER_NONE )
1171cdf0e10cSrcweir {
1172cdf0e10cSrcweir DeselectAllBorders();
1173cdf0e10cSrcweir SelectBorder( eBorder );
1174cdf0e10cSrcweir }
1175cdf0e10cSrcweir }
1176cdf0e10cSrcweir }
1177cdf0e10cSrcweir break;
1178cdf0e10cSrcweir }
1179cdf0e10cSrcweir }
1180cdf0e10cSrcweir if( !bHandled )
1181cdf0e10cSrcweir Window::KeyInput(rKEvt);
1182cdf0e10cSrcweir }
1183cdf0e10cSrcweir
GetFocus()1184cdf0e10cSrcweir void FrameSelector::GetFocus()
1185cdf0e10cSrcweir {
1186cdf0e10cSrcweir // auto-selection of a frame border, if focus reaches control, and nothing is selected
1187cdf0e10cSrcweir if( mxImpl->mbAutoSelect && !IsAnyBorderSelected() && !mxImpl->maEnabBorders.empty() )
1188cdf0e10cSrcweir mxImpl->SelectBorder( *mxImpl->maEnabBorders.front(), true );
1189cdf0e10cSrcweir
1190cdf0e10cSrcweir mxImpl->DoInvalidate( false );
1191cdf0e10cSrcweir if( mxImpl->mxAccess.is() )
1192cdf0e10cSrcweir mxImpl->mpAccess->NotifyFocusListeners( sal_True );
11939b8096d0SSteve Yin if (IsAnyBorderSelected())
11949b8096d0SSteve Yin {
11959b8096d0SSteve Yin FrameBorderType borderType = FRAMEBORDER_NONE;
11969b8096d0SSteve Yin if (mxImpl->maLeft.IsSelected())
11979b8096d0SSteve Yin borderType = FRAMEBORDER_LEFT;
11989b8096d0SSteve Yin else if (mxImpl->maRight.IsSelected())
11999b8096d0SSteve Yin borderType = FRAMEBORDER_RIGHT;
12009b8096d0SSteve Yin else if (mxImpl->maTop.IsSelected())
12019b8096d0SSteve Yin borderType = FRAMEBORDER_TOP;
12029b8096d0SSteve Yin else if (mxImpl->maBottom.IsSelected())
12039b8096d0SSteve Yin borderType = FRAMEBORDER_BOTTOM;
12049b8096d0SSteve Yin else if (mxImpl->maHor.IsSelected())
12059b8096d0SSteve Yin borderType = FRAMEBORDER_HOR;
12069b8096d0SSteve Yin else if (mxImpl->maVer.IsSelected())
12079b8096d0SSteve Yin borderType = FRAMEBORDER_VER;
12089b8096d0SSteve Yin else if (mxImpl->maTLBR.IsSelected())
12099b8096d0SSteve Yin borderType = FRAMEBORDER_TLBR;
12109b8096d0SSteve Yin else if (mxImpl->maBLTR.IsSelected())
12119b8096d0SSteve Yin borderType = FRAMEBORDER_BLTR;
12129b8096d0SSteve Yin SelectBorder(borderType);
12139b8096d0SSteve Yin }
12149b8096d0SSteve Yin for( SelFrameBorderIter aIt( mxImpl->maEnabBorders ); aIt.Is(); ++aIt )
12159b8096d0SSteve Yin mxImpl->SetBorderState( **aIt, FRAMESTATE_SHOW );
1216cdf0e10cSrcweir Control::GetFocus();
1217cdf0e10cSrcweir }
1218cdf0e10cSrcweir
LoseFocus()1219cdf0e10cSrcweir void FrameSelector::LoseFocus()
1220cdf0e10cSrcweir {
1221cdf0e10cSrcweir mxImpl->DoInvalidate( false );
1222cdf0e10cSrcweir if( mxImpl->mxAccess.is() )
1223cdf0e10cSrcweir mxImpl->mpAccess->NotifyFocusListeners( sal_False );
1224cdf0e10cSrcweir Control::LoseFocus();
1225cdf0e10cSrcweir }
1226cdf0e10cSrcweir
DataChanged(const DataChangedEvent & rDCEvt)1227cdf0e10cSrcweir void FrameSelector::DataChanged( const DataChangedEvent& rDCEvt )
1228cdf0e10cSrcweir {
1229cdf0e10cSrcweir Control::DataChanged( rDCEvt );
1230cdf0e10cSrcweir if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
1231cdf0e10cSrcweir mxImpl->InitVirtualDevice();
1232cdf0e10cSrcweir }
1233cdf0e10cSrcweir
1234cdf0e10cSrcweir // ============================================================================
1235cdf0e10cSrcweir
1236cdf0e10cSrcweir template< typename Cont, typename Iter, typename Pred >
FrameBorderIterBase(container_type & rCont)1237cdf0e10cSrcweir FrameBorderIterBase< Cont, Iter, Pred >::FrameBorderIterBase( container_type& rCont ) :
1238cdf0e10cSrcweir maIt( rCont.begin() ),
1239cdf0e10cSrcweir maEnd( rCont.end() )
1240cdf0e10cSrcweir {
1241cdf0e10cSrcweir while( Is() && !maPred( *maIt ) ) ++maIt;
1242cdf0e10cSrcweir }
1243cdf0e10cSrcweir
1244cdf0e10cSrcweir template< typename Cont, typename Iter, typename Pred >
operator ++()1245cdf0e10cSrcweir FrameBorderIterBase< Cont, Iter, Pred >& FrameBorderIterBase< Cont, Iter, Pred >::operator++()
1246cdf0e10cSrcweir {
1247cdf0e10cSrcweir do { ++maIt; } while( Is() && !maPred( *maIt ) );
1248cdf0e10cSrcweir return *this;
1249cdf0e10cSrcweir }
1250cdf0e10cSrcweir
1251cdf0e10cSrcweir // ============================================================================
1252cdf0e10cSrcweir
1253cdf0e10cSrcweir } // namespace svx
1254