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