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