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() 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 { 128 if ( maChildren.size() == 2 ) 129 throw css::awt::MaxChildrenException(); 130 Box_Base::addChild( xChild ); 131 } 132 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 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 216 void VCLXSplitter::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent ) 217 { 218 VCLXWindow::ProcessWindowEvent( _rVclWindowEvent ); 219 } 220 221 void SAL_CALL VCLXSplitter::setProperty( const ::rtl::OUString& PropertyName, const Any &Value ) 222 { 223 VCLXWindow::setProperty( PropertyName, Value ); 224 } 225 226 Any SAL_CALL VCLXSplitter::getProperty( const ::rtl::OUString& PropertyName ) 227 { 228 return VCLXWindow::getProperty( PropertyName ); 229 } 230 231 IMPL_LINK( VCLXSplitter, HandleMovedHdl, Splitter *, pSplitter ) 232 { 233 (void) pSplitter; 234 forceRecalc(); 235 return 0; 236 } 237 238 } // namespace layoutimpl 239