1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "vclxsplitter.hxx" 29 30 #include <assert.h> 31 #include <com/sun/star/awt/PosSize.hpp> 32 #include <sal/macros.h> 33 #include <toolkit/helper/property.hxx> 34 #include <toolkit/helper/vclunohelper.hxx> 35 #include <vcl/split.hxx> 36 37 #include "forward.hxx" 38 39 namespace layoutimpl 40 { 41 42 using namespace ::com::sun::star::uno; 43 using namespace ::com::sun::star::awt; 44 using namespace ::com::sun::star::lang; 45 using namespace ::com::sun::star::beans; 46 using namespace ::com::sun::star; 47 48 VCLXSplitter::ChildProps::ChildProps( VCLXSplitter::ChildData *pData ) 49 { 50 addProp( RTL_CONSTASCII_USTRINGPARAM( "Shrink" ), 51 ::getCppuType( static_cast< const rtl::OUString* >( NULL ) ), 52 &(pData->mbShrink) ); 53 } 54 55 VCLXSplitter::ChildData::ChildData( uno::Reference< awt::XLayoutConstrains > const& xChild ) 56 : Box_Base::ChildData( xChild ) 57 , mbShrink( false ) 58 { 59 } 60 61 VCLXSplitter::ChildData* 62 VCLXSplitter::createChild( uno::Reference< awt::XLayoutConstrains > const& xChild ) 63 { 64 return new ChildData( xChild ); 65 } 66 67 VCLXSplitter::ChildProps* 68 VCLXSplitter::createChildProps( Box_Base::ChildData *pData ) 69 { 70 return new ChildProps( static_cast<VCLXSplitter::ChildData*> ( pData ) ); 71 } 72 73 74 DBG_NAME( VCLXSplitter ); 75 76 VCLXSplitter::VCLXSplitter( bool bHorizontal ) 77 : VCLXWindow() 78 , Box_Base() 79 { 80 DBG_CTOR( VCLXSplitter, NULL ); 81 mnHandleRatio = 0.5; 82 mbHandlePressed = false; 83 mbHorizontal = bHorizontal; 84 mpSplitter = NULL; 85 } 86 87 VCLXSplitter::~VCLXSplitter() 88 { 89 DBG_DTOR( VCLXSplitter, NULL ); 90 } 91 92 IMPLEMENT_2_FORWARD_XINTERFACE1( VCLXSplitter, VCLXWindow, Container ); 93 94 IMPLEMENT_FORWARD_XTYPEPROVIDER1( VCLXSplitter, VCLXWindow ); 95 96 VCLXSplitter::ChildData* 97 VCLXSplitter::getChild( int i ) 98 { 99 if ( maChildren.size() && i == 0 ) 100 return static_cast<VCLXSplitter::ChildData*>( maChildren.front() ); 101 else if ( maChildren.size() > 1 && i == 1 ) 102 return static_cast<VCLXSplitter::ChildData*>( maChildren.back() ); 103 return 0; 104 } 105 106 void SAL_CALL VCLXSplitter::dispose() throw(RuntimeException) 107 { 108 { 109 ::vos::OGuard aGuard( GetMutex() ); 110 111 EventObject aDisposeEvent; 112 aDisposeEvent.Source = W3K_EXPLICIT_CAST (*this); 113 // maTabListeners.disposeAndClear( aDisposeEvent ); 114 } 115 116 VCLXWindow::dispose(); 117 } 118 119 void VCLXSplitter::ensureSplitter() 120 { 121 if ( !mpSplitter ) 122 { 123 mpSplitter = new Splitter( GetWindow() , mbHorizontal ? WB_HORZ : WB_VERT ); 124 mpSplitter->Show(); 125 mpSplitter->SetEndSplitHdl( LINK( this, VCLXSplitter, HandleMovedHdl ) ); 126 } 127 } 128 129 void SAL_CALL VCLXSplitter::addChild( 130 const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XLayoutConstrains > &xChild ) 131 throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::awt::MaxChildrenException) 132 { 133 if ( maChildren.size() == 2 ) 134 throw css::awt::MaxChildrenException(); 135 Box_Base::addChild( xChild ); 136 } 137 138 void SAL_CALL VCLXSplitter::allocateArea( 139 const ::com::sun::star::awt::Rectangle &rArea ) 140 throw (::com::sun::star::uno::RuntimeException) 141 { 142 ensureSplitter(); // shouldn't be needed... 143 getMinimumSize(); 144 int splitDiff; 145 if ( mbHorizontal ) 146 splitDiff = rArea.Width - maAllocation.Width; 147 else 148 splitDiff = rArea.Height - maAllocation.Height; 149 150 assert( mpSplitter ); 151 if ( splitDiff ) 152 mpSplitter->SetSplitPosPixel( mpSplitter->GetSplitPosPixel() + splitDiff/2 ); 153 154 maAllocation = rArea; 155 int width = mbHorizontal ? rArea.Width : rArea.Height; 156 int splitLen = 2; 157 int splitPos = mpSplitter->GetSplitPosPixel(); 158 setPosSize( rArea.X, rArea.Y, rArea.Width, rArea.Height, PosSize::POSSIZE ); 159 if ( mbHorizontal ) 160 mpSplitter->SetPosSizePixel( splitPos, 0, splitLen, rArea.Height, PosSize::POSSIZE ); 161 else 162 mpSplitter->SetPosSizePixel( 0, splitPos, rArea.Width, splitLen, PosSize::POSSIZE ); 163 mpSplitter->SetDragRectPixel( ::Rectangle( 0, 0, rArea.Width, rArea.Height ) ); 164 int leftWidth = splitPos; 165 int rightWidth = width - splitPos; 166 167 if ( getChild( 0 ) && getChild( 0 )->mxChild.is() ) 168 { 169 awt::Rectangle childRect( 0, 0, rArea.Width, rArea.Height ); 170 171 if ( mbHorizontal ) 172 childRect.Width = leftWidth - 2; 173 else 174 childRect.Height = leftWidth - 2; 175 allocateChildAt( getChild( 0 )->mxChild, childRect ); 176 } 177 if ( getChild( 0 ) && getChild( 0 )->mxChild.is() ) 178 { 179 awt::Rectangle childRect( 0, 0, rArea.Width, rArea.Height ); 180 181 if ( mbHorizontal ) 182 { 183 childRect.X += leftWidth + splitLen + 2; 184 childRect.Width = rightWidth; 185 } 186 else 187 { 188 childRect.Y += leftWidth + splitLen + 2; 189 childRect.Height = rightWidth; 190 } 191 allocateChildAt( getChild( 1 )->mxChild, childRect ); 192 } 193 } 194 195 ::com::sun::star::awt::Size SAL_CALL VCLXSplitter::getMinimumSize() 196 throw(::com::sun::star::uno::RuntimeException) 197 { 198 ensureSplitter(); 199 200 awt::Size size( mbHorizontal ? 2 : 0, mbHorizontal ? 0 : 2 ); 201 for ( unsigned int i = 0; i < 2; i++ ) 202 { 203 if ( getChild( i ) && getChild( i )->mxChild.is() ) 204 { 205 awt::Size childSize = getChild( i )->mxChild->getMinimumSize(); 206 if ( mbHorizontal ) 207 { 208 size.Width += childSize.Width; 209 size.Height = SAL_MAX( size.Height, childSize.Height ); 210 } 211 else 212 { 213 size.Width = SAL_MAX( size.Width, childSize.Width ); 214 size.Height += childSize.Height; 215 } 216 } 217 } 218 219 maRequisition = size; 220 return size; 221 } 222 223 void VCLXSplitter::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent ) 224 { 225 VCLXWindow::ProcessWindowEvent( _rVclWindowEvent ); 226 } 227 228 void SAL_CALL VCLXSplitter::setProperty( const ::rtl::OUString& PropertyName, const Any &Value ) throw(RuntimeException) 229 { 230 VCLXWindow::setProperty( PropertyName, Value ); 231 } 232 233 Any SAL_CALL VCLXSplitter::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException) 234 { 235 return VCLXWindow::getProperty( PropertyName ); 236 } 237 238 IMPL_LINK( VCLXSplitter, HandleMovedHdl, Splitter *, pSplitter ) 239 { 240 (void) pSplitter; 241 forceRecalc(); 242 return 0; 243 } 244 245 } // namespace layoutimpl 246