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