1 /*****************************************************************************
2 * playlist.cpp: Playlist control
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: playlist.cpp,v 1.9 2003/04/21 22:12:37 asmax Exp $
7 * Authors: Olivier Teulière <ipkiss@via.ecp.fr>
8 * Emmanuel Puig <karibu@via.ecp.fr>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program 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 General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111,
24 *****************************************************************************/
27 //--- GENERAL ---------------------------------------------------------------
30 //--- VLC -------------------------------------------------------------------
33 //--- SKIN ------------------------------------------------------------------
34 #include "../os_api.h"
35 #include "../src/bitmap.h"
36 #include "../src/banks.h"
37 #include "../src/bezier.h"
38 #include "../src/graphics.h"
39 #include "../os_graphics.h"
40 #include "../src/font.h"
41 #include "../os_font.h"
45 #include "../src/event.h"
46 #include "../src/theme.h"
47 #include "../src/window.h"
48 #include "../src/skin_common.h"
52 //---------------------------------------------------------------------------
54 //---------------------------------------------------------------------------
55 ControlPlayList::ControlPlayList( string id, bool visible, int width,
56 int infowidth, string font, string playfont, int selcolor, double *ptx,
57 double *pty, int nb, bool longfilename, string help, SkinWindow *Parent )
58 : GenericControl( id, visible, help, Parent )
67 PlayFontName = playfont;
71 InfoWidth = infowidth;
76 SelectColor = selcolor;
77 TextCurve = new Bezier( ptx, pty, nb, BEZIER_PTS_Y );
78 LongFileName = longfilename;
83 //---------------------------------------------------------------------------
84 ControlPlayList::~ControlPlayList()
86 if( PlayList != NULL )
88 vlc_object_release( PlayList );
91 //---------------------------------------------------------------------------
92 void ControlPlayList::Init()
98 UpdateEvent = p_intf->p_sys->p_theme->EvtBank->Get( "playlist_refresh" );
99 TextFont = p_intf->p_sys->p_theme->FntBank->Get( FontName );
100 if( PlayFontName == "none" )
101 PlayFont = p_intf->p_sys->p_theme->FntBank->Get( FontName );
103 PlayFont = p_intf->p_sys->p_theme->FntBank->Get( PlayFontName );
105 TextFont->GetSize( "lp", h, CaseHeight );
107 // Get bitmap from list
110 // Get points for Text curve
111 h = TextCurve->GetNumOfDifferentPoints();
114 TextCurve->GetDifferentPoints( x, y, 0, 0 );
116 // Get top of first point
117 TextCurve->GetPoint( 0, i, TextTop );
119 // Set number of lines
121 for( i = 0; i < h; i++ )
123 if( ( Line + 1 ) * CaseHeight < y[i] - TextTop )
126 CaseLeft = new int[Line];
127 CaseRight = new int[Line];
128 CaseTextLeft = new int[Line];
129 for( i = 0; i < Line; i++ )
131 CaseLeft[i] = x[i * CaseHeight];
132 CaseTextLeft[i] = x[i * CaseHeight];
133 for( j = 1; j < CaseHeight; j++ )
135 if( x[i * CaseHeight + j] < CaseLeft[i] )
136 CaseLeft[i] = x[i * CaseHeight + j];
137 if( x[i * CaseHeight + j] > CaseTextLeft[i] )
138 CaseTextLeft[i] = x[i * CaseHeight + j];
140 CaseRight[i] = CaseTextLeft[i] + CaseWidth;
143 // Get size of text zone
144 TextHeight = Line * CaseHeight;
145 TextLeft = CaseLeft[0];
146 TextWidth = CaseRight[0];
147 for( i = 1; i < Line; i++ )
149 if( CaseLeft[i] < TextLeft )
150 TextLeft = CaseLeft[i];
151 if( CaseRight[i] > TextWidth )
152 TextWidth = CaseRight[i];
154 TextWidth -= TextLeft;
156 // Set Text Clipping Region
157 TextClipRgn = (Region *)new OSRegion;
158 for( i = 0; i < Line; i++ )
160 for( j = 0; j < CaseHeight; j++ )
162 h = i * CaseHeight + j;
163 TextClipRgn->AddRectangle( x[h] - TextLeft, h, CaseWidth, 1 );
167 // Curve is no more needed so delete it
172 // Get size of control
175 Width = Slider->Left + Slider->Width;
176 Height = Slider->Top + Slider->Height;
177 if( TextLeft < Left )
181 if( TextLeft + TextWidth > Width )
182 Width = TextLeft + TextWidth;
183 if( TextTop + TextHeight > Height )
184 Height = TextTop + TextHeight;
189 PlayList = (playlist_t *)
190 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
191 if( PlayList == NULL )
192 msg_Err( p_intf, "cannot find a playlist object" );
195 Slider->Enable( p_intf->p_sys->p_theme->EvtBank->Get( "none" ), true );
198 //---------------------------------------------------------------------------
199 bool ControlPlayList::ProcessEvent( Event *evt )
201 switch( evt->GetMessage() )
204 Enable( (Event*)evt->GetParam1(), (bool)evt->GetParam2() );
208 if( UpdateEvent->IsEqual( (Event*)evt->GetParam1() ) )
215 case PLAYLIST_ID_DEL:
216 if( (GenericControl *)evt->GetParam1() == this )
218 vlc_mutex_lock( &PlayList->object_lock );
219 for( int i = PlayList->i_size - 1; i >= 0; i-- )
221 if( Select[i] && i != PlayList->i_index )
222 playlist_Delete( PlayList, i );
224 vlc_mutex_unlock( &PlayList->object_lock );
231 //---------------------------------------------------------------------------
232 void ControlPlayList::RefreshList()
234 vlc_mutex_lock( &PlayList->object_lock );
236 if( NumOfItems != PlayList->i_size )
240 NumOfItems = PlayList->i_size;
241 if( PlayList->i_size > 0 )
243 Select = new bool[NumOfItems];
244 for( int i = 0; i < NumOfItems; i++ )
247 sprintf( Num, " %i", NumOfItems + 1 );
248 TextFont->GetSize( Num, NumWidth, h);
249 FileWidth = CaseWidth - NumWidth - InfoWidth;
252 int Range = PlayList->i_size - Line * Column;
256 Slider->ChangeSliderRange( Range );
257 StartIndex = Slider->GetCursorPosition();
260 vlc_mutex_unlock( &PlayList->object_lock );
262 //---------------------------------------------------------------------------
263 void ControlPlayList::RefreshAll()
265 ParentWindow->Refresh( TextLeft, TextTop, TextWidth, TextHeight );
267 //---------------------------------------------------------------------------
268 void ControlPlayList::Draw( int x, int y, int w, int h, Graphics *dest )
275 Slider->Draw( x, y, w, h, dest );
278 if( GetIntersectRgn( x, y, w, h, TextLeft, TextTop, TextWidth, TextHeight,
281 // Change clipping region
282 Region *destClipRgn = (Region *)new OSRegion( 0, 0, w, h );
283 TextClipRgn->Move( TextLeft - x, TextTop - y );
284 dest->SetClipRegion( TextClipRgn );
287 DrawAllCase( dest, x, y, wI, hI );
289 // Reset clipping region to old region
290 dest->SetClipRegion( destClipRgn );
292 TextClipRgn->Move( x - TextLeft, y - TextTop );
295 //---------------------------------------------------------------------------
296 void ControlPlayList::DrawAllCase( Graphics *dest, int x, int y, int w, int h )
299 for( i = 0; i < NumOfItems - StartIndex && i < Line * Column; i++ )
301 DrawCase( dest, i + StartIndex, x, y, w, h );
304 //---------------------------------------------------------------------------
305 void ControlPlayList::DrawCase( Graphics *dest, int i, int x, int y, int w,
308 // Test if case is in range
309 int j = i - StartIndex;
310 if( j < 0 || j >= Line * Column )
313 // Draw background if selected
318 TextTop + j * CaseHeight - y,
319 CaseRight[j] - CaseLeft[j],
327 if( PlayList->i_index == i )
333 sprintf( Num, "%i", i + 1 );
336 CaseTextLeft[j] - x, TextTop + j * CaseHeight - y,
337 NumWidth - Margin, CaseHeight, VLC_FONT_ALIGN_RIGHT );
342 NumWidth + Margin + CaseTextLeft[j] - x,
343 TextTop + j * CaseHeight - y,
344 FileWidth - 2 * Margin, CaseHeight, VLC_FONT_ALIGN_LEFT );
349 NumWidth + FileWidth + Margin + CaseTextLeft[j] - x,
350 TextTop + j * CaseHeight - y,
351 InfoWidth - Margin, CaseHeight, VLC_FONT_ALIGN_CENTER );
353 //---------------------------------------------------------------------------
354 char * ControlPlayList::GetFileName( int i )
358 return PlayList->pp_items[i]->psz_name;
362 string f = PlayList->pp_items[i]->psz_name;
363 int pos = f.rfind( DIRECTORY_SEPARATOR, f.size() );
364 return PlayList->pp_items[i]->psz_name + pos + 1;
367 //---------------------------------------------------------------------------
368 void ControlPlayList::MoveRelative( int xOff, int yOff )
370 Slider->MoveRelative( xOff, yOff );
375 for( int i = 1; i < Line; i++ )
378 CaseTextLeft[i] += xOff;
379 CaseRight[i] += xOff;
382 //---------------------------------------------------------------------------
383 double ControlPlayList::Dist( int x1, int y1, int x2, int y2 )
385 return sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
387 //---------------------------------------------------------------------------
388 bool ControlPlayList::MouseDown( int x, int y, int button )
393 // If hit into slider
394 if( Slider->MouseDown( x, y, button ) )
396 int New = Slider->GetCursorPosition();
397 if( New != StartIndex )
400 ParentWindow->Refresh( TextLeft,TextTop,TextWidth,TextHeight );
405 if( !TextClipRgn->Hit( x - TextLeft, y - TextTop ) )
410 for( i = 0; i < PlayList->i_size - StartIndex && i < Line * Column; i++)
412 if( x >= CaseLeft[i] && x <= CaseRight[i] && y >= TextTop +
413 i * CaseHeight && y < TextTop + (i + 1) * CaseHeight )
415 for( j = 0; j < NumOfItems; j++ )
417 if( j == i + StartIndex )
418 Select[j] = !Select[j];
427 //---------------------------------------------------------------------------
428 bool ControlPlayList::MouseUp( int x, int y, int button )
433 // If hit into slider
434 if( Slider->MouseUp( x, y, button ) )
439 //---------------------------------------------------------------------------
440 bool ControlPlayList::MouseMove( int x, int y, int button )
442 if( !Enabled || !button )
445 // If hit into slider
446 if( Slider->MouseMove( x, y, button ) )
448 int New = Slider->GetCursorPosition();
449 if( New != StartIndex )
459 //---------------------------------------------------------------------------
460 bool ControlPlayList::MouseScroll( int x, int y, int direction )
465 if( !TextClipRgn->Hit( x - Left, y - Top ) && !Slider->MouseOver( x, y ) )
468 long pos = StartIndex;
471 case MOUSE_SCROLL_UP:
474 case MOUSE_SCROLL_DOWN:
475 if( pos + Line < NumOfItems ) pos++;
479 Slider->SetCursorPosition( pos );
483 //---------------------------------------------------------------------------
484 bool ControlPlayList::MouseOver( int x, int y )
486 if( TextClipRgn->Hit( x - Left, y - Top ) || Slider->MouseOver( x, y ) )
491 //---------------------------------------------------------------------------
492 bool ControlPlayList::MouseDblClick( int x, int y, int button )
494 if( !Enabled || button != 1 )
499 if( !TextClipRgn->Hit( x - TextLeft, y - TextTop ) )
502 for( i = 0; i < PlayList->i_size - StartIndex && i < Line * Column; i++ )
504 if( x >= CaseLeft[i] && x <= CaseRight[i] && y >=
505 TextTop + i * CaseHeight && y < TextTop + (i + 1) * CaseHeight )
507 playlist_Goto( PlayList, i + StartIndex );
508 OSAPI_PostMessage( NULL, VLC_INTF_REFRESH, 0, (int)false );
514 //---------------------------------------------------------------------------
515 bool ControlPlayList::ToolTipTest( int x, int y )
521 for( i = 0; i < PlayList->i_size - StartIndex && i < Line * Column; i++ )
523 if( x >= CaseLeft[i] && x <= CaseRight[i] && y >=
524 TextTop + i * CaseHeight && y < TextTop + (i + 1) * CaseHeight )
526 TextFont->GetSize( PlayList->pp_items[i + StartIndex]->psz_name, w,
530 ParentWindow->ChangeToolTipText(
531 (string)PlayList->pp_items[i + StartIndex]->psz_name );
538 //---------------------------------------------------------------------------
539 void ControlPlayList::InitSliderCurve( double *ptx, double *pty, int nb,
540 string scroll_up, string scroll_down )
542 Slider = new ControlSlider( "none", true, "none", scroll_up, scroll_down,
543 ptx, pty, nb, "none", "", ParentWindow );
545 //---------------------------------------------------------------------------