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 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sd.hxx"
30 #include "DialogListBox.hxx"
31 
32 namespace sd
33 {
34 
35 DialogListBox::DialogListBox( Window* pParent, WinBits nWinStyle ) :
36 	Control( pParent, nWinStyle ),
37 	mpChild( 0 )
38 {
39 	mpVScrollBar	= new ScrollBar( this, WB_VSCROLL | WB_DRAG );
40 	mpHScrollBar	= new ScrollBar( this, WB_HSCROLL | WB_DRAG );
41 	mpScrollBarBox	= new ScrollBarBox( this );
42 
43 	Link aLink( LINK( this, DialogListBox, ScrollBarHdl ) );
44 	mpVScrollBar->SetScrollHdl( aLink );
45 	mpHScrollBar->SetScrollHdl( aLink );
46 
47 	mbVScroll		= false;
48 	mbHScroll		= false;
49 	mbAutoHScroll	= ( nWinStyle & WB_AUTOHSCROLL ) ? true : false;
50 }
51 
52 // -----------------------------------------------------------------------
53 
54 DialogListBox::~DialogListBox()
55 {
56 	delete mpHScrollBar;
57 	delete mpVScrollBar;
58 	delete mpScrollBarBox;
59 	delete mpChild;
60 }
61 
62 // -----------------------------------------------------------------------
63 
64 void DialogListBox::SetChildWindow( Window* pChild, const Size& rMinSize )
65 {
66 	if( mpChild )
67 		delete mpChild;
68 
69 	mpChild = pChild;
70 	maMinSize = rMinSize;
71 	ImplResizeControls();
72 	ImplCheckScrollBars();
73 }
74 
75 // -----------------------------------------------------------------------
76 
77 void DialogListBox::GetFocus()
78 {
79 	if( mpChild )
80 		mpChild->GrabFocus();
81 }
82 
83 // -----------------------------------------------------------------------
84 
85 ::Window* DialogListBox::GetPreferredKeyInputWindow()
86 {
87 	if( mpChild )
88 		return mpChild;
89 	else
90 		return this;
91 }
92 
93 // -----------------------------------------------------------------------
94 
95 void DialogListBox::Resize()
96 {
97     Control::Resize();
98 	ImplResizeControls();
99 	ImplCheckScrollBars();
100 }
101 
102 // -----------------------------------------------------------------------
103 
104 IMPL_LINK( DialogListBox, ScrollBarHdl, ScrollBar*, EMPTYARG )
105 {
106 	ImplResizeChild();
107 	return 1;
108 }
109 
110 // -----------------------------------------------------------------------
111 
112 void DialogListBox::ImplCheckScrollBars()
113 {
114 	bool bArrange = false;
115 
116 	Size aOutSz = GetOutputSizePixel();
117 
118 	// vert. ScrollBar
119 	if( aOutSz.Height() < maMinSize.Height() )
120 	{
121 		if( !mbVScroll )
122 			bArrange = true;
123 		mbVScroll = true;
124 	}
125 	else
126 	{
127 		if( mbVScroll )
128 			bArrange = true;
129 		mbVScroll = false;
130 	}
131 
132 	// horz. ScrollBar
133 	if( mbAutoHScroll )
134 	{
135 		long nWidth = aOutSz.Width();
136 		if ( mbVScroll )
137 			nWidth -= mpVScrollBar->GetSizePixel().Width();
138 		if( nWidth < maMinSize.Width() )
139 		{
140 			if( !mbHScroll )
141 				bArrange = true;
142 			mbHScroll = true;
143 
144 			if ( !mbVScroll )
145 			{
146 				int nHeight = aOutSz.Height() - mpHScrollBar->GetSizePixel().Height();
147 				if( nHeight < maMinSize.Height() )
148 				{
149 					if( !mbVScroll )
150 						bArrange = true;
151 					mbVScroll = true;
152 				}
153 			}
154 		}
155 		else
156 		{
157 			if( mbHScroll )
158 				bArrange = true;
159 			mbHScroll = false;
160 		}
161 	}
162 
163 	if( bArrange )
164 		ImplResizeControls();
165 
166 	ImplInitScrollBars();
167 }
168 
169 // -----------------------------------------------------------------------
170 
171 void DialogListBox::ImplInitScrollBars()
172 {
173 	if( mpChild )
174 	{
175 		Size aOutSize( GetOutputSizePixel() );
176 		if( mbHScroll ) aOutSize.Height() -= mpHScrollBar->GetSizePixel().Height();
177 		if( mbVScroll ) aOutSize.Width() -= mpVScrollBar->GetSizePixel().Width();
178 
179 		if ( mbVScroll )
180 		{
181 			mpVScrollBar->SetRangeMax( maMinSize.Height() );
182 			mpVScrollBar->SetVisibleSize( aOutSize.Height() );
183 			mpVScrollBar->SetPageSize( 16 );
184 		}
185 
186 		if ( mbHScroll )
187 		{
188 			mpHScrollBar->SetRangeMax( maMinSize.Width() );
189 			mpHScrollBar->SetVisibleSize( aOutSize.Width() );
190 			mpHScrollBar->SetPageSize( 16 );
191 		}
192 	}
193 }
194 
195 // -----------------------------------------------------------------------
196 
197 void DialogListBox::ImplResizeControls()
198 {
199 	Size aOutSz( GetOutputSizePixel() );
200 	long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
201 	nSBWidth = CalcZoom( nSBWidth );
202 
203 	maInnerSize = aOutSz;
204 	if ( mbVScroll )
205 		maInnerSize.Width() -= nSBWidth;
206 	if ( mbHScroll )
207 		maInnerSize.Height() -= nSBWidth;
208 
209 	// ScrollBarBox
210 	if( mbVScroll && mbHScroll )
211 	{
212 		Point aBoxPos( maInnerSize.Width(), maInnerSize.Height() );
213 		mpScrollBarBox->SetPosSizePixel( aBoxPos, Size( nSBWidth, nSBWidth ) );
214 		mpScrollBarBox->Show();
215 	}
216 	else
217 	{
218 		mpScrollBarBox->Hide();
219 	}
220 
221 	// vert. ScrollBar
222 	if( mbVScroll )
223 	{
224 		// Scrollbar on left or right side?
225 		Point aVPos( aOutSz.Width() - nSBWidth, 0 );
226 		mpVScrollBar->SetPosSizePixel( aVPos, Size( nSBWidth, maInnerSize.Height() ) );
227 		mpVScrollBar->Show();
228 	}
229 	else
230 	{
231 		mpVScrollBar->Hide();
232 	}
233 
234 	// horz. ScrollBar
235 	if( mbHScroll )
236 	{
237 		Point aHPos( 0, aOutSz.Height() - nSBWidth );
238 		mpHScrollBar->SetPosSizePixel( aHPos, Size( maInnerSize.Width(), nSBWidth ) );
239 		mpHScrollBar->Show();
240 	}
241 	else
242 	{
243 		mpHScrollBar->Hide();
244 	}
245 
246 	ImplResizeChild();
247 }
248 
249 void DialogListBox::ImplResizeChild()
250 {
251 	Point aWinPos;
252 	Size aSize( maInnerSize );
253 
254 	int nOffset;
255 	if( mbHScroll )
256 	{
257 		nOffset = mpHScrollBar->GetThumbPos();
258 		aWinPos.X() = -nOffset;
259 		aSize.Width() += nOffset;
260 	}
261 
262 	if( mbVScroll )
263 	{
264 		nOffset = mpVScrollBar->GetThumbPos();
265 		aWinPos.Y() = -nOffset;
266 		aSize.Height() += nOffset;
267 	}
268 
269 	mpChild->SetPosSizePixel( aWinPos, aSize );
270 }
271 
272 // -----------------------------------------------------------------------
273 
274 void DialogListBox::StateChanged( StateChangedType nType )
275 {
276 	if ( nType == STATE_CHANGE_INITSHOW )
277 	{
278 		ImplCheckScrollBars();
279 	}
280 	else if ( ( nType == STATE_CHANGE_UPDATEMODE ) || ( nType == STATE_CHANGE_DATA ) )
281 	{
282 		sal_Bool bUpdate = IsUpdateMode();
283 		mpChild->SetUpdateMode( bUpdate );
284 		if ( bUpdate && IsReallyVisible() )
285 			ImplCheckScrollBars();
286 	}
287 	else if( nType == STATE_CHANGE_ENABLE )
288 	{
289 		mpHScrollBar->Enable( IsEnabled() );
290 		mpVScrollBar->Enable( IsEnabled() );
291 		mpScrollBarBox->Enable( IsEnabled() );
292 		Invalidate();
293 	}
294 	else if ( nType == STATE_CHANGE_ZOOM )
295 	{
296 		mpChild->SetZoom( GetZoom() );
297 		Resize();
298 	}
299 	else if ( nType == STATE_CHANGE_CONTROLFONT )
300 	{
301 		mpChild->SetControlFont( GetControlFont() );
302 	}
303 	else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
304 	{
305 		mpChild->SetControlForeground( GetControlForeground() );
306 	}
307 	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
308 	{
309 		mpChild->SetControlBackground( GetControlBackground() );
310 	}
311 	else if( nType == STATE_CHANGE_VISIBLE )
312 	{
313 		mpChild->Show( IsVisible() );
314 	}
315 
316 	Control::StateChanged( nType );
317 }
318 
319 // -----------------------------------------------------------------------
320 
321 long DialogListBox::Notify( NotifyEvent& rNEvt )
322 {
323 	long nDone = 0;
324 	if ( rNEvt.GetType() == EVENT_COMMAND )
325 	{
326 		const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
327 		if ( rCEvt.GetCommand() == COMMAND_WHEEL )
328 		{
329 			const CommandWheelData* pData = rCEvt.GetWheelData();
330 			if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
331 			{
332 				nDone = HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
333 			}
334 		}
335 	}
336 
337 	return nDone ? nDone : Window::Notify( rNEvt );
338 }
339 
340 } //  namespace sd
341