1 /*****************************************************************************
2 * playlist.cpp: Playlist control
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: playlist.cpp,v 1.2 2003/04/16 21:40:07 ipkiss 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, Window *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 for( int i = PlayList->i_size - 1; i >= 0; i-- )
220 if( Select[i] && i != PlayList->i_index )
221 playlist_Delete( PlayList, i );
229 //---------------------------------------------------------------------------
230 void ControlPlayList::RefreshList()
232 if( NumOfItems != PlayList->i_size )
236 NumOfItems = PlayList->i_size;
237 if( PlayList->i_size > 0 )
239 Select = new bool[NumOfItems];
240 for( int i = 0; i < NumOfItems; i++ )
243 sprintf( Num, " %i", NumOfItems + 1 );
244 TextFont->GetSize( Num, NumWidth, h);
245 FileWidth = CaseWidth - NumWidth - InfoWidth;
248 int Range = PlayList->i_size - Line * Column;
252 Slider->ChangeSliderRange( Range );
253 StartIndex = Slider->GetCursorPosition();
256 //---------------------------------------------------------------------------
257 void ControlPlayList::RefreshAll()
259 ParentWindow->Refresh( TextLeft, TextTop, TextWidth, TextHeight );
261 //---------------------------------------------------------------------------
262 void ControlPlayList::Draw( int x, int y, int w, int h, Graphics *dest )
269 Slider->Draw( x, y, w, h, dest );
272 if( GetIntersectRgn( x, y, w, h, TextLeft, TextTop, TextWidth, TextHeight,
275 // Change clipping region
276 Region *destClipRgn = (Region *)new OSRegion( 0, 0, w, h );
277 TextClipRgn->Move( TextLeft - x, TextTop - y );
278 dest->SetClipRegion( TextClipRgn );
281 DrawAllCase( dest, x, y, wI, hI );
283 // Reset clipping region to old region
284 dest->SetClipRegion( destClipRgn );
286 TextClipRgn->Move( x - TextLeft, y - TextTop );
289 //---------------------------------------------------------------------------
290 void ControlPlayList::DrawAllCase( Graphics *dest, int x, int y, int w, int h )
293 for( i = 0; i < PlayList->i_size - StartIndex && i < Line * Column; i++ )
295 DrawCase( dest, i + StartIndex, x, y, w, h );
298 //---------------------------------------------------------------------------
299 void ControlPlayList::DrawCase( Graphics *dest, int i, int x, int y, int w,
302 // Test if case is in range
303 int j = i - StartIndex;
304 if( j < 0 || j >= Line * Column )
307 // Draw background if selected
312 TextTop + j * CaseHeight - y,
313 CaseRight[j] - CaseLeft[j],
321 if( PlayList->i_index == i )
327 sprintf( Num, "%i", i + 1 );
330 CaseTextLeft[j] - x, TextTop + j * CaseHeight - y,
331 NumWidth - Margin, CaseHeight, DT_RIGHT );
336 NumWidth + Margin + CaseTextLeft[j] - x,
337 TextTop + j * CaseHeight - y,
338 FileWidth - 2 * Margin, CaseHeight, DT_LEFT );
343 NumWidth + FileWidth + Margin + CaseTextLeft[j] - x,
344 TextTop + j * CaseHeight - y,
345 InfoWidth - Margin, CaseHeight, DT_CENTER );
347 //---------------------------------------------------------------------------
348 char * ControlPlayList::GetFileName( int i )
352 return PlayList->pp_items[i]->psz_name;
356 string f = PlayList->pp_items[i]->psz_name;
357 int pos = f.rfind( DIRECTORY_SEPARATOR, f.size() );
358 return PlayList->pp_items[i]->psz_name + pos + 1;
361 //---------------------------------------------------------------------------
362 void ControlPlayList::MoveRelative( int xOff, int yOff )
364 Slider->MoveRelative( xOff, yOff );
369 for( int i = 1; i < Line; i++ )
372 CaseTextLeft[i] += xOff;
373 CaseRight[i] += xOff;
376 //---------------------------------------------------------------------------
377 double ControlPlayList::Dist( int x1, int y1, int x2, int y2 )
379 return sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
381 //---------------------------------------------------------------------------
382 bool ControlPlayList::MouseDown( int x, int y, int button )
387 // If hit into slider
388 if( Slider->MouseDown( x, y, button ) )
390 int New = Slider->GetCursorPosition();
391 if( New != StartIndex )
394 ParentWindow->Refresh( TextLeft,TextTop,TextWidth,TextHeight );
399 if( !TextClipRgn->Hit( x - TextLeft, y - TextTop ) )
404 for( i = 0; i < PlayList->i_size - StartIndex && i < Line * Column; i++)
406 if( x >= CaseLeft[i] && x <= CaseRight[i] && y >= TextTop +
407 i * CaseHeight && y < TextTop + (i + 1) * CaseHeight )
409 for( j = 0; j < NumOfItems; j++ )
411 if( j == i + StartIndex )
412 Select[j] = !Select[j];
421 //---------------------------------------------------------------------------
422 bool ControlPlayList::MouseUp( int x, int y, int button )
427 // If hit into slider
428 if( Slider->MouseUp( x, y, button ) )
433 //---------------------------------------------------------------------------
434 bool ControlPlayList::MouseMove( int x, int y, int button )
436 if( !Enabled || !button )
439 // If hit into slider
440 if( Slider->MouseMove( x, y, button ) )
442 int New = Slider->GetCursorPosition();
443 if( New != StartIndex )
453 //---------------------------------------------------------------------------
454 bool ControlPlayList::MouseOver( int x, int y )
456 if( TextClipRgn->Hit( x - Left, y - Top ) || Slider->MouseOver( x, y ) )
461 //---------------------------------------------------------------------------
462 bool ControlPlayList::MouseDblClick( int x, int y, int button )
464 if( !Enabled || button != 1 )
469 if( !TextClipRgn->Hit( x - TextLeft, y - TextTop ) )
472 for( i = 0; i < PlayList->i_size - StartIndex && i < Line * Column; i++ )
474 if( x >= CaseLeft[i] && x <= CaseRight[i] && y >=
475 TextTop + i * CaseHeight && y < TextTop + (i + 1) * CaseHeight )
477 playlist_Goto( PlayList, i + StartIndex );
478 OSAPI_PostMessage( NULL, VLC_INTF_REFRESH, 0, (int)false );
484 //---------------------------------------------------------------------------
485 bool ControlPlayList::ToolTipTest( int x, int y )
491 for( i = 0; i < PlayList->i_size - StartIndex && i < Line * Column; i++ )
493 if( x >= CaseLeft[i] && x <= CaseRight[i] && y >=
494 TextTop + i * CaseHeight && y < TextTop + (i + 1) * CaseHeight )
496 TextFont->GetSize( PlayList->pp_items[i + StartIndex]->psz_name, w,
500 ParentWindow->ChangeToolTipText(
501 (string)PlayList->pp_items[i + StartIndex]->psz_name );
508 //---------------------------------------------------------------------------
509 void ControlPlayList::InitSliderCurve( double *ptx, double *pty, int nb,
510 string scroll_up, string scroll_down )
512 Slider = new ControlSlider( "none", true, "none", scroll_up, scroll_down,
513 ptx, pty, nb, "none", "", ParentWindow );
515 //---------------------------------------------------------------------------