1 /*****************************************************************************
2 * playlist.cpp: Playlist control
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: playlist.cpp,v 1.14 2003/06/09 14:04:20 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()
96 delete[] CaseTextLeft;
106 if( PlayList != NULL )
108 vlc_object_release( PlayList );
111 //---------------------------------------------------------------------------
112 void ControlPlayList::Init()
118 UpdateEvent = p_intf->p_sys->p_theme->EvtBank->Get( "playlist_refresh" );
119 TextFont = p_intf->p_sys->p_theme->FntBank->Get( FontName );
120 if( PlayFontName == "none" )
121 PlayFont = p_intf->p_sys->p_theme->FntBank->Get( FontName );
123 PlayFont = p_intf->p_sys->p_theme->FntBank->Get( PlayFontName );
125 TextFont->GetSize( "lp", h, CaseHeight );
127 // Get bitmap from list
130 // Get points for Text curve
131 h = TextCurve->GetNumOfDifferentPoints();
134 TextCurve->GetDifferentPoints( x, y, 0, 0 );
136 // Get top of first point
137 TextCurve->GetPoint( 0, i, TextTop );
139 // Set number of lines
141 for( i = 0; i < h; i++ )
143 if( ( Line + 1 ) * CaseHeight < y[i] - TextTop )
146 CaseLeft = new int[Line];
147 CaseRight = new int[Line];
148 CaseTextLeft = new int[Line];
149 for( i = 0; i < Line; i++ )
151 CaseLeft[i] = x[i * CaseHeight];
152 CaseTextLeft[i] = x[i * CaseHeight];
153 for( j = 1; j < CaseHeight; j++ )
155 if( x[i * CaseHeight + j] < CaseLeft[i] )
156 CaseLeft[i] = x[i * CaseHeight + j];
157 if( x[i * CaseHeight + j] > CaseTextLeft[i] )
158 CaseTextLeft[i] = x[i * CaseHeight + j];
160 CaseRight[i] = CaseTextLeft[i] + CaseWidth;
163 // Get size of text zone
164 TextHeight = Line * CaseHeight;
165 TextLeft = CaseLeft[0];
166 TextWidth = CaseRight[0];
167 for( i = 1; i < Line; i++ )
169 if( CaseLeft[i] < TextLeft )
170 TextLeft = CaseLeft[i];
171 if( CaseRight[i] > TextWidth )
172 TextWidth = CaseRight[i];
174 TextWidth -= TextLeft;
176 // Set Text Clipping Region
177 TextClipRgn = (SkinRegion *)new OSRegion;
178 for( i = 0; i < Line; i++ )
180 for( j = 0; j < CaseHeight; j++ )
182 h = i * CaseHeight + j;
183 TextClipRgn->AddRectangle( x[h] - TextLeft, h, CaseWidth, 1 );
187 // Curve is no more needed so delete it
192 // Get size of control
193 Left = Slider->GetLeft();
194 Top = Slider->GetTop();
195 Width = Slider->GetLeft() + Slider->GetWidth();
196 Height = Slider->GetTop() + Slider->GetHeight();
197 if( TextLeft < Left )
201 if( TextLeft + TextWidth > Width )
202 Width = TextLeft + TextWidth;
203 if( TextTop + TextHeight > Height )
204 Height = TextTop + TextHeight;
209 PlayList = (playlist_t *)
210 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
211 if( PlayList == NULL )
212 msg_Err( p_intf, "cannot find a playlist object" );
215 Slider->Enable( p_intf->p_sys->p_theme->EvtBank->Get( "none" ), true );
218 //---------------------------------------------------------------------------
219 bool ControlPlayList::ProcessEvent( Event *evt )
221 switch( evt->GetMessage() )
224 Enable( (Event*)evt->GetParam1(), (bool)evt->GetParam2() );
228 if( UpdateEvent->IsEqual( (Event*)evt->GetParam1() ) )
235 case PLAYLIST_ID_DEL:
236 if( (GenericControl *)evt->GetParam1() == this )
238 for( int i = PlayList->i_size - 1; i >= 0; i-- )
240 if( Select[i] && i != PlayList->i_index )
241 playlist_Delete( PlayList, i );
250 //---------------------------------------------------------------------------
251 void ControlPlayList::RefreshList()
253 vlc_mutex_lock( &PlayList->object_lock );
255 if( NumOfItems != PlayList->i_size )
259 NumOfItems = PlayList->i_size;
260 if( PlayList->i_size > 0 )
262 Select = new bool[NumOfItems];
263 for( int i = 0; i < NumOfItems; i++ )
266 sprintf( Num, " %i", NumOfItems + 1 );
267 TextFont->GetSize( Num, NumWidth, h);
268 FileWidth = CaseWidth - NumWidth - InfoWidth;
271 int Range = PlayList->i_size - Line * Column;
275 Slider->ChangeSliderRange( Range );
276 StartIndex = Slider->GetCursorPosition();
279 vlc_mutex_unlock( &PlayList->object_lock );
281 //---------------------------------------------------------------------------
282 void ControlPlayList::RefreshAll()
284 ParentWindow->Refresh( TextLeft, TextTop, TextWidth, TextHeight );
286 //---------------------------------------------------------------------------
287 void ControlPlayList::Draw( int x, int y, int w, int h, Graphics *dest )
294 Slider->Draw( x, y, w, h, dest );
297 if( GetIntersectRgn( x, y, w, h, TextLeft, TextTop, TextWidth, TextHeight,
300 // Change clipping region
301 SkinRegion *destClipRgn = (SkinRegion *)new OSRegion( 0, 0, w, h );
302 TextClipRgn->Move( TextLeft - x, TextTop - y );
303 dest->SetClipRegion( TextClipRgn );
306 DrawAllCase( dest, x, y, wI, hI );
308 // Reset clipping region to old region
309 dest->SetClipRegion( destClipRgn );
311 TextClipRgn->Move( x - TextLeft, y - TextTop );
314 //---------------------------------------------------------------------------
315 void ControlPlayList::DrawAllCase( Graphics *dest, int x, int y, int w, int h )
318 for( i = 0; i < NumOfItems - StartIndex && i < Line * Column; i++ )
320 DrawCase( dest, i + StartIndex, x, y, w, h );
323 //---------------------------------------------------------------------------
324 void ControlPlayList::DrawCase( Graphics *dest, int i, int x, int y, int w,
327 // Test if case is in range
328 int j = i - StartIndex;
329 if( j < 0 || j >= Line * Column )
332 // Draw background if selected
337 TextTop + j * CaseHeight - y,
338 CaseRight[j] - CaseLeft[j],
346 if( PlayList->i_index == i )
352 sprintf( Num, "%i", i + 1 );
355 CaseTextLeft[j] - x, TextTop + j * CaseHeight - y,
356 NumWidth - Margin, CaseHeight, VLC_FONT_ALIGN_RIGHT );
361 NumWidth + Margin + CaseTextLeft[j] - x,
362 TextTop + j * CaseHeight - y,
363 FileWidth - 2 * Margin, CaseHeight, VLC_FONT_ALIGN_LEFT );
368 NumWidth + FileWidth + Margin + CaseTextLeft[j] - x,
369 TextTop + j * CaseHeight - y,
370 InfoWidth - Margin, CaseHeight, VLC_FONT_ALIGN_CENTER );
372 //---------------------------------------------------------------------------
373 char * ControlPlayList::GetFileName( int i )
377 return PlayList->pp_items[i]->psz_name;
381 string f = PlayList->pp_items[i]->psz_name;
382 int pos = f.rfind( DIRECTORY_SEPARATOR, f.size() );
383 return PlayList->pp_items[i]->psz_name + pos + 1;
386 //---------------------------------------------------------------------------
387 void ControlPlayList::MoveRelative( int xOff, int yOff )
389 Slider->MoveRelative( xOff, yOff );
394 for( int i = 1; i < Line; i++ )
397 CaseTextLeft[i] += xOff;
398 CaseRight[i] += xOff;
401 //---------------------------------------------------------------------------
402 double ControlPlayList::Dist( int x1, int y1, int x2, int y2 )
404 return sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
406 //---------------------------------------------------------------------------
407 bool ControlPlayList::MouseDown( int x, int y, int button )
412 // If hit into slider
413 if( Slider->MouseDown( x, y, button ) )
415 int New = Slider->GetCursorPosition();
416 if( New != StartIndex )
419 ParentWindow->Refresh( TextLeft,TextTop,TextWidth,TextHeight );
424 if( !TextClipRgn->Hit( x - TextLeft, y - TextTop ) )
429 for( i = 0; i < PlayList->i_size - StartIndex && i < Line * Column; i++)
431 if( x >= CaseLeft[i] && x <= CaseRight[i] && y >= TextTop +
432 i * CaseHeight && y < TextTop + (i + 1) * CaseHeight )
434 for( j = 0; j < NumOfItems; j++ )
436 if( button & KEY_CTRL )
439 if( j == i + StartIndex )
441 Select[j] = !Select[j];
446 // CTRL is not pressed
447 Select[j] = ( j == i + StartIndex );
457 //---------------------------------------------------------------------------
458 bool ControlPlayList::MouseUp( int x, int y, int button )
463 // If hit into slider
464 if( Slider->MouseUp( x, y, button ) )
469 //---------------------------------------------------------------------------
470 bool ControlPlayList::MouseMove( int x, int y, int button )
472 if( !Enabled || !button )
475 // If hit into slider
476 if( Slider->MouseMove( x, y, button ) )
478 int New = Slider->GetCursorPosition();
479 if( New != StartIndex )
489 //---------------------------------------------------------------------------
490 bool ControlPlayList::MouseScroll( int x, int y, int direction )
495 if( !TextClipRgn->Hit( x - Left, y - Top ) && !Slider->MouseOver( x, y ) )
498 long pos = StartIndex;
501 case MOUSE_SCROLL_UP:
504 case MOUSE_SCROLL_DOWN:
505 if( pos + Line < NumOfItems ) pos++;
509 Slider->SetCursorPosition( pos );
513 //---------------------------------------------------------------------------
514 bool ControlPlayList::MouseOver( int x, int y )
516 if( TextClipRgn->Hit( x - Left, y - Top ) || Slider->MouseOver( x, y ) )
521 //---------------------------------------------------------------------------
522 bool ControlPlayList::MouseDblClick( int x, int y, int button )
524 if( !Enabled || button != 1 )
529 if( !TextClipRgn->Hit( x - TextLeft, y - TextTop ) )
532 for( i = 0; i < PlayList->i_size - StartIndex && i < Line * Column; i++ )
534 if( x >= CaseLeft[i] && x <= CaseRight[i] && y >=
535 TextTop + i * CaseHeight && y < TextTop + (i + 1) * CaseHeight )
537 playlist_Goto( PlayList, i + StartIndex );
538 OSAPI_PostMessage( NULL, VLC_INTF_REFRESH, 0, (int)false );
544 //---------------------------------------------------------------------------
545 bool ControlPlayList::ToolTipTest( int x, int y )
551 for( i = 0; i < PlayList->i_size - StartIndex && i < Line * Column; i++ )
553 if( x >= CaseLeft[i] && x <= CaseRight[i] && y >=
554 TextTop + i * CaseHeight && y < TextTop + (i + 1) * CaseHeight )
556 TextFont->GetSize( PlayList->pp_items[i + StartIndex]->psz_name, w,
560 ParentWindow->ChangeToolTipText(
561 (string)PlayList->pp_items[i + StartIndex]->psz_name );
568 //---------------------------------------------------------------------------
569 void ControlPlayList::InitSliderCurve( double *ptx, double *pty, int nb,
570 string scroll_up, string scroll_down )
572 Slider = new ControlSlider( "none", true, "none", scroll_up, scroll_down,
573 ptx, pty, nb, "none", "", ParentWindow );
575 //---------------------------------------------------------------------------