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() throw(RuntimeException)
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     throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::awt::MaxChildrenException)
128 {
129     if ( maChildren.size() == 2 )
130         throw css::awt::MaxChildrenException();
131     Box_Base::addChild( xChild );
132 }
133 
allocateArea(const::com::sun::star::awt::Rectangle & rArea)134 void SAL_CALL VCLXSplitter::allocateArea(
135     const ::com::sun::star::awt::Rectangle &rArea )
136     throw (::com::sun::star::uno::RuntimeException)
137 {
138     ensureSplitter();  // shouldn't be needed...
139     getMinimumSize();
140     int splitDiff;
141     if ( mbHorizontal )
142         splitDiff = rArea.Width - maAllocation.Width;
143     else
144         splitDiff = rArea.Height - maAllocation.Height;
145 
146     assert( mpSplitter );
147     if ( splitDiff )
148         mpSplitter->SetSplitPosPixel( mpSplitter->GetSplitPosPixel() + splitDiff/2 );
149 
150     maAllocation = rArea;
151     int width = mbHorizontal ? rArea.Width : rArea.Height;
152     int splitLen = 2;
153     int splitPos = mpSplitter->GetSplitPosPixel();
154     setPosSize( rArea.X, rArea.Y, rArea.Width, rArea.Height, PosSize::POSSIZE );
155     if ( mbHorizontal )
156         mpSplitter->SetPosSizePixel( splitPos, 0, splitLen, rArea.Height, PosSize::POSSIZE );
157     else
158         mpSplitter->SetPosSizePixel( 0, splitPos, rArea.Width, splitLen, PosSize::POSSIZE );
159     mpSplitter->SetDragRectPixel( ::Rectangle( 0, 0, rArea.Width, rArea.Height ) );
160     int leftWidth = splitPos;
161     int rightWidth = width - splitPos;
162 
163     if ( getChild( 0 ) && getChild( 0 )->mxChild.is() )
164     {
165         awt::Rectangle childRect( 0, 0, rArea.Width, rArea.Height );
166 
167         if ( mbHorizontal )
168             childRect.Width = leftWidth - 2;
169         else
170             childRect.Height = leftWidth - 2;
171         allocateChildAt( getChild( 0 )->mxChild, childRect );
172     }
173     if ( getChild( 0 ) && getChild( 0 )->mxChild.is() )
174     {
175         awt::Rectangle childRect( 0, 0, rArea.Width, rArea.Height );
176 
177         if ( mbHorizontal )
178         {
179             childRect.X += leftWidth + splitLen + 2;
180             childRect.Width = rightWidth;
181         }
182         else
183         {
184             childRect.Y += leftWidth + splitLen + 2;
185             childRect.Height = rightWidth;
186         }
187         allocateChildAt( getChild( 1 )->mxChild, childRect );
188     }
189 }
190 
getMinimumSize()191 ::com::sun::star::awt::Size SAL_CALL VCLXSplitter::getMinimumSize()
192     throw(::com::sun::star::uno::RuntimeException)
193 {
194     ensureSplitter();
195 
196     awt::Size size( mbHorizontal ? 2 : 0, mbHorizontal ? 0 : 2 );
197     for ( unsigned int i = 0; i < 2; i++ )
198     {
199         if ( getChild( i ) && getChild( i )->mxChild.is() )
200         {
201             awt::Size childSize = getChild( i )->mxChild->getMinimumSize();
202             if ( mbHorizontal )
203             {
204                 size.Width += childSize.Width;
205                 size.Height = SAL_MAX( size.Height, childSize.Height );
206             }
207             else
208             {
209                 size.Width = SAL_MAX( size.Width, childSize.Width );
210                 size.Height += childSize.Height;
211             }
212         }
213     }
214 
215     maRequisition = size;
216     return size;
217 }
218 
ProcessWindowEvent(const VclWindowEvent & _rVclWindowEvent)219 void VCLXSplitter::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent )
220 {
221     VCLXWindow::ProcessWindowEvent( _rVclWindowEvent );
222 }
223 
setProperty(const::rtl::OUString & PropertyName,const Any & Value)224 void SAL_CALL VCLXSplitter::setProperty( const ::rtl::OUString& PropertyName, const Any &Value ) throw(RuntimeException)
225 {
226     VCLXWindow::setProperty( PropertyName, Value );
227 }
228 
getProperty(const::rtl::OUString & PropertyName)229 Any SAL_CALL VCLXSplitter::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException)
230 {
231     return VCLXWindow::getProperty( PropertyName );
232 }
233 
IMPL_LINK(VCLXSplitter,HandleMovedHdl,Splitter *,pSplitter)234 IMPL_LINK( VCLXSplitter, HandleMovedHdl, Splitter *, pSplitter )
235 {
236     (void) pSplitter;
237     forceRecalc();
238     return 0;
239 }
240 
241 } // namespace layoutimpl
242