Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

PageTimeline Class Reference

This class defines the Page behaviour of the Timeline notebook page. More...

#include <page_timeline.h>

Inheritance diagram for PageTimeline:

Inheritance graph
[legend]
Collaboration diagram for PageTimeline:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 PageTimeline (KinoCommon *common)
virtual ~PageTimeline ()
gulong activate ()
void start ()
void selectScene (int)
void showIcons ()
void refresh ()
gboolean processKeyboard (GdkEventKey *event)
gboolean processCommand (char *cmd)
void timeFormatChanged ()
GtkListStore * getModel () const
GtkIconView * getView () const
void * Thread ()

Static Private Member Functions

static void * ThreadProxy (void *arg)

Private Attributes

KinoCommoncommon
bool refresh_required
int action
int last_begin
int last_end
int scene
GtkIconView * view
GtkListStore * model
pthread_t thread
pthread_mutex_t key
pthread_mutex_t mutex
enum TimelineStatus showIconsRunning

Detailed Description

This class defines the Page behaviour of the Timeline notebook page.

Definition at line 40 of file page_timeline.h.


Constructor & Destructor Documentation

PageTimeline::PageTimeline KinoCommon common  ) 
 

Definition at line 175 of file page_timeline.cc.

References COLUMN_ICON, COLUMN_TIME, KinoCommon::getWidget(), key, lookup_widget(), model, mutex, N_COLUMNS, on_iconlist_refresh_required(), on_iconview_timeline_item_activated(), on_iconview_timeline_selection_changed(), and view.

00175                                                :
00176         refresh_required( false ), action( 0 ),
00177         last_begin( 0 ), last_end( 0 ), scene( -1 ),
00178         showIconsRunning( TIMELINE_INIT )
00179 {
00180     this->common = common;
00181 
00182     view = GTK_ICON_VIEW( lookup_widget( common->getWidget(), "iconview_timeline" ) );
00183     g_signal_connect( G_OBJECT( view ), "expose_event", G_CALLBACK( on_iconlist_refresh_required ), this );
00184     g_signal_connect( G_OBJECT( view ), "item-activated", G_CALLBACK( on_iconview_timeline_item_activated ), this );
00185     g_signal_connect( G_OBJECT( view ), "selection-changed", G_CALLBACK( on_iconview_timeline_selection_changed ), this );
00186     model = gtk_list_store_new( N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT );
00187     gtk_icon_view_set_model( view, GTK_TREE_MODEL( model ) );
00188     gtk_icon_view_set_pixbuf_column( view, COLUMN_ICON );
00189     gtk_icon_view_set_text_column( view, COLUMN_TIME );
00190     pthread_mutex_init( &key, NULL );
00191     pthread_mutex_init( &mutex, NULL );
00192 }

virtual PageTimeline::~PageTimeline  )  [inline, virtual]
 

Definition at line 60 of file page_timeline.h.

00061     { }


Member Function Documentation

gulong PageTimeline::activate  )  [virtual]
 

Reimplemented from Page.

Definition at line 276 of file page_timeline.cc.

References SCENE_LIST.

00277 {
00278     return SCENE_LIST;
00279 }

GtkListStore* PageTimeline::getModel  )  const [inline]
 

Definition at line 70 of file page_timeline.h.

References model.

Referenced by on_iconview_timeline_item_activated(), and on_iconview_timeline_selection_changed().

00071     {
00072         return model;
00073     }

GtkIconView* PageTimeline::getView  )  const [inline]
 

Definition at line 74 of file page_timeline.h.

References view.

Referenced by on_iconview_timeline_selection_changed().

00075     {
00076         return view;
00077     }

gboolean PageTimeline::processCommand char *  cmd  )  [virtual]
 

Reimplemented from Page.

Definition at line 469 of file page_timeline.cc.

References CAPTURE_FRAME_APPEND, CAPTURE_MOVIE_APPEND, KinoCommon::changePageRequest(), common, KinoCommon::g_currentFrame, FileTracker::GetInstance(), KinoCommon::getPlayList(), KinoCommon::keyboardFeedback(), kinoDeactivate(), KinoCommon::moveToFrame(), PAGE_CAPTURE, PAGE_MAGICK, PAGE_TIMELINE, PAGE_TRIM, and KinoCommon::savePlayList().

00470 {
00471     if ( strcmp( cmd, "F2" ) == 0 )
00472     {
00473         common->keyboardFeedback( cmd, _( "Edit" ) );
00474         common->changePageRequest( PAGE_TIMELINE );
00475     }
00476 
00477     else if ( strcmp( cmd, "A" ) == 0 )
00478     {
00479         common->keyboardFeedback( cmd, _( "Capture, append to movie" ) );
00480         common->moveToFrame( common->getPlayList() ->GetNumFrames() );
00481         FileTracker::GetInstance().SetMode( CAPTURE_MOVIE_APPEND );
00482         common->changePageRequest( PAGE_CAPTURE );
00483     }
00484 
00485     else if ( strcmp( cmd, "a" ) == 0 )
00486     {
00487         common->keyboardFeedback( cmd, _( "Capture, insert after frame" ) );
00488         common->moveToFrame( common->getPlayList() ->FindEndOfScene( common->g_currentFrame ) );
00489         FileTracker::GetInstance().SetMode( CAPTURE_FRAME_APPEND );
00490         common->changePageRequest( PAGE_CAPTURE );
00491     }
00492 
00493     else if ( strcmp( cmd, "t" ) == 0 )
00494     {
00495         common->keyboardFeedback( cmd, _( "Trim" ) );
00496         common->changePageRequest( PAGE_TRIM );
00497     }
00498 
00499     else if ( strcmp( cmd, "v" ) == 0 )
00500     {
00501         common->keyboardFeedback( cmd, _( "Timeline" ) );
00502         common->changePageRequest( PAGE_TIMELINE );
00503     }
00504 
00505     else if ( strcmp( cmd, "C" ) == 0 )
00506     {
00507         common->keyboardFeedback( cmd, _( "FX" ) );
00508         common->changePageRequest( PAGE_MAGICK );
00509     }
00510 
00511     else if ( strcmp( cmd, ":W" ) == 0 )
00512     {
00513         common->keyboardFeedback( cmd, _( "Export" ) );
00514         common->changePageRequest( PAGE_TIMELINE );
00515     }
00516 
00517     /* write PlayList */
00518 
00519     else if ( strcmp( cmd, ":w" ) == 0 )
00520     {
00521         common->keyboardFeedback( cmd, _( "Write playlist" ) );
00522         common->savePlayList( );
00523     }
00524 
00525     /* quit */
00526 
00527     else if ( strcmp( cmd, ":q" ) == 0 )
00528     {
00529         common->keyboardFeedback( cmd, _( "quit" ) );
00530         kinoDeactivate();
00531     }
00532 
00533     return FALSE;
00534 }

gboolean PageTimeline::processKeyboard GdkEventKey *  event  )  [virtual]
 

Reimplemented from Page.

Definition at line 441 of file page_timeline.cc.

References KinoCommon::changePageRequest(), common, PAGE_EDITOR, scene, and selectScene().

00442 {
00443     gboolean ret = FALSE;
00444 
00445     // Translate special keys to equivalent command
00446     switch ( event->keyval )
00447     {
00448     case GDK_k:
00449     case GDK_Up:
00450         selectScene( scene - 1 );
00451         break;
00452     case GDK_j:
00453     case GDK_Down:
00454         selectScene( scene + 1 );
00455         break;
00456     case GDK_Return:
00457         selectScene( scene );
00458         break;
00459     case GDK_Escape:
00460         common->changePageRequest( PAGE_EDITOR );
00461         break;
00462     default:
00463         break;
00464     }
00465 
00466     return ret;
00467 }

void PageTimeline::refresh  ) 
 

Definition at line 432 of file page_timeline.cc.

References refresh_required, and showIcons().

00433 {
00434     if ( refresh_required )
00435     {
00436         refresh_required = false;
00437         showIcons( );
00438     }
00439 }

void PageTimeline::selectScene int   )  [virtual]
 

Reimplemented from Page.

Definition at line 236 of file page_timeline.cc.

References common, KinoCommon::g_currentFrame, GetFramePool(), KinoCommon::getPageEditor(), KinoCommon::getPlayList(), KinoCommon::getWidget(), last_begin, last_end, lookup_widget(), scene, scenes, KinoCommon::setCurrentScene(), KinoCommon::showFrameMoreInfo(), and showIcons().

Referenced by processKeyboard().

00237 {
00238     std::cerr << "Time line scene " << i << std::endl;
00239     GtkWidget *start_spin = lookup_widget( common->getWidget(), "start_spin" );
00240     GtkWidget *end_spin = lookup_widget( common->getWidget(), "end_spin" );
00241     GtkAdjustment *adjust = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( start_spin ) );
00242     vector <int> scenes = common->getPageEditor() ->GetScene();
00243 
00244     if ( i < 0 )
00245         i = 0;
00246     if ( i >= ( int ) scenes.size() )
00247         i = scenes.size() - 1;
00248     int value = i == 0 ? 0 : scenes[ i - 1 ];
00249     adjust->lower = 0;
00250     adjust->upper = scenes[ scenes.size() - 1 ];
00251     gtk_spin_button_set_value( GTK_SPIN_BUTTON( start_spin ), value );
00252 
00253     adjust = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( end_spin ) );
00254 
00255     adjust->lower = 0;
00256     adjust->upper = scenes[ scenes.size() - 1 ];
00257     gtk_spin_button_set_value( GTK_SPIN_BUTTON( end_spin ), scenes[ i ] - 1 );
00258 
00259     last_begin = value;
00260     last_end = scenes[ i ] - 1;
00261     scene = i;
00262 
00263     common->g_currentFrame = value;
00264 
00265     Frame &frame = *( GetFramePool( ) ->GetFrame( ) );
00266     FileHandler *media;
00267     common->getPlayList() ->GetMediaObject( value, &media );
00268     common->getPlayList() ->GetFrame( value, frame );
00269     common->showFrameMoreInfo( frame, media );
00270     GetFramePool( ) ->DoneWithFrame( &frame );
00271     common->setCurrentScene( value );
00272 
00273     showIcons( );
00274 }

void PageTimeline::showIcons  ) 
 

Definition at line 281 of file page_timeline.cc.

References mutex, showIconsRunning, thread, ThreadProxy(), TIMELINE_IDLE, TIMELINE_INIT, TIMELINE_RESTART, TIMELINE_RUNNING, and TIMELINE_STARTING.

Referenced by refresh(), selectScene(), and timeFormatChanged().

00282 {
00283     pthread_mutex_lock( &mutex );
00284 
00285     // If running then, set as RESTART otherwise start the thread,
00286     // otherwise we're already waiting on a restart so do nothing
00287     if ( showIconsRunning == TIMELINE_RUNNING )
00288     {
00289         showIconsRunning = TIMELINE_RESTART;
00290     }
00291     else if ( showIconsRunning == TIMELINE_INIT )
00292     {
00293         showIconsRunning = TIMELINE_STARTING;
00294         pthread_create( &thread, NULL, ThreadProxy, this );
00295     }
00296     else if ( showIconsRunning == TIMELINE_IDLE )
00297     {
00298         pthread_join( thread, NULL );
00299         showIconsRunning = TIMELINE_STARTING;
00300         pthread_create( &thread, NULL, ThreadProxy, this );
00301     }
00302 
00303     pthread_mutex_unlock( &mutex );
00304 }

void PageTimeline::start  )  [virtual]
 

Reimplemented from Page.

Definition at line 194 of file page_timeline.cc.

References common, KinoCommon::g_currentFrame, KinoCommon::getPageEditor(), KinoCommon::getPlayList(), KinoCommon::getWidget(), last_begin, last_end, lookup_widget(), refresh_required, scene, and scenes.

Referenced by Thread().

00195 {
00196     std::cerr << ">> Starting timeline" << std::endl;
00197 
00198     if ( common->getPlayList() ->GetNumFrames() > 0 )
00199     {
00200         int begin = common->getPlayList() ->FindStartOfScene( common->g_currentFrame );
00201         int end = common->getPlayList() ->FindEndOfScene( common->g_currentFrame );
00202 
00203         if ( last_begin != begin || last_end != end )
00204         {
00205             GtkEntry *startSpin = GTK_ENTRY( lookup_widget( common->getWidget(), "start_spin" ) );
00206             GtkEntry *endSpin = GTK_ENTRY( lookup_widget( common->getWidget(), "end_spin" ) );
00207             GtkAdjustment *adjust = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( startSpin ) );
00208 
00209             adjust->lower = 0;
00210             adjust->upper = common->getPlayList() ->GetNumFrames();
00211             gtk_spin_button_set_value( GTK_SPIN_BUTTON( startSpin ), begin );
00212             g_signal_emit_by_name( adjust, "changed" );
00213 
00214             adjust = gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON( endSpin ) );
00215             adjust->lower = 0;
00216             adjust->upper = common->getPlayList() ->GetNumFrames();
00217             gtk_spin_button_set_value( GTK_SPIN_BUTTON( endSpin ), end );
00218             g_signal_emit_by_name( adjust, "changed" );
00219 
00220             last_begin = begin;
00221             last_end = end;
00222 
00223             scene = 0;
00224             vector <int> scenes = common->getPageEditor() ->GetScene();
00225             while ( begin > scenes[ scene++ ] )
00226                 ;
00227             scene--;
00228 
00229             refresh_required = true;
00230         }
00231     }
00232     gtk_notebook_set_page( GTK_NOTEBOOK( lookup_widget( common->getWidget(), "notebook_keyhelp" ) ), 3 );
00233     gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM( lookup_widget( common->getWidget(), "menuitem_timeline" ) ), TRUE );
00234 }

void * PageTimeline::Thread  ) 
 

Definition at line 312 of file page_timeline.cc.

References action, COLUMN_FRAME, COLUMN_ICON, COLUMN_TIME, common, count, GetFramePool(), Frame::GetFrameRate(), Preferences::getInstance(), KinoCommon::getPlayList(), KinoCommon::getTime(), KinoCommon::getTimeFormat(), KinoCommon::getWidget(), key, lookup_widget(), model, pixels, refresh_required, showIconsRunning, start(), TIMELINE_IDLE, TIMELINE_RUNNING, and view.

00313 {
00314     Frame &frame = *GetFramePool( ) ->GetFrame( );
00315 
00316     // Set the lowest coloured quality for decode
00317     frame.decoder->quality = DV_QUALITY_DC;
00318     if ( Preferences::getInstance().displayQuality < 4 )
00319         frame.decoder->quality |= DV_QUALITY_COLOR;
00320 
00321     while ( showIconsRunning != TIMELINE_IDLE )
00322     {
00323         GtkTreeIter iter;
00324 
00325         showIconsRunning = TIMELINE_RUNNING;
00326         refresh_required = false;
00327         gdk_threads_enter();
00328     
00329         // Increment and store the number of times this is called
00330         int my_action = ++ action;
00331     
00332         // Lock the mutex to ensure only one scene is rendered
00333         pthread_mutex_lock( &key );
00334     
00335         // Obtain the start and end widgets
00336         GtkWidget *start_spin = lookup_widget( common->getWidget(), "start_spin" );
00337         GtkWidget *end_spin = lookup_widget( common->getWidget(), "end_spin" );
00338     
00339         // Get the start and end frames from the widgets
00340         int start = atoi( gtk_entry_get_text( GTK_ENTRY( start_spin ) ) );
00341         int end = atoi( gtk_entry_get_text( GTK_ENTRY( end_spin ) ) );
00342     
00343         // Calculate the number of thumbs per line
00344         int items_per_row = ( GTK_WIDGET( view )->allocation.width - 12 ) / 96;
00345         int number_of_rows = GTK_WIDGET( view )->allocation.height / 98;
00346         int total_possible = items_per_row * number_of_rows;
00347         int total_required = end - start + 1;
00348     
00349         // Calculate the increment
00350         double increment = 1;
00351         if ( total_required == 1 )
00352             increment = 2;
00353         else if ( total_possible < total_required )
00354             increment = 1 / ( ( double ) total_possible - 1 );
00355         else
00356             increment = 1 / ( ( double ) total_required );
00357     
00358         // Wipe the previous contents
00359         gtk_list_store_clear( model );
00360     
00361         // Hmm - avoid rounding errors?
00362         int count = 0;
00363     
00364         // Loop for each thumb nail
00365         for ( double position = 0;
00366                 showIconsRunning == TIMELINE_RUNNING &&
00367                     action == my_action && count ++ < total_possible;
00368                 position += increment )
00369         {
00370             // Calculate the index
00371             int index = start + ( int ) ( position * total_required );
00372     
00373             if ( position >= 1 )
00374                 index = start + total_required - 1;
00375     
00376             // Define the label text variable
00377             string text = "";
00378     
00379             // Get the frame at the index
00380             common->getPlayList() ->GetFrame( ( int ) index, frame );
00381     
00382             // Extract the RGB image
00383             frame.ExtractRGB( pixels );
00384     
00385             // Create gdk pixbuf image to allow rescaling
00386             GdkPixbuf *image = gdk_pixbuf_new_from_data( pixels, GDK_COLORSPACE_RGB, FALSE, 8,
00387                             frame.GetWidth(), frame.GetHeight(), frame.GetWidth() * 3, NULL, NULL );
00388     
00389             // Rescale
00390             GdkPixbuf *scaled = gdk_pixbuf_scale_simple( image, 90, frame.IsWide() ? 51 : 68, GDK_INTERP_NEAREST );
00391     
00392             // Set the label
00393             char label[ 256 ] = "";
00394             sprintf( label, "%d", ( int ) index + 1 );
00395             common->getTime().setFramerate( frame.GetFrameRate() );
00396             text = common->getTime().parseFramesToString( index, common->getTimeFormat() );
00397     
00398             // Place image in icon list
00399             gtk_list_store_append( model, &iter );
00400             gtk_list_store_set( model, &iter, COLUMN_ICON, scaled, 
00401                 COLUMN_TIME, text.c_str(), COLUMN_FRAME, index, -1 );
00402     
00403             // Delete the original, unscaled pixbuf
00404             g_object_unref( image );
00405             g_object_unref( scaled );
00406     
00407             // Process any pending events
00408             while ( action == my_action && gtk_events_pending() )
00409             {
00410                 pthread_mutex_unlock( &key );
00411                 gtk_main_iteration();
00412                 pthread_mutex_lock( &key );
00413             }
00414     
00415             if ( position >= 1 )
00416                 break;
00417         }
00418     
00419         // Unlock the mutex
00420         pthread_mutex_unlock( &key );
00421         gdk_threads_leave();
00422     
00423         // If we're still running now, it's OK to idle again.
00424         if ( showIconsRunning == TIMELINE_RUNNING )
00425             showIconsRunning = TIMELINE_IDLE;
00426     }
00427     GetFramePool( ) ->DoneWithFrame( &frame );
00428 
00429     return NULL;
00430 }

void * PageTimeline::ThreadProxy void *  arg  )  [static, private]
 

Definition at line 306 of file page_timeline.cc.

Referenced by showIcons().

00307 {
00308     PageTimeline* self = static_cast< PageTimeline* >( arg );
00309     return self->Thread();
00310 }

void PageTimeline::timeFormatChanged  )  [virtual]
 

Reimplemented from Page.

Definition at line 536 of file page_timeline.cc.

References common, KinoCommon::getWidget(), lookup_widget(), on_end_spin_value_changed(), on_start_spin_value_changed(), and showIcons().

00537 {
00538     on_start_spin_value_changed( GTK_SPIN_BUTTON( lookup_widget( common->getWidget(), "start_spin" ) ), NULL );
00539     on_end_spin_value_changed( GTK_SPIN_BUTTON( lookup_widget( common->getWidget(), "end_spin" ) ), NULL );
00540     showIcons();
00541 }


Member Data Documentation

int PageTimeline::action [private]
 

Definition at line 45 of file page_timeline.h.

Referenced by Thread().

KinoCommon* PageTimeline::common [private]
 

Definition at line 43 of file page_timeline.h.

Referenced by processCommand(), processKeyboard(), selectScene(), start(), Thread(), and timeFormatChanged().

pthread_mutex_t PageTimeline::key [private]
 

Definition at line 53 of file page_timeline.h.

Referenced by PageTimeline(), and Thread().

int PageTimeline::last_begin [private]
 

Definition at line 46 of file page_timeline.h.

Referenced by selectScene(), and start().

int PageTimeline::last_end [private]
 

Definition at line 47 of file page_timeline.h.

Referenced by selectScene(), and start().

GtkListStore* PageTimeline::model [private]
 

Definition at line 50 of file page_timeline.h.

Referenced by getModel(), PageTimeline(), and Thread().

pthread_mutex_t PageTimeline::mutex [private]
 

Definition at line 54 of file page_timeline.h.

Referenced by PageTimeline(), and showIcons().

bool PageTimeline::refresh_required [private]
 

Definition at line 44 of file page_timeline.h.

Referenced by refresh(), start(), and Thread().

int PageTimeline::scene [private]
 

Definition at line 48 of file page_timeline.h.

Referenced by processKeyboard(), selectScene(), and start().

enum TimelineStatus PageTimeline::showIconsRunning [private]
 

Definition at line 55 of file page_timeline.h.

Referenced by showIcons(), and Thread().

pthread_t PageTimeline::thread [private]
 

Definition at line 52 of file page_timeline.h.

Referenced by showIcons().

GtkIconView* PageTimeline::view [private]
 

Definition at line 49 of file page_timeline.h.

Referenced by getView(), PageTimeline(), and Thread().


The documentation for this class was generated from the following files:
Generated on Sun Mar 11 22:13:20 2007 for Kino by  doxygen 1.4.2