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 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 51 VCLXSplitter::ChildData::ChildData( uno::Reference< awt::XLayoutConstrains > const& xChild ) 52 : Box_Base::ChildData( xChild ) 53 , mbShrink( false ) 54 { 55 } 56 57 VCLXSplitter::ChildData* 58 VCLXSplitter::createChild( uno::Reference< awt::XLayoutConstrains > const& xChild ) 59 { 60 return new ChildData( xChild ); 61 } 62 63 VCLXSplitter::ChildProps* 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 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 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* 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 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 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 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 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 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 219 void VCLXSplitter::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent ) 220 { 221 VCLXWindow::ProcessWindowEvent( _rVclWindowEvent ); 222 } 223 224 void SAL_CALL VCLXSplitter::setProperty( const ::rtl::OUString& PropertyName, const Any &Value ) throw(RuntimeException) 225 { 226 VCLXWindow::setProperty( PropertyName, Value ); 227 } 228 229 Any SAL_CALL VCLXSplitter::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException) 230 { 231 return VCLXWindow::getProperty( PropertyName ); 232 } 233 234 IMPL_LINK( VCLXSplitter, HandleMovedHdl, Splitter *, pSplitter ) 235 { 236 (void) pSplitter; 237 forceRecalc(); 238 return 0; 239 } 240 241 } // namespace layoutimpl 242