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_vcl.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <tools/rc.h> 32*cdf0e10cSrcweir #include <tools/poly.hxx> 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir #include <vcl/event.hxx> 35*cdf0e10cSrcweir #include <vcl/split.hxx> 36*cdf0e10cSrcweir #include <vcl/svapp.hxx> 37*cdf0e10cSrcweir #include <vcl/syswin.hxx> 38*cdf0e10cSrcweir #include <vcl/taskpanelist.hxx> 39*cdf0e10cSrcweir #include <vcl/gradient.hxx> 40*cdf0e10cSrcweir #include <vcl/lineinfo.hxx> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include <rtl/instance.hxx> 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir #include <window.h> 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir namespace 47*cdf0e10cSrcweir { 48*cdf0e10cSrcweir struct ImplBlackWall 49*cdf0e10cSrcweir : public rtl::StaticWithInit<Wallpaper, ImplBlackWall> { 50*cdf0e10cSrcweir Wallpaper operator () () { 51*cdf0e10cSrcweir return Wallpaper(COL_BLACK); 52*cdf0e10cSrcweir } 53*cdf0e10cSrcweir }; 54*cdf0e10cSrcweir struct ImplWhiteWall 55*cdf0e10cSrcweir : public rtl::StaticWithInit<Wallpaper, ImplWhiteWall> { 56*cdf0e10cSrcweir Wallpaper operator () () { 57*cdf0e10cSrcweir return Wallpaper(COL_LIGHTGRAY); 58*cdf0e10cSrcweir } 59*cdf0e10cSrcweir }; 60*cdf0e10cSrcweir } 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir // ======================================================================= 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir void Splitter::ImplInitSplitterData() 65*cdf0e10cSrcweir { 66*cdf0e10cSrcweir ImplGetWindowImpl()->mbSplitter = sal_True; 67*cdf0e10cSrcweir mpRefWin = NULL; 68*cdf0e10cSrcweir mnSplitPos = 0; 69*cdf0e10cSrcweir mnLastSplitPos = 0; 70*cdf0e10cSrcweir mnStartSplitPos = 0; 71*cdf0e10cSrcweir mbDragFull = sal_False; 72*cdf0e10cSrcweir mbKbdSplitting = sal_False; 73*cdf0e10cSrcweir mbInKeyEvent = 0; 74*cdf0e10cSrcweir mnKeyboardStepSize = SPLITTER_DEFAULTSTEPSIZE; 75*cdf0e10cSrcweir } 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir // ----------------------------------------------------------------------- 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir void Splitter::ImplInit( Window* pParent, WinBits nWinStyle ) 80*cdf0e10cSrcweir { 81*cdf0e10cSrcweir Window::ImplInit( pParent, nWinStyle, NULL ); 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir mpRefWin = pParent; 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir const StyleSettings& rSettings = GetSettings().GetStyleSettings(); 86*cdf0e10cSrcweir long nA = rSettings.GetScrollBarSize(); 87*cdf0e10cSrcweir long nB = rSettings.GetSplitSize(); 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir PointerStyle ePointerStyle; 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir if ( nWinStyle & WB_HSCROLL ) 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir ePointerStyle = POINTER_HSPLIT; 94*cdf0e10cSrcweir mbHorzSplit = sal_True; 95*cdf0e10cSrcweir SetSizePixel( Size( nB, nA ) ); 96*cdf0e10cSrcweir } 97*cdf0e10cSrcweir else 98*cdf0e10cSrcweir { 99*cdf0e10cSrcweir ePointerStyle = POINTER_VSPLIT; 100*cdf0e10cSrcweir mbHorzSplit = sal_False; 101*cdf0e10cSrcweir SetSizePixel( Size( nA, nB ) ); 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir SetPointer( Pointer( ePointerStyle ) ); 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir if( GetSettings().GetStyleSettings().GetFaceColor().IsDark() ) 107*cdf0e10cSrcweir SetBackground( ImplWhiteWall::get() ); 108*cdf0e10cSrcweir else 109*cdf0e10cSrcweir SetBackground( ImplBlackWall::get() ); 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir TaskPaneList *pTList = GetSystemWindow()->GetTaskPaneList(); 112*cdf0e10cSrcweir pTList->AddWindow( this ); 113*cdf0e10cSrcweir } 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir // ----------------------------------------------------------------------- 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir void Splitter::ImplSplitMousePos( Point& rPos ) 118*cdf0e10cSrcweir { 119*cdf0e10cSrcweir if ( mbHorzSplit ) 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir if ( rPos.X() > maDragRect.Right()-1 ) 122*cdf0e10cSrcweir rPos.X() = maDragRect.Right()-1; 123*cdf0e10cSrcweir if ( rPos.X() < maDragRect.Left()+1 ) 124*cdf0e10cSrcweir rPos.X() = maDragRect.Left()+1; 125*cdf0e10cSrcweir } 126*cdf0e10cSrcweir else 127*cdf0e10cSrcweir { 128*cdf0e10cSrcweir if ( rPos.Y() > maDragRect.Bottom()-1 ) 129*cdf0e10cSrcweir rPos.Y() = maDragRect.Bottom()-1; 130*cdf0e10cSrcweir if ( rPos.Y() < maDragRect.Top()+1 ) 131*cdf0e10cSrcweir rPos.Y() = maDragRect.Top()+1; 132*cdf0e10cSrcweir } 133*cdf0e10cSrcweir } 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir // ----------------------------------------------------------------------- 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir void Splitter::ImplDrawSplitter() 138*cdf0e10cSrcweir { 139*cdf0e10cSrcweir Rectangle aInvRect( maDragRect ); 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir if ( mbHorzSplit ) 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir aInvRect.Left() = maDragPos.X() - 1; 144*cdf0e10cSrcweir aInvRect.Right() = maDragPos.X() + 1; 145*cdf0e10cSrcweir } 146*cdf0e10cSrcweir else 147*cdf0e10cSrcweir { 148*cdf0e10cSrcweir aInvRect.Top() = maDragPos.Y() - 1; 149*cdf0e10cSrcweir aInvRect.Bottom() = maDragPos.Y() + 1; 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir mpRefWin->InvertTracking( mpRefWin->PixelToLogic(aInvRect), SHOWTRACK_SPLIT ); 153*cdf0e10cSrcweir } 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir // ----------------------------------------------------------------------- 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir Splitter::Splitter( Window* pParent, WinBits nStyle ) : 158*cdf0e10cSrcweir Window( WINDOW_SPLITTER ) 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir ImplInitSplitterData(); 161*cdf0e10cSrcweir ImplInit( pParent, nStyle ); 162*cdf0e10cSrcweir } 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir // ----------------------------------------------------------------------- 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir Splitter::Splitter( Window* pParent, const ResId& rResId ) : 167*cdf0e10cSrcweir Window( WINDOW_SPLITTER ) 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir ImplInitSplitterData(); 170*cdf0e10cSrcweir rResId.SetRT( RSC_SPLITTER ); 171*cdf0e10cSrcweir WinBits nStyle = ImplInitRes( rResId ); 172*cdf0e10cSrcweir ImplInit( pParent, nStyle ); 173*cdf0e10cSrcweir ImplLoadRes( rResId ); 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir if ( !(nStyle & WB_HIDE) ) 176*cdf0e10cSrcweir Show(); 177*cdf0e10cSrcweir } 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir // ----------------------------------------------------------------------- 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir Splitter::~Splitter() 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir TaskPaneList *pTList = GetSystemWindow()->GetTaskPaneList(); 184*cdf0e10cSrcweir pTList->RemoveWindow( this ); 185*cdf0e10cSrcweir } 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir // ----------------------------------------------------------------------- 188*cdf0e10cSrcweir 189*cdf0e10cSrcweir void Splitter::SetKeyboardStepSize( long nStepSize ) 190*cdf0e10cSrcweir { 191*cdf0e10cSrcweir mnKeyboardStepSize = nStepSize; 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir // ----------------------------------------------------------------------- 195*cdf0e10cSrcweir 196*cdf0e10cSrcweir long Splitter::GetKeyboardStepSize() const 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir return mnKeyboardStepSize; 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir 201*cdf0e10cSrcweir // ----------------------------------------------------------------------- 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir Splitter* Splitter::ImplFindSibling() 204*cdf0e10cSrcweir { 205*cdf0e10cSrcweir // look for another splitter with the same parent but different orientation 206*cdf0e10cSrcweir Window *pWin = GetParent()->GetWindow( WINDOW_FIRSTCHILD ); 207*cdf0e10cSrcweir Splitter *pSplitter = NULL; 208*cdf0e10cSrcweir while( pWin ) 209*cdf0e10cSrcweir { 210*cdf0e10cSrcweir if( pWin->ImplIsSplitter() ) 211*cdf0e10cSrcweir { 212*cdf0e10cSrcweir pSplitter = (Splitter*) pWin; 213*cdf0e10cSrcweir if( pSplitter != this && IsHorizontal() != pSplitter->IsHorizontal() ) 214*cdf0e10cSrcweir return pSplitter; 215*cdf0e10cSrcweir } 216*cdf0e10cSrcweir pWin = pWin->GetWindow( WINDOW_NEXT ); 217*cdf0e10cSrcweir } 218*cdf0e10cSrcweir return NULL; 219*cdf0e10cSrcweir } 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir // ----------------------------------------------------------------------- 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir sal_Bool Splitter::ImplSplitterActive() 224*cdf0e10cSrcweir { 225*cdf0e10cSrcweir // is splitter in document or at scrollbar handle ? 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir sal_Bool bActive = sal_True; 228*cdf0e10cSrcweir const StyleSettings& rSettings = GetSettings().GetStyleSettings(); 229*cdf0e10cSrcweir long nA = rSettings.GetScrollBarSize(); 230*cdf0e10cSrcweir long nB = rSettings.GetSplitSize(); 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir Size aSize = GetOutputSize(); 233*cdf0e10cSrcweir if ( mbHorzSplit ) 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir if( aSize.Width() == nB && aSize.Height() == nA ) 236*cdf0e10cSrcweir bActive = sal_False; 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir else 239*cdf0e10cSrcweir { 240*cdf0e10cSrcweir if( aSize.Width() == nA && aSize.Height() == nB ) 241*cdf0e10cSrcweir bActive = sal_False; 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir return bActive; 244*cdf0e10cSrcweir } 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir // ----------------------------------------------------------------------- 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir void Splitter::MouseButtonDown( const MouseEvent& rMEvt ) 249*cdf0e10cSrcweir { 250*cdf0e10cSrcweir if ( rMEvt.GetClicks() == 2 ) 251*cdf0e10cSrcweir { 252*cdf0e10cSrcweir if ( mnLastSplitPos != mnSplitPos ) 253*cdf0e10cSrcweir { 254*cdf0e10cSrcweir StartSplit(); 255*cdf0e10cSrcweir Point aPos = rMEvt.GetPosPixel(); 256*cdf0e10cSrcweir if ( mbHorzSplit ) 257*cdf0e10cSrcweir aPos.X() = mnLastSplitPos; 258*cdf0e10cSrcweir else 259*cdf0e10cSrcweir aPos.Y() = mnLastSplitPos; 260*cdf0e10cSrcweir ImplSplitMousePos( aPos ); 261*cdf0e10cSrcweir Splitting( aPos ); 262*cdf0e10cSrcweir ImplSplitMousePos( aPos ); 263*cdf0e10cSrcweir long nTemp = mnSplitPos; 264*cdf0e10cSrcweir if ( mbHorzSplit ) 265*cdf0e10cSrcweir SetSplitPosPixel( aPos.X() ); 266*cdf0e10cSrcweir else 267*cdf0e10cSrcweir SetSplitPosPixel( aPos.Y() ); 268*cdf0e10cSrcweir mnLastSplitPos = nTemp; 269*cdf0e10cSrcweir Split(); 270*cdf0e10cSrcweir EndSplit(); 271*cdf0e10cSrcweir } 272*cdf0e10cSrcweir } 273*cdf0e10cSrcweir else 274*cdf0e10cSrcweir StartDrag(); 275*cdf0e10cSrcweir } 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir // ----------------------------------------------------------------------- 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir void Splitter::Tracking( const TrackingEvent& rTEvt ) 280*cdf0e10cSrcweir { 281*cdf0e10cSrcweir if ( rTEvt.IsTrackingEnded() ) 282*cdf0e10cSrcweir { 283*cdf0e10cSrcweir if ( !mbDragFull ) 284*cdf0e10cSrcweir ImplDrawSplitter(); 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir if ( !rTEvt.IsTrackingCanceled() ) 287*cdf0e10cSrcweir { 288*cdf0e10cSrcweir long nNewPos; 289*cdf0e10cSrcweir if ( mbHorzSplit ) 290*cdf0e10cSrcweir nNewPos = maDragPos.X(); 291*cdf0e10cSrcweir else 292*cdf0e10cSrcweir nNewPos = maDragPos.Y(); 293*cdf0e10cSrcweir if ( nNewPos != mnStartSplitPos ) 294*cdf0e10cSrcweir { 295*cdf0e10cSrcweir SetSplitPosPixel( nNewPos ); 296*cdf0e10cSrcweir mnLastSplitPos = 0; 297*cdf0e10cSrcweir Split(); 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir EndSplit(); 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir else if ( mbDragFull ) 302*cdf0e10cSrcweir { 303*cdf0e10cSrcweir SetSplitPosPixel( mnStartSplitPos ); 304*cdf0e10cSrcweir Split(); 305*cdf0e10cSrcweir } 306*cdf0e10cSrcweir mnStartSplitPos = 0; 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir else 309*cdf0e10cSrcweir { 310*cdf0e10cSrcweir //Point aNewPos = mpRefWin->ScreenToOutputPixel( OutputToScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) ); 311*cdf0e10cSrcweir Point aNewPos = mpRefWin->NormalizedScreenToOutputPixel( OutputToNormalizedScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) ); 312*cdf0e10cSrcweir ImplSplitMousePos( aNewPos ); 313*cdf0e10cSrcweir Splitting( aNewPos ); 314*cdf0e10cSrcweir ImplSplitMousePos( aNewPos ); 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir if ( mbHorzSplit ) 317*cdf0e10cSrcweir { 318*cdf0e10cSrcweir if ( aNewPos.X() == maDragPos.X() ) 319*cdf0e10cSrcweir return; 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir else 322*cdf0e10cSrcweir { 323*cdf0e10cSrcweir if ( aNewPos.Y() == maDragPos.Y() ) 324*cdf0e10cSrcweir return; 325*cdf0e10cSrcweir } 326*cdf0e10cSrcweir 327*cdf0e10cSrcweir if ( mbDragFull ) 328*cdf0e10cSrcweir { 329*cdf0e10cSrcweir maDragPos = aNewPos; 330*cdf0e10cSrcweir long nNewPos; 331*cdf0e10cSrcweir if ( mbHorzSplit ) 332*cdf0e10cSrcweir nNewPos = maDragPos.X(); 333*cdf0e10cSrcweir else 334*cdf0e10cSrcweir nNewPos = maDragPos.Y(); 335*cdf0e10cSrcweir if ( nNewPos != mnSplitPos ) 336*cdf0e10cSrcweir { 337*cdf0e10cSrcweir SetSplitPosPixel( nNewPos ); 338*cdf0e10cSrcweir mnLastSplitPos = 0; 339*cdf0e10cSrcweir Split(); 340*cdf0e10cSrcweir } 341*cdf0e10cSrcweir 342*cdf0e10cSrcweir GetParent()->Update(); 343*cdf0e10cSrcweir } 344*cdf0e10cSrcweir else 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir ImplDrawSplitter(); 347*cdf0e10cSrcweir maDragPos = aNewPos; 348*cdf0e10cSrcweir ImplDrawSplitter(); 349*cdf0e10cSrcweir } 350*cdf0e10cSrcweir } 351*cdf0e10cSrcweir } 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir // ----------------------------------------------------------------------- 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir void Splitter::ImplKbdTracking( KeyCode aKeyCode ) 356*cdf0e10cSrcweir { 357*cdf0e10cSrcweir sal_uInt16 nCode = aKeyCode.GetCode(); 358*cdf0e10cSrcweir if ( nCode == KEY_ESCAPE || nCode == KEY_RETURN ) 359*cdf0e10cSrcweir { 360*cdf0e10cSrcweir if( !mbKbdSplitting ) 361*cdf0e10cSrcweir return; 362*cdf0e10cSrcweir else 363*cdf0e10cSrcweir mbKbdSplitting = sal_False; 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir if ( nCode != KEY_ESCAPE ) 366*cdf0e10cSrcweir { 367*cdf0e10cSrcweir long nNewPos; 368*cdf0e10cSrcweir if ( mbHorzSplit ) 369*cdf0e10cSrcweir nNewPos = maDragPos.X(); 370*cdf0e10cSrcweir else 371*cdf0e10cSrcweir nNewPos = maDragPos.Y(); 372*cdf0e10cSrcweir if ( nNewPos != mnStartSplitPos ) 373*cdf0e10cSrcweir { 374*cdf0e10cSrcweir SetSplitPosPixel( nNewPos ); 375*cdf0e10cSrcweir mnLastSplitPos = 0; 376*cdf0e10cSrcweir Split(); 377*cdf0e10cSrcweir } 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir else 380*cdf0e10cSrcweir { 381*cdf0e10cSrcweir SetSplitPosPixel( mnStartSplitPos ); 382*cdf0e10cSrcweir Split(); 383*cdf0e10cSrcweir EndSplit(); 384*cdf0e10cSrcweir } 385*cdf0e10cSrcweir mnStartSplitPos = 0; 386*cdf0e10cSrcweir } 387*cdf0e10cSrcweir else 388*cdf0e10cSrcweir { 389*cdf0e10cSrcweir Point aNewPos; 390*cdf0e10cSrcweir Size aSize = mpRefWin->GetOutputSize(); 391*cdf0e10cSrcweir Point aPos = GetPosPixel(); 392*cdf0e10cSrcweir // depending on the position calc allows continous moves or snaps to row/columns 393*cdf0e10cSrcweir // continous mode is active when position is at the origin or end of the splitter 394*cdf0e10cSrcweir // otherwise snap mode is active 395*cdf0e10cSrcweir // default here is snap, holding shift sets continous mode 396*cdf0e10cSrcweir if( mbHorzSplit ) 397*cdf0e10cSrcweir aNewPos = Point( ImplSplitterActive() ? aPos.X() : mnSplitPos, aKeyCode.IsShift() ? 0 : aSize.Height()/2); 398*cdf0e10cSrcweir else 399*cdf0e10cSrcweir aNewPos = Point( aKeyCode.IsShift() ? 0 : aSize.Width()/2, ImplSplitterActive() ? aPos.Y() : mnSplitPos ); 400*cdf0e10cSrcweir 401*cdf0e10cSrcweir Point aOldWindowPos = GetPosPixel(); 402*cdf0e10cSrcweir 403*cdf0e10cSrcweir int maxiter = 500; // avoid endless loop 404*cdf0e10cSrcweir int delta=0; 405*cdf0e10cSrcweir int delta_step = mbHorzSplit ? aSize.Width()/10 : aSize.Height()/10; 406*cdf0e10cSrcweir 407*cdf0e10cSrcweir // use the specified step size if it was set 408*cdf0e10cSrcweir if( mnKeyboardStepSize != SPLITTER_DEFAULTSTEPSIZE ) 409*cdf0e10cSrcweir delta_step = mnKeyboardStepSize; 410*cdf0e10cSrcweir 411*cdf0e10cSrcweir while( maxiter-- && aOldWindowPos == GetPosPixel() ) 412*cdf0e10cSrcweir { 413*cdf0e10cSrcweir // inc/dec position until application performs changes 414*cdf0e10cSrcweir // thus a single key press really moves the splitter 415*cdf0e10cSrcweir if( aKeyCode.IsShift() ) 416*cdf0e10cSrcweir delta++; 417*cdf0e10cSrcweir else 418*cdf0e10cSrcweir delta += delta_step; 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir switch( nCode ) 421*cdf0e10cSrcweir { 422*cdf0e10cSrcweir case KEY_LEFT: 423*cdf0e10cSrcweir aNewPos.X()-=delta; 424*cdf0e10cSrcweir break; 425*cdf0e10cSrcweir case KEY_RIGHT: 426*cdf0e10cSrcweir aNewPos.X()+=delta; 427*cdf0e10cSrcweir break; 428*cdf0e10cSrcweir case KEY_UP: 429*cdf0e10cSrcweir aNewPos.Y()-=delta; 430*cdf0e10cSrcweir break; 431*cdf0e10cSrcweir case KEY_DOWN: 432*cdf0e10cSrcweir aNewPos.Y()+=delta; 433*cdf0e10cSrcweir break; 434*cdf0e10cSrcweir default: 435*cdf0e10cSrcweir maxiter = 0; // leave loop 436*cdf0e10cSrcweir break; 437*cdf0e10cSrcweir } 438*cdf0e10cSrcweir ImplSplitMousePos( aNewPos ); 439*cdf0e10cSrcweir Splitting( aNewPos ); 440*cdf0e10cSrcweir ImplSplitMousePos( aNewPos ); 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir if ( mbHorzSplit ) 443*cdf0e10cSrcweir { 444*cdf0e10cSrcweir if ( aNewPos.X() == maDragPos.X() ) 445*cdf0e10cSrcweir continue; 446*cdf0e10cSrcweir } 447*cdf0e10cSrcweir else 448*cdf0e10cSrcweir { 449*cdf0e10cSrcweir if ( aNewPos.Y() == maDragPos.Y() ) 450*cdf0e10cSrcweir continue; 451*cdf0e10cSrcweir } 452*cdf0e10cSrcweir 453*cdf0e10cSrcweir maDragPos = aNewPos; 454*cdf0e10cSrcweir long nNewPos; 455*cdf0e10cSrcweir if ( mbHorzSplit ) 456*cdf0e10cSrcweir nNewPos = maDragPos.X(); 457*cdf0e10cSrcweir else 458*cdf0e10cSrcweir nNewPos = maDragPos.Y(); 459*cdf0e10cSrcweir if ( nNewPos != mnSplitPos ) 460*cdf0e10cSrcweir { 461*cdf0e10cSrcweir SetSplitPosPixel( nNewPos ); 462*cdf0e10cSrcweir mnLastSplitPos = 0; 463*cdf0e10cSrcweir Split(); 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir GetParent()->Update(); 466*cdf0e10cSrcweir } 467*cdf0e10cSrcweir } 468*cdf0e10cSrcweir } 469*cdf0e10cSrcweir 470*cdf0e10cSrcweir // ----------------------------------------------------------------------- 471*cdf0e10cSrcweir 472*cdf0e10cSrcweir void Splitter::StartSplit() 473*cdf0e10cSrcweir { 474*cdf0e10cSrcweir maStartSplitHdl.Call( this ); 475*cdf0e10cSrcweir } 476*cdf0e10cSrcweir 477*cdf0e10cSrcweir // ----------------------------------------------------------------------- 478*cdf0e10cSrcweir 479*cdf0e10cSrcweir void Splitter::Split() 480*cdf0e10cSrcweir { 481*cdf0e10cSrcweir maSplitHdl.Call( this ); 482*cdf0e10cSrcweir } 483*cdf0e10cSrcweir 484*cdf0e10cSrcweir // ----------------------------------------------------------------------- 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir void Splitter::EndSplit() 487*cdf0e10cSrcweir { 488*cdf0e10cSrcweir if ( maEndSplitHdl.IsSet() ) 489*cdf0e10cSrcweir maEndSplitHdl.Call( this ); 490*cdf0e10cSrcweir } 491*cdf0e10cSrcweir 492*cdf0e10cSrcweir // ----------------------------------------------------------------------- 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir void Splitter::Splitting( Point& /* rSplitPos */ ) 495*cdf0e10cSrcweir { 496*cdf0e10cSrcweir } 497*cdf0e10cSrcweir 498*cdf0e10cSrcweir // ----------------------------------------------------------------------- 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir void Splitter::SetDragRectPixel( const Rectangle& rDragRect, Window* _pRefWin ) 501*cdf0e10cSrcweir { 502*cdf0e10cSrcweir maDragRect = rDragRect; 503*cdf0e10cSrcweir if ( !_pRefWin ) 504*cdf0e10cSrcweir mpRefWin = GetParent(); 505*cdf0e10cSrcweir else 506*cdf0e10cSrcweir mpRefWin = _pRefWin; 507*cdf0e10cSrcweir } 508*cdf0e10cSrcweir 509*cdf0e10cSrcweir // ----------------------------------------------------------------------- 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir void Splitter::SetSplitPosPixel( long nNewPos ) 512*cdf0e10cSrcweir { 513*cdf0e10cSrcweir mnSplitPos = nNewPos; 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir 516*cdf0e10cSrcweir // ----------------------------------------------------------------------- 517*cdf0e10cSrcweir 518*cdf0e10cSrcweir void Splitter::SetLastSplitPosPixel( long nNewPos ) 519*cdf0e10cSrcweir { 520*cdf0e10cSrcweir mnLastSplitPos = nNewPos; 521*cdf0e10cSrcweir } 522*cdf0e10cSrcweir 523*cdf0e10cSrcweir // ----------------------------------------------------------------------- 524*cdf0e10cSrcweir 525*cdf0e10cSrcweir void Splitter::StartDrag() 526*cdf0e10cSrcweir { 527*cdf0e10cSrcweir if ( IsTracking() ) 528*cdf0e10cSrcweir return; 529*cdf0e10cSrcweir 530*cdf0e10cSrcweir StartSplit(); 531*cdf0e10cSrcweir 532*cdf0e10cSrcweir // Tracking starten 533*cdf0e10cSrcweir StartTracking(); 534*cdf0e10cSrcweir 535*cdf0e10cSrcweir // Start-Positon ermitteln 536*cdf0e10cSrcweir maDragPos = mpRefWin->GetPointerPosPixel(); 537*cdf0e10cSrcweir ImplSplitMousePos( maDragPos ); 538*cdf0e10cSrcweir Splitting( maDragPos ); 539*cdf0e10cSrcweir ImplSplitMousePos( maDragPos ); 540*cdf0e10cSrcweir if ( mbHorzSplit ) 541*cdf0e10cSrcweir mnStartSplitPos = maDragPos.X(); 542*cdf0e10cSrcweir else 543*cdf0e10cSrcweir mnStartSplitPos = maDragPos.Y(); 544*cdf0e10cSrcweir 545*cdf0e10cSrcweir mbDragFull = (Application::GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SPLIT) != 0; 546*cdf0e10cSrcweir if ( !mbDragFull ) 547*cdf0e10cSrcweir ImplDrawSplitter(); 548*cdf0e10cSrcweir } 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir 551*cdf0e10cSrcweir // ----------------------------------------------------------------------- 552*cdf0e10cSrcweir 553*cdf0e10cSrcweir void Splitter::ImplStartKbdSplitting() 554*cdf0e10cSrcweir { 555*cdf0e10cSrcweir if( mbKbdSplitting ) 556*cdf0e10cSrcweir return; 557*cdf0e10cSrcweir 558*cdf0e10cSrcweir mbKbdSplitting = sal_True; 559*cdf0e10cSrcweir 560*cdf0e10cSrcweir StartSplit(); 561*cdf0e10cSrcweir 562*cdf0e10cSrcweir // determine start position 563*cdf0e10cSrcweir // because we have no mouse position we take either the position 564*cdf0e10cSrcweir // of the splitter window or the last split position 565*cdf0e10cSrcweir // the other coordinate is just the center of the reference window 566*cdf0e10cSrcweir Size aSize = mpRefWin->GetOutputSize(); 567*cdf0e10cSrcweir Point aPos = GetPosPixel(); 568*cdf0e10cSrcweir if( mbHorzSplit ) 569*cdf0e10cSrcweir maDragPos = Point( ImplSplitterActive() ? aPos.X() : mnSplitPos, aSize.Height()/2 ); 570*cdf0e10cSrcweir else 571*cdf0e10cSrcweir maDragPos = Point( aSize.Width()/2, ImplSplitterActive() ? aPos.Y() : mnSplitPos ); 572*cdf0e10cSrcweir ImplSplitMousePos( maDragPos ); 573*cdf0e10cSrcweir Splitting( maDragPos ); 574*cdf0e10cSrcweir ImplSplitMousePos( maDragPos ); 575*cdf0e10cSrcweir if ( mbHorzSplit ) 576*cdf0e10cSrcweir mnStartSplitPos = maDragPos.X(); 577*cdf0e10cSrcweir else 578*cdf0e10cSrcweir mnStartSplitPos = maDragPos.Y(); 579*cdf0e10cSrcweir } 580*cdf0e10cSrcweir 581*cdf0e10cSrcweir // ----------------------------------------------------------------------- 582*cdf0e10cSrcweir 583*cdf0e10cSrcweir void Splitter::ImplRestoreSplitter() 584*cdf0e10cSrcweir { 585*cdf0e10cSrcweir // set splitter in the center of the ref window 586*cdf0e10cSrcweir StartSplit(); 587*cdf0e10cSrcweir Size aSize = mpRefWin->GetOutputSize(); 588*cdf0e10cSrcweir Point aPos = Point( aSize.Width()/2 , aSize.Height()/2); 589*cdf0e10cSrcweir if ( mnLastSplitPos != mnSplitPos && mnLastSplitPos > 5 ) 590*cdf0e10cSrcweir { 591*cdf0e10cSrcweir // restore last pos if it was a useful position (>5) 592*cdf0e10cSrcweir if ( mbHorzSplit ) 593*cdf0e10cSrcweir aPos.X() = mnLastSplitPos; 594*cdf0e10cSrcweir else 595*cdf0e10cSrcweir aPos.Y() = mnLastSplitPos; 596*cdf0e10cSrcweir } 597*cdf0e10cSrcweir 598*cdf0e10cSrcweir ImplSplitMousePos( aPos ); 599*cdf0e10cSrcweir Splitting( aPos ); 600*cdf0e10cSrcweir ImplSplitMousePos( aPos ); 601*cdf0e10cSrcweir long nTemp = mnSplitPos; 602*cdf0e10cSrcweir if ( mbHorzSplit ) 603*cdf0e10cSrcweir SetSplitPosPixel( aPos.X() ); 604*cdf0e10cSrcweir else 605*cdf0e10cSrcweir SetSplitPosPixel( aPos.Y() ); 606*cdf0e10cSrcweir mnLastSplitPos = nTemp; 607*cdf0e10cSrcweir Split(); 608*cdf0e10cSrcweir EndSplit(); 609*cdf0e10cSrcweir } 610*cdf0e10cSrcweir 611*cdf0e10cSrcweir 612*cdf0e10cSrcweir // ----------------------------------------------------------------------- 613*cdf0e10cSrcweir 614*cdf0e10cSrcweir void Splitter::GetFocus() 615*cdf0e10cSrcweir { 616*cdf0e10cSrcweir if( !ImplSplitterActive() ) 617*cdf0e10cSrcweir ImplRestoreSplitter(); 618*cdf0e10cSrcweir 619*cdf0e10cSrcweir Invalidate(); 620*cdf0e10cSrcweir } 621*cdf0e10cSrcweir 622*cdf0e10cSrcweir // ----------------------------------------------------------------------- 623*cdf0e10cSrcweir 624*cdf0e10cSrcweir void Splitter::LoseFocus() 625*cdf0e10cSrcweir { 626*cdf0e10cSrcweir if( mbKbdSplitting ) 627*cdf0e10cSrcweir { 628*cdf0e10cSrcweir KeyCode aReturnKey( KEY_RETURN ); 629*cdf0e10cSrcweir ImplKbdTracking( aReturnKey ); 630*cdf0e10cSrcweir mbKbdSplitting = sal_False; 631*cdf0e10cSrcweir } 632*cdf0e10cSrcweir Invalidate(); 633*cdf0e10cSrcweir } 634*cdf0e10cSrcweir 635*cdf0e10cSrcweir // ----------------------------------------------------------------------- 636*cdf0e10cSrcweir 637*cdf0e10cSrcweir void Splitter::KeyInput( const KeyEvent& rKEvt ) 638*cdf0e10cSrcweir { 639*cdf0e10cSrcweir if( mbInKeyEvent ) 640*cdf0e10cSrcweir return; 641*cdf0e10cSrcweir 642*cdf0e10cSrcweir mbInKeyEvent = 1; 643*cdf0e10cSrcweir 644*cdf0e10cSrcweir Splitter *pSibling = ImplFindSibling(); 645*cdf0e10cSrcweir KeyCode aKeyCode = rKEvt.GetKeyCode(); 646*cdf0e10cSrcweir sal_uInt16 nCode = aKeyCode.GetCode(); 647*cdf0e10cSrcweir switch ( nCode ) 648*cdf0e10cSrcweir { 649*cdf0e10cSrcweir case KEY_UP: 650*cdf0e10cSrcweir case KEY_DOWN: 651*cdf0e10cSrcweir if( !mbHorzSplit ) 652*cdf0e10cSrcweir { 653*cdf0e10cSrcweir ImplStartKbdSplitting(); 654*cdf0e10cSrcweir ImplKbdTracking( aKeyCode ); 655*cdf0e10cSrcweir } 656*cdf0e10cSrcweir else 657*cdf0e10cSrcweir { 658*cdf0e10cSrcweir if( pSibling ) 659*cdf0e10cSrcweir { 660*cdf0e10cSrcweir pSibling->GrabFocus(); 661*cdf0e10cSrcweir pSibling->KeyInput( rKEvt ); 662*cdf0e10cSrcweir } 663*cdf0e10cSrcweir } 664*cdf0e10cSrcweir break; 665*cdf0e10cSrcweir case KEY_RIGHT: 666*cdf0e10cSrcweir case KEY_LEFT: 667*cdf0e10cSrcweir if( mbHorzSplit ) 668*cdf0e10cSrcweir { 669*cdf0e10cSrcweir ImplStartKbdSplitting(); 670*cdf0e10cSrcweir ImplKbdTracking( aKeyCode ); 671*cdf0e10cSrcweir } 672*cdf0e10cSrcweir else 673*cdf0e10cSrcweir { 674*cdf0e10cSrcweir if( pSibling ) 675*cdf0e10cSrcweir { 676*cdf0e10cSrcweir pSibling->GrabFocus(); 677*cdf0e10cSrcweir pSibling->KeyInput( rKEvt ); 678*cdf0e10cSrcweir } 679*cdf0e10cSrcweir } 680*cdf0e10cSrcweir break; 681*cdf0e10cSrcweir 682*cdf0e10cSrcweir case KEY_DELETE: 683*cdf0e10cSrcweir if( ImplSplitterActive() ) 684*cdf0e10cSrcweir { 685*cdf0e10cSrcweir if( mbKbdSplitting ) 686*cdf0e10cSrcweir { 687*cdf0e10cSrcweir KeyCode aKey( KEY_ESCAPE ); 688*cdf0e10cSrcweir ImplKbdTracking( aKey ); 689*cdf0e10cSrcweir } 690*cdf0e10cSrcweir 691*cdf0e10cSrcweir StartSplit(); 692*cdf0e10cSrcweir Point aPos; 693*cdf0e10cSrcweir if ( mbHorzSplit ) 694*cdf0e10cSrcweir aPos.X() = 0; 695*cdf0e10cSrcweir else 696*cdf0e10cSrcweir aPos.Y() = 0; 697*cdf0e10cSrcweir ImplSplitMousePos( aPos ); 698*cdf0e10cSrcweir Splitting( aPos ); 699*cdf0e10cSrcweir ImplSplitMousePos( aPos ); 700*cdf0e10cSrcweir long nTemp = mnSplitPos; 701*cdf0e10cSrcweir if ( mbHorzSplit ) 702*cdf0e10cSrcweir SetSplitPosPixel( aPos.X() ); 703*cdf0e10cSrcweir else 704*cdf0e10cSrcweir SetSplitPosPixel( aPos.Y() ); 705*cdf0e10cSrcweir mnLastSplitPos = nTemp; 706*cdf0e10cSrcweir Split(); 707*cdf0e10cSrcweir EndSplit(); 708*cdf0e10cSrcweir 709*cdf0e10cSrcweir // Shift-Del deletes both splitters 710*cdf0e10cSrcweir if( aKeyCode.IsShift() && pSibling ) 711*cdf0e10cSrcweir pSibling->KeyInput( rKEvt ); 712*cdf0e10cSrcweir 713*cdf0e10cSrcweir GrabFocusToDocument(); 714*cdf0e10cSrcweir } 715*cdf0e10cSrcweir break; 716*cdf0e10cSrcweir 717*cdf0e10cSrcweir case KEY_ESCAPE: 718*cdf0e10cSrcweir if( mbKbdSplitting ) 719*cdf0e10cSrcweir ImplKbdTracking( aKeyCode ); 720*cdf0e10cSrcweir else 721*cdf0e10cSrcweir GrabFocusToDocument(); 722*cdf0e10cSrcweir break; 723*cdf0e10cSrcweir 724*cdf0e10cSrcweir case KEY_RETURN: 725*cdf0e10cSrcweir ImplKbdTracking( aKeyCode ); 726*cdf0e10cSrcweir GrabFocusToDocument(); 727*cdf0e10cSrcweir break; 728*cdf0e10cSrcweir default: // let any key input fix the splitter 729*cdf0e10cSrcweir Window::KeyInput( rKEvt ); 730*cdf0e10cSrcweir GrabFocusToDocument(); 731*cdf0e10cSrcweir break; 732*cdf0e10cSrcweir } 733*cdf0e10cSrcweir mbInKeyEvent = 0; 734*cdf0e10cSrcweir } 735*cdf0e10cSrcweir 736*cdf0e10cSrcweir // ----------------------------------------------------------------------- 737*cdf0e10cSrcweir 738*cdf0e10cSrcweir long Splitter::Notify( NotifyEvent& rNEvt ) 739*cdf0e10cSrcweir { 740*cdf0e10cSrcweir return Window::Notify( rNEvt ); 741*cdf0e10cSrcweir } 742*cdf0e10cSrcweir 743*cdf0e10cSrcweir // ----------------------------------------------------------------------- 744*cdf0e10cSrcweir 745*cdf0e10cSrcweir void Splitter::DataChanged( const DataChangedEvent& rDCEvt ) 746*cdf0e10cSrcweir { 747*cdf0e10cSrcweir Window::DataChanged( rDCEvt ); 748*cdf0e10cSrcweir if( rDCEvt.GetType() == DATACHANGED_SETTINGS ) 749*cdf0e10cSrcweir { 750*cdf0e10cSrcweir Color oldFaceColor = ((AllSettings *) rDCEvt.GetData())->GetStyleSettings().GetFaceColor(); 751*cdf0e10cSrcweir Color newFaceColor = Application::GetSettings().GetStyleSettings().GetFaceColor(); 752*cdf0e10cSrcweir if( oldFaceColor.IsDark() != newFaceColor.IsDark() ) 753*cdf0e10cSrcweir { 754*cdf0e10cSrcweir if( newFaceColor.IsDark() ) 755*cdf0e10cSrcweir SetBackground( ImplWhiteWall::get() ); 756*cdf0e10cSrcweir else 757*cdf0e10cSrcweir SetBackground( ImplBlackWall::get() ); 758*cdf0e10cSrcweir } 759*cdf0e10cSrcweir } 760*cdf0e10cSrcweir } 761*cdf0e10cSrcweir 762*cdf0e10cSrcweir // ----------------------------------------------------------------------- 763*cdf0e10cSrcweir 764*cdf0e10cSrcweir void Splitter::Paint( const Rectangle& rPaintRect ) 765*cdf0e10cSrcweir { 766*cdf0e10cSrcweir if( HasFocus() || mbKbdSplitting ) 767*cdf0e10cSrcweir { 768*cdf0e10cSrcweir Color oldFillCol = GetFillColor(); 769*cdf0e10cSrcweir Color oldLineCol = GetLineColor(); 770*cdf0e10cSrcweir 771*cdf0e10cSrcweir SetLineColor(); 772*cdf0e10cSrcweir SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() ); 773*cdf0e10cSrcweir DrawRect( rPaintRect ); 774*cdf0e10cSrcweir 775*cdf0e10cSrcweir Color aSelectionBorderCol( GetSettings().GetStyleSettings().GetActiveColor() ); 776*cdf0e10cSrcweir SetFillColor( aSelectionBorderCol ); 777*cdf0e10cSrcweir SetLineColor(); 778*cdf0e10cSrcweir 779*cdf0e10cSrcweir Polygon aPoly( rPaintRect ); 780*cdf0e10cSrcweir PolyPolygon aPolyPoly( aPoly ); 781*cdf0e10cSrcweir DrawTransparent( aPolyPoly, 85 ); 782*cdf0e10cSrcweir 783*cdf0e10cSrcweir SetLineColor( aSelectionBorderCol ); 784*cdf0e10cSrcweir SetFillColor(); 785*cdf0e10cSrcweir 786*cdf0e10cSrcweir if( mbKbdSplitting ) 787*cdf0e10cSrcweir { 788*cdf0e10cSrcweir LineInfo aInfo( LINE_DASH ); 789*cdf0e10cSrcweir //aInfo.SetDashLen( 2 ); 790*cdf0e10cSrcweir //aInfo.SetDashCount( 1 ); 791*cdf0e10cSrcweir aInfo.SetDistance( 1 ); 792*cdf0e10cSrcweir aInfo.SetDotLen( 2 ); 793*cdf0e10cSrcweir aInfo.SetDotCount( 1 ); 794*cdf0e10cSrcweir 795*cdf0e10cSrcweir DrawPolyLine( aPoly, aInfo ); 796*cdf0e10cSrcweir } 797*cdf0e10cSrcweir else 798*cdf0e10cSrcweir DrawRect( rPaintRect ); 799*cdf0e10cSrcweir 800*cdf0e10cSrcweir SetFillColor( oldFillCol); 801*cdf0e10cSrcweir SetLineColor( oldLineCol); 802*cdf0e10cSrcweir } 803*cdf0e10cSrcweir else 804*cdf0e10cSrcweir { 805*cdf0e10cSrcweir Window::Paint( rPaintRect ); 806*cdf0e10cSrcweir } 807*cdf0e10cSrcweir } 808