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_svtools.hxx"
26 
27 #define _TASKBAR_CXX
28 
29 #include <tools/list.hxx>
30 #include <tools/debug.hxx>
31 #include <vcl/floatwin.hxx>
32 
33 #include <svtools/taskbar.hxx>
34 
35 // =======================================================================
36 
37 class ImplTaskBarFloat : public FloatingWindow
38 {
39 public:
40 	TaskBar*			mpTaskBar;
41 
42 public:
43 						ImplTaskBarFloat( TaskBar* pTaskBar );
44 };
45 
46 // -----------------------------------------------------------------------
47 
ImplTaskBarFloat(TaskBar * pTaskBar)48 ImplTaskBarFloat::ImplTaskBarFloat( TaskBar* pTaskBar ) :
49 	FloatingWindow( pTaskBar, 0 )
50 {
51 	mpTaskBar	= pTaskBar;
52 }
53 
54 // =======================================================================
55 
56 #define TASKBAR_BORDER				2
57 #define TASKBAR_OFFSIZE 			3
58 #define TASKBAR_OFFX				2
59 #define TASKBAR_OFFY				1
60 #define TASKBAR_BUTTONOFF			5
61 #define TASKBAR_AUTOHIDE_HEIGHT 	2
62 
63 // =======================================================================
64 
TaskBar(Window * pParent,WinBits nWinStyle)65 TaskBar::TaskBar( Window* pParent, WinBits nWinStyle ) :
66 	Window( pParent, WB_3DLOOK )
67 {
68 	mpButtonBar 		= NULL;
69 	mpTaskToolBox		= NULL;
70 	mpStatusBar 		= NULL;
71 	mnStatusWidth		= 0;
72 	mnOldStatusWidth	= 0;
73 	mnLines 			= 1;
74 	mnWinBits			= nWinStyle;
75 	mbStatusText		= sal_False;
76 	mbShowItems 		= sal_False;
77 	mbAutoHide			= sal_False;
78 
79 	ImplInitSettings();
80 }
81 
82 // -----------------------------------------------------------------------
83 
~TaskBar()84 TaskBar::~TaskBar()
85 {
86 	if ( mpButtonBar )
87 		delete mpButtonBar;
88 	if ( mpTaskToolBox )
89 		delete mpTaskToolBox;
90 	if ( mpStatusBar )
91 		delete mpStatusBar;
92 }
93 
94 // -----------------------------------------------------------------------
95 
ImplInitSettings()96 void TaskBar::ImplInitSettings()
97 {
98 	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
99 
100 	Color aColor;
101 	if ( IsControlBackground() )
102 		aColor = GetControlBackground();
103 	else if ( Window::GetStyle() & WB_3DLOOK )
104 		aColor = rStyleSettings.GetFaceColor();
105 	else
106 		aColor = rStyleSettings.GetWindowColor();
107 	SetBackground( aColor );
108 }
109 
110 // -----------------------------------------------------------------------
111 
ImplNewHeight(long nNewHeight)112 void TaskBar::ImplNewHeight( long nNewHeight )
113 {
114 	long nOldHeight = GetSizePixel().Height();
115 	if ( nNewHeight != nOldHeight )
116 	{
117 		long nY = GetPosPixel().Y()-(nNewHeight-nOldHeight);
118 		SetPosSizePixel( 0, nY, 0, nNewHeight,
119 						 WINDOW_POSSIZE_Y | WINDOW_POSSIZE_HEIGHT );
120 		TaskResize();
121 	}
122 }
123 
124 // -----------------------------------------------------------------------
125 
TaskResize()126 void TaskBar::TaskResize()
127 {
128 	maTaskResizeHdl.Call( this );
129 }
130 
131 // -----------------------------------------------------------------------
132 
CreateButtonBar()133 TaskButtonBar* TaskBar::CreateButtonBar()
134 {
135 	return new TaskButtonBar( this );
136 }
137 
138 // -----------------------------------------------------------------------
139 
CreateTaskToolBox()140 TaskToolBox* TaskBar::CreateTaskToolBox()
141 {
142 	return new TaskToolBox( this );
143 }
144 
145 // -----------------------------------------------------------------------
146 
CreateTaskStatusBar()147 TaskStatusBar* TaskBar::CreateTaskStatusBar()
148 {
149 	return new TaskStatusBar( this );
150 }
151 
152 // -----------------------------------------------------------------------
153 
MouseMove(const MouseEvent & rMEvt)154 void TaskBar::MouseMove( const MouseEvent& rMEvt )
155 {
156 	if ( mnWinBits & WB_SIZEABLE )
157 	{
158 		TaskToolBox*	pTempTaskToolBox = GetTaskToolBox();
159 		TaskStatusBar*	pTempStatusBar = GetStatusBar();
160 
161 		if ( pTempTaskToolBox && pTempStatusBar )
162 		{
163 			long			nStatusX = pTempStatusBar->GetPosPixel().X()-TASKBAR_OFFSIZE-2;
164 			long			nMouseX = rMEvt.GetPosPixel().X();
165 			PointerStyle	ePtrStyle;
166 			if ( (nMouseX >= nStatusX-1) && (nMouseX <= nStatusX+3) )
167 				ePtrStyle = POINTER_HSIZEBAR;
168 			else
169 				ePtrStyle = POINTER_ARROW;
170 			Pointer aPtr( ePtrStyle );
171 			SetPointer( aPtr );
172 		}
173 	}
174 }
175 
176 // -----------------------------------------------------------------------
177 
MouseButtonDown(const MouseEvent & rMEvt)178 void TaskBar::MouseButtonDown( const MouseEvent& rMEvt )
179 {
180 	if ( rMEvt.IsLeft() && (mnWinBits & WB_SIZEABLE) )
181 	{
182 		TaskToolBox*	pTempTaskToolBox = GetTaskToolBox();
183 		TaskStatusBar*	pTempStatusBar = GetStatusBar();
184 
185 		if ( pTempTaskToolBox && pTempStatusBar )
186 		{
187 			long	nStatusX = pTempStatusBar->GetPosPixel().X()-TASKBAR_OFFSIZE-2;
188 			long	nMouseX = rMEvt.GetPosPixel().X();
189 			if ( (nMouseX >= nStatusX-1) && (nMouseX <= nStatusX+3) )
190 			{
191 				if ( rMEvt.GetClicks() == 2 )
192 				{
193 					if ( mnStatusWidth )
194 					{
195 						mnStatusWidth = 0;
196 						Resize();
197 					}
198 				}
199 				else
200 				{
201 					StartTracking();
202 					mnOldStatusWidth = mnStatusWidth;
203 					mnMouseOff = nMouseX-nStatusX;
204 				}
205 			}
206 		}
207 	}
208 }
209 
210 // -----------------------------------------------------------------------
211 
Tracking(const TrackingEvent & rTEvt)212 void TaskBar::Tracking( const TrackingEvent& rTEvt )
213 {
214 	if ( rTEvt.IsTrackingEnded() )
215 	{
216 		if ( rTEvt.IsTrackingCanceled() )
217 		{
218 			mnStatusWidth = mnOldStatusWidth;
219 			Resize();
220 			Update();
221 		}
222 	}
223 	else
224 	{
225 		Size aSize = GetOutputSizePixel();
226 
227 		long nMouseX = rTEvt.GetMouseEvent().GetPosPixel().X()-mnMouseOff;
228 		if ( nMouseX < 0 )
229 			nMouseX = 0;
230 		long nMaxX = aSize.Width()-TASKBAR_OFFX-TASKBAR_OFFSIZE-1;
231 		if ( nMouseX > nMaxX )
232 			nMouseX = nMaxX;
233 		mnStatusWidth = aSize.Width()-nMouseX-TASKBAR_OFFX-TASKBAR_OFFSIZE;
234 		Resize();
235 		Update();
236 	}
237 }
238 
239 // -----------------------------------------------------------------------
240 
Paint(const Rectangle & rRect)241 void TaskBar::Paint( const Rectangle& rRect )
242 {
243 	if ( mnWinBits & (WB_BORDER | WB_SIZEABLE) )
244 	{
245 		const StyleSettings&	rStyleSettings = GetSettings().GetStyleSettings();
246 		Size					aSize = GetOutputSizePixel();
247 		long	nY = 0;
248 
249 		if ( mnWinBits & WB_BORDER )
250 		{
251 			SetLineColor( rStyleSettings.GetShadowColor() );
252 			DrawLine( Point( 0, 0 ), Point( aSize.Width()-1, 0 ) );
253 			SetLineColor( rStyleSettings.GetLightColor() );
254 			DrawLine( Point( 0, 1 ), Point( aSize.Width()-1, 1 ) );
255 			nY += 2;
256 		}
257 
258 		if ( (mnWinBits & WB_SIZEABLE) )
259 		{
260 			//TaskButtonBar*	pTempButtonBar = GetButtonBar();
261 			TaskToolBox*	pTempTaskToolBox = GetTaskToolBox();
262 			TaskStatusBar*	pTempStatusBar = GetStatusBar();
263 
264 			if ( pTempTaskToolBox && pTempStatusBar )
265 			{
266 				long nStatusX = pTempStatusBar->GetPosPixel().X()-TASKBAR_OFFSIZE-2;
267 				if ( nStatusX > 0 )
268 				{
269 					SetLineColor( rStyleSettings.GetShadowColor() );
270 					DrawLine( Point( nStatusX, nY ), Point( nStatusX, aSize.Height()-1 ) );
271 					nStatusX++;
272 					SetLineColor( rStyleSettings.GetLightColor() );
273 					DrawLine( Point( nStatusX, nY ), Point( nStatusX, aSize.Height()-1 ) );
274 				}
275 			}
276 		}
277 	}
278 
279 	Window::Paint( rRect );
280 }
281 
282 // -----------------------------------------------------------------------
283 
Resize()284 void TaskBar::Resize()
285 {
286 	if ( !IsReallyShown() )
287 		return;
288 
289 	TaskButtonBar*	pTempButtonBar = GetButtonBar();
290 	TaskToolBox*	pTempTaskToolBox = GetTaskToolBox();
291 	TaskStatusBar*	pTempStatusBar = GetStatusBar();
292 	Point			aToolPos( TASKBAR_OFFX, 0 );
293 	Size			aSize = GetOutputSizePixel();
294 	Size			aStatusSize;
295 	Size			aToolSize( aSize.Width()-(TASKBAR_OFFX*2), 0 );
296 	long			nOldStatusX = -1;
297 	long			nNewStatusX = -1;
298 	long			nTaskHeight = aSize.Height() - (TASKBAR_OFFY*2);
299 
300 	if ( mnWinBits & WB_BORDER )
301 	{
302 		nTaskHeight -= TASKBAR_BORDER;
303 		aToolPos.Y() += TASKBAR_BORDER;
304 	}
305 
306 	if ( pTempButtonBar )
307 	{
308 		sal_uInt16	i = 0;
309 		sal_Bool	bVisibleItems = sal_False;
310 		while ( i < pTempButtonBar->GetItemCount() )
311 		{
312 			if ( pTempButtonBar->IsItemVisible( pTempButtonBar->GetItemId( i ) ) )
313 			{
314 				bVisibleItems = sal_True;
315 				break;
316 			}
317 			i++;
318 		}
319 		if ( mbStatusText || !bVisibleItems )
320 			pTempButtonBar->Hide();
321 		else
322 		{
323 			Size aButtonBarSize = pTempButtonBar->CalcWindowSizePixel();
324 			if ( pTempButtonBar->GetItemCount() )
325 				nTaskHeight = aButtonBarSize.Height();
326 			else
327 				aButtonBarSize.Height() = nTaskHeight;
328 			Point aTempPos = aToolPos;
329 			aTempPos.Y() += (aSize.Height()-aButtonBarSize.Height()-aTempPos.Y())/2;
330 			pTempButtonBar->SetPosSizePixel( aTempPos, aButtonBarSize );
331 			pTempButtonBar->Show();
332 			aToolPos.X() += aButtonBarSize.Width()+TASKBAR_BUTTONOFF;
333 		}
334 	}
335 
336 	if ( pTempStatusBar )
337 	{
338 		aStatusSize = pTempStatusBar->CalcWindowSizePixel();
339 		if ( mnStatusWidth )
340 			aStatusSize.Width() = mnStatusWidth;
341 		if ( !pTempTaskToolBox || mbStatusText )
342 			aStatusSize.Width() = aSize.Width();
343 		long nMaxHeight = aSize.Height()-(TASKBAR_OFFY*2);
344 		if ( mnWinBits & WB_BORDER )
345 			nMaxHeight -= TASKBAR_BORDER;
346 		if ( nMaxHeight+2 > aStatusSize.Height() )
347 			aStatusSize.Height() = nMaxHeight;
348 		Point aPos( aSize.Width()-aStatusSize.Width(), 0 );
349 		if ( pTempTaskToolBox && (mnWinBits & WB_SIZEABLE) && !mbStatusText )
350 		{
351 			long nMinToolWidth = aToolPos.X()+50;
352 			if ( aPos.X() < nMinToolWidth )
353 			{
354 				aStatusSize.Width() -= nMinToolWidth-aPos.X();
355 				aPos.X() = nMinToolWidth;
356 			}
357 		}
358 		if ( aPos.X() < 0 )
359 		{
360 			aStatusSize.Width() = aSize.Width();
361 			aPos.X() = 0;
362 		}
363 		if ( mnWinBits & WB_BORDER )
364 			aPos.Y() += TASKBAR_BORDER;
365 		aPos.Y() += (aSize.Height()-aStatusSize.Height()-aPos.Y())/2;
366 		if ( mnWinBits & WB_SIZEABLE )
367 		{
368 			if ( pTempTaskToolBox )
369 			{
370 				nOldStatusX = pTempStatusBar->GetPosPixel().X()-TASKBAR_OFFSIZE-2;
371 				nNewStatusX = aPos.X()-TASKBAR_OFFSIZE-2;
372 			}
373 		}
374 		pTempStatusBar->SetPosSizePixel( aPos, aStatusSize );
375 		pTempStatusBar->Show();
376 		aToolSize.Width() = aPos.X()-aToolPos.X()-TASKBAR_OFFX;
377 		if ( mnWinBits & WB_SIZEABLE )
378 			aToolSize.Width() -= (TASKBAR_OFFSIZE*2)-2;
379 	}
380 
381 	if ( pTempTaskToolBox )
382 	{
383 		if ( aToolSize.Width() <= 24 )
384 			pTempTaskToolBox->Hide();
385 		else
386 		{
387 			aToolSize.Height() = pTempTaskToolBox->CalcWindowSizePixel().Height();
388 			if ( pTempTaskToolBox->GetItemCount() )
389 				nTaskHeight = aToolSize.Height();
390 			else
391 				aToolSize.Height() = nTaskHeight;
392 			aToolPos.Y() += (aSize.Height()-aToolSize.Height()-aToolPos.Y())/2;
393 			pTempTaskToolBox->SetPosSizePixel( aToolPos, aToolSize );
394 			pTempTaskToolBox->Show();
395 		}
396 	}
397 
398 	if ( nOldStatusX != nNewStatusX )
399 	{
400 		if ( nOldStatusX > 0 )
401 		{
402 			Rectangle aRect( nOldStatusX, 0, nOldStatusX+2, aSize.Height()-1 );
403 			Invalidate( aRect );
404 		}
405 		if ( nNewStatusX > 0 )
406 		{
407 			Rectangle aRect( nNewStatusX, 0, nNewStatusX+2, aSize.Height()-1 );
408 			Invalidate( aRect );
409 		}
410 	}
411 }
412 
413 // -----------------------------------------------------------------------
414 
StateChanged(StateChangedType nType)415 void TaskBar::StateChanged( StateChangedType nType )
416 {
417 	Window::StateChanged( nType );
418 
419 	if ( nType == STATE_CHANGE_INITSHOW )
420 		Format();
421 	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
422 	{
423 		ImplInitSettings();
424 		Invalidate();
425 	}
426 	else if ( nType == STATE_CHANGE_FORMAT )
427 	{
428 		ImplInitSettings();
429 		ImplNewHeight( CalcWindowSizePixel().Height() );
430 		Format();
431 		Invalidate();
432 	}
433 }
434 
435 // -----------------------------------------------------------------------
436 
DataChanged(const DataChangedEvent & rDCEvt)437 void TaskBar::DataChanged( const DataChangedEvent& rDCEvt )
438 {
439 	Window::DataChanged( rDCEvt );
440 
441 	if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
442 		 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
443 		 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
444 		  (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
445 	{
446 		// Asyncronen StateChanged ausloesen, damit sich die
447 		// TaskBar an die neuen Groessen der Child-Fenster
448 		// orientieren kann
449 		PostStateChanged( STATE_CHANGE_FORMAT );
450 	}
451 }
452 
453 // -----------------------------------------------------------------------
454 
Format()455 void TaskBar::Format()
456 {
457 	ImplNewHeight( CalcWindowSizePixel().Height() );
458 	Resize();
459 }
460 
461 // -----------------------------------------------------------------------
462 
SetLines(sal_uInt16 nLines)463 void TaskBar::SetLines( sal_uInt16 nLines )
464 {
465 	mnLines = nLines;
466 }
467 
468 // -----------------------------------------------------------------------
469 
EnableAutoHide(sal_Bool bAutoHide)470 void TaskBar::EnableAutoHide( sal_Bool bAutoHide )
471 {
472 	mbAutoHide = bAutoHide;
473 
474 	if ( mbAutoHide )
475 	{
476 		ImplNewHeight( TASKBAR_AUTOHIDE_HEIGHT );
477 	}
478 	else
479 	{
480 		ImplNewHeight( CalcWindowSizePixel().Height() );
481 	}
482 }
483 
484 // -----------------------------------------------------------------------
485 
ShowStatusText(const String & rText)486 void TaskBar::ShowStatusText( const String& rText )
487 {
488 	if ( mpStatusBar )
489 	{
490 		if ( !mbStatusText )
491 		{
492 			mbStatusText = sal_True;
493 			if ( mpStatusBar->AreItemsVisible() )
494 			{
495 				mbShowItems = sal_True;
496 				mpStatusBar->HideItems();
497 			}
498 			else
499 				mbShowItems = sal_True;
500 			maOldText = mpStatusBar->GetText();
501 			Resize();
502 			mpStatusBar->SetText( rText );
503 			Update();
504 			mpStatusBar->Update();
505 		}
506 		else
507 			mpStatusBar->SetText( rText );
508 	}
509 }
510 
511 // -----------------------------------------------------------------------
512 
HideStatusText()513 void TaskBar::HideStatusText()
514 {
515 	if ( mbStatusText && mpStatusBar )
516 	{
517 		mbStatusText = sal_False;
518 		mpStatusBar->SetText( maOldText );
519 		Resize();
520 		if ( mbShowItems )
521 			mpStatusBar->ShowItems();
522 	}
523 }
524 
525 // -----------------------------------------------------------------------
526 
CalcWindowSizePixel() const527 Size TaskBar::CalcWindowSizePixel() const
528 {
529 	TaskButtonBar*	pTempButtonBar = GetButtonBar();
530 	TaskToolBox*	pTempTaskToolBox = GetTaskToolBox();
531 	TaskStatusBar*	pTempStatusBar = GetStatusBar();
532 	Size			aSize;
533 	long			nTempHeight;
534 
535 	if ( pTempButtonBar && pTempButtonBar->GetItemCount() )
536 		aSize.Height() = pTempButtonBar->CalcWindowSizePixel().Height()+(TASKBAR_OFFY*2);
537 	if ( pTempTaskToolBox && pTempTaskToolBox->GetItemCount() )
538 	{
539 		nTempHeight = pTempTaskToolBox->CalcWindowSizePixel().Height()+(TASKBAR_OFFY*2);
540 		if ( nTempHeight > aSize.Height() )
541 			 aSize.Height() = nTempHeight;
542 	}
543 	if ( pTempStatusBar )
544 	{
545 		nTempHeight = pTempStatusBar->GetSizePixel().Height();
546 		if ( nTempHeight > aSize.Height() )
547 			 aSize.Height() = nTempHeight;
548 	}
549 
550 	if ( mnWinBits & WB_BORDER )
551 		aSize.Height() += TASKBAR_BORDER;
552 
553 	return aSize;
554 }
555 
556 // -----------------------------------------------------------------------
557 
GetButtonBar() const558 TaskButtonBar* TaskBar::GetButtonBar() const
559 {
560 	if ( !mpButtonBar )
561 		((TaskBar*)this)->mpButtonBar = ((TaskBar*)this)->CreateButtonBar();
562 	return mpButtonBar;
563 }
564 
565 // -----------------------------------------------------------------------
566 
GetTaskToolBox() const567 TaskToolBox* TaskBar::GetTaskToolBox() const
568 {
569 	if ( !mpTaskToolBox )
570 		((TaskBar*)this)->mpTaskToolBox = ((TaskBar*)this)->CreateTaskToolBox();
571 	return mpTaskToolBox;
572 }
573 
574 // -----------------------------------------------------------------------
575 
GetStatusBar() const576 TaskStatusBar* TaskBar::GetStatusBar() const
577 {
578 	if ( !mpStatusBar )
579 	{
580 		((TaskBar*)this)->mpStatusBar = ((TaskBar*)this)->CreateTaskStatusBar();
581 		if ( mpStatusBar )
582 			mpStatusBar->mpNotifyTaskBar = (TaskBar*)this;
583 	}
584 	return mpStatusBar;
585 }
586