1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "vclxsplitter.hxx"
25
26 #include <assert.h>
27 #include <com/sun/star/awt/PosSize.hpp>
28 #include <sal/macros.h>
29 #include <toolkit/helper/property.hxx>
30 #include <toolkit/helper/vclunohelper.hxx>
31 #include <vcl/split.hxx>
32
33 #include "forward.hxx"
34
35 namespace layoutimpl
36 {
37
38 using namespace ::com::sun::star::uno;
39 using namespace ::com::sun::star::awt;
40 using namespace ::com::sun::star::lang;
41 using namespace ::com::sun::star::beans;
42 using namespace ::com::sun::star;
43
ChildProps(VCLXSplitter::ChildData * pData)44 VCLXSplitter::ChildProps::ChildProps( VCLXSplitter::ChildData *pData )
45 {
46 addProp( RTL_CONSTASCII_USTRINGPARAM( "Shrink" ),
47 ::getCppuType( static_cast< const rtl::OUString* >( NULL ) ),
48 &(pData->mbShrink) );
49 }
50
ChildData(uno::Reference<awt::XLayoutConstrains> const & xChild)51 VCLXSplitter::ChildData::ChildData( uno::Reference< awt::XLayoutConstrains > const& xChild )
52 : Box_Base::ChildData( xChild )
53 , mbShrink( false )
54 {
55 }
56
57 VCLXSplitter::ChildData*
createChild(uno::Reference<awt::XLayoutConstrains> const & xChild)58 VCLXSplitter::createChild( uno::Reference< awt::XLayoutConstrains > const& xChild )
59 {
60 return new ChildData( xChild );
61 }
62
63 VCLXSplitter::ChildProps*
createChildProps(Box_Base::ChildData * pData)64 VCLXSplitter::createChildProps( Box_Base::ChildData *pData )
65 {
66 return new ChildProps( static_cast<VCLXSplitter::ChildData*> ( pData ) );
67 }
68
69
70 DBG_NAME( VCLXSplitter );
71
VCLXSplitter(bool bHorizontal)72 VCLXSplitter::VCLXSplitter( bool bHorizontal )
73 : VCLXWindow()
74 , Box_Base()
75 {
76 DBG_CTOR( VCLXSplitter, NULL );
77 mnHandleRatio = 0.5;
78 mbHandlePressed = false;
79 mbHorizontal = bHorizontal;
80 mpSplitter = NULL;
81 }
82
~VCLXSplitter()83 VCLXSplitter::~VCLXSplitter()
84 {
85 DBG_DTOR( VCLXSplitter, NULL );
86 }
87
88 IMPLEMENT_2_FORWARD_XINTERFACE1( VCLXSplitter, VCLXWindow, Container );
89
90 IMPLEMENT_FORWARD_XTYPEPROVIDER1( VCLXSplitter, VCLXWindow );
91
92 VCLXSplitter::ChildData*
getChild(int i)93 VCLXSplitter::getChild( int i )
94 {
95 if ( maChildren.size() && i == 0 )
96 return static_cast<VCLXSplitter::ChildData*>( maChildren.front() );
97 else if ( maChildren.size() > 1 && i == 1 )
98 return static_cast<VCLXSplitter::ChildData*>( maChildren.back() );
99 return 0;
100 }
101
dispose()102 void SAL_CALL VCLXSplitter::dispose()
103 {
104 {
105 ::vos::OGuard aGuard( GetMutex() );
106
107 EventObject aDisposeEvent;
108 aDisposeEvent.Source = W3K_EXPLICIT_CAST (*this);
109 // maTabListeners.disposeAndClear( aDisposeEvent );
110 }
111
112 VCLXWindow::dispose();
113 }
114
ensureSplitter()115 void VCLXSplitter::ensureSplitter()
116 {
117 if ( !mpSplitter )
118 {
119 mpSplitter = new Splitter( GetWindow() , mbHorizontal ? WB_HORZ : WB_VERT );
120 mpSplitter->Show();
121 mpSplitter->SetEndSplitHdl( LINK( this, VCLXSplitter, HandleMovedHdl ) );
122 }
123 }
124
addChild(const::com::sun::star::uno::Reference<::com::sun::star::awt::XLayoutConstrains> & xChild)125 void SAL_CALL VCLXSplitter::addChild(
126 const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XLayoutConstrains > &xChild )
127 {
128 if ( maChildren.size() == 2 )
129 throw css::awt::MaxChildrenException();
130 Box_Base::addChild( xChild );
131 }
132
allocateArea(const::com::sun::star::awt::Rectangle & rArea)133 void SAL_CALL VCLXSplitter::allocateArea(
134 const ::com::sun::star::awt::Rectangle &rArea )
135 {
136 ensureSplitter(); // shouldn't be needed...
137 getMinimumSize();
138 int splitDiff;
139 if ( mbHorizontal )
140 splitDiff = rArea.Width - maAllocation.Width;
141 else
142 splitDiff = rArea.Height - maAllocation.Height;
143
144 assert( mpSplitter );
145 if ( splitDiff )
146 mpSplitter->SetSplitPosPixel( mpSplitter->GetSplitPosPixel() + splitDiff/2 );
147
148 maAllocation = rArea;
149 int width = mbHorizontal ? rArea.Width : rArea.Height;
150 int splitLen = 2;
151 int splitPos = mpSplitter->GetSplitPosPixel();
152 setPosSize( rArea.X, rArea.Y, rArea.Width, rArea.Height, PosSize::POSSIZE );
153 if ( mbHorizontal )
154 mpSplitter->SetPosSizePixel( splitPos, 0, splitLen, rArea.Height, PosSize::POSSIZE );
155 else
156 mpSplitter->SetPosSizePixel( 0, splitPos, rArea.Width, splitLen, PosSize::POSSIZE );
157 mpSplitter->SetDragRectPixel( ::Rectangle( 0, 0, rArea.Width, rArea.Height ) );
158 int leftWidth = splitPos;
159 int rightWidth = width - splitPos;
160
161 if ( getChild( 0 ) && getChild( 0 )->mxChild.is() )
162 {
163 awt::Rectangle childRect( 0, 0, rArea.Width, rArea.Height );
164
165 if ( mbHorizontal )
166 childRect.Width = leftWidth - 2;
167 else
168 childRect.Height = leftWidth - 2;
169 allocateChildAt( getChild( 0 )->mxChild, childRect );
170 }
171 if ( getChild( 0 ) && getChild( 0 )->mxChild.is() )
172 {
173 awt::Rectangle childRect( 0, 0, rArea.Width, rArea.Height );
174
175 if ( mbHorizontal )
176 {
177 childRect.X += leftWidth + splitLen + 2;
178 childRect.Width = rightWidth;
179 }
180 else
181 {
182 childRect.Y += leftWidth + splitLen + 2;
183 childRect.Height = rightWidth;
184 }
185 allocateChildAt( getChild( 1 )->mxChild, childRect );
186 }
187 }
188
getMinimumSize()189 ::com::sun::star::awt::Size SAL_CALL VCLXSplitter::getMinimumSize()
190 {
191 ensureSplitter();
192
193 awt::Size size( mbHorizontal ? 2 : 0, mbHorizontal ? 0 : 2 );
194 for ( unsigned int i = 0; i < 2; i++ )
195 {
196 if ( getChild( i ) && getChild( i )->mxChild.is() )
197 {
198 awt::Size childSize = getChild( i )->mxChild->getMinimumSize();
199 if ( mbHorizontal )
200 {
201 size.Width += childSize.Width;
202 size.Height = SAL_MAX( size.Height, childSize.Height );
203 }
204 else
205 {
206 size.Width = SAL_MAX( size.Width, childSize.Width );
207 size.Height += childSize.Height;
208 }
209 }
210 }
211
212 maRequisition = size;
213 return size;
214 }
215
ProcessWindowEvent(const VclWindowEvent & _rVclWindowEvent)216 void VCLXSplitter::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent )
217 {
218 VCLXWindow::ProcessWindowEvent( _rVclWindowEvent );
219 }
220
setProperty(const::rtl::OUString & PropertyName,const Any & Value)221 void SAL_CALL VCLXSplitter::setProperty( const ::rtl::OUString& PropertyName, const Any &Value )
222 {
223 VCLXWindow::setProperty( PropertyName, Value );
224 }
225
getProperty(const::rtl::OUString & PropertyName)226 Any SAL_CALL VCLXSplitter::getProperty( const ::rtl::OUString& PropertyName )
227 {
228 return VCLXWindow::getProperty( PropertyName );
229 }
230
IMPL_LINK(VCLXSplitter,HandleMovedHdl,Splitter *,pSplitter)231 IMPL_LINK( VCLXSplitter, HandleMovedHdl, Splitter *, pSplitter )
232 {
233 (void) pSplitter;
234 forceRecalc();
235 return 0;
236 }
237
238 } // namespace layoutimpl
239