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