repair vaapi encode_frame, fix segv on unreadable asset, update crop resource icon...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / awindowgui.C
index 13e802a8f0f7430fe6c3121acb97bb3be6cded17..66e69c3bd873d769092624af39d32cfb95b377d1 100644 (file)
@@ -121,8 +121,7 @@ VFrame *AssetVIcon::frame()
 {
        AssetVIconThread *avt = picon->gui->vicon_thread;
        Asset *asset = (Asset *)picon->indexable;
-       if( !asset )
-               return *images[0];
+       if( !asset ) return vframes()>0 ? (VFrame*)*images[0] : 0;
        if( !asset->video_data && audio_data && audio_size && length > 0 ) {
                if( !temp ) temp = new VFrame(0, -1, w, h, BC_RGB888, -1);
                temp->clear_frame();
@@ -326,12 +325,19 @@ AssetViewPopup::AssetViewPopup(VIconThread *vt, int draw_mode,
 {
        this->draw_mode = draw_mode;
        this->bar_h = (VIEW_POPUP_BAR_H * h) / 200;
+       dragging = 0;
 }
 
 AssetViewPopup::~AssetViewPopup()
 {
 }
 
+int AssetViewPopup::reposition_window(int x, int y, int w, int h)
+{
+       this->bar_h = (VIEW_POPUP_BAR_H * h) / 200;
+       return ViewPopup::reposition_window(x, y, w, h);
+}
+
 int AssetViewPopup::button_press_event()
 {
        if( !is_event_win() ) return 0;
@@ -342,6 +348,9 @@ int AssetViewPopup::button_press_event()
        switch( get_buttonpress() ) {
        case LEFT_BUTTON:
                break;
+       case MIDDLE_BUTTON:
+               avt->set_view_popup(0);
+               return 1;
        case WHEEL_DOWN:
                dir = -1; // fall thru
        case WHEEL_UP:
@@ -556,6 +565,7 @@ void AssetViewPopup::draw_vframe(VFrame *vframe)
 
 int AssetViewPopup::keypress_event()
 {
+       int result = 0;
        AssetVIconThread *avt = (AssetVIconThread *)vt;
        switch( avt->draw_mode ) {
        case ASSET_VIEW_MEDIA_MAP:
@@ -563,15 +573,15 @@ int AssetViewPopup::keypress_event()
                case 'f':
                case 'F':
                        avt->draw_mode = ASSET_VIEW_FULL;
-                       avt->viewing = 0;
-                       return 1;
+                       result = 1;
                }
                break;
        case ASSET_VIEW_FULL:
                avt->draw_mode = ASSET_VIEW_MEDIA_MAP;
-               avt->viewing = 0;
-               return 1;
+               result = 1;
        }
+       if( result ) // zero change for refresh
+               avt->zoom_scale(0);
        return ViewPopup::keypress_event();
 }
 
@@ -611,7 +621,7 @@ void AssetVIconThread::set_view_popup(AssetVIcon *v, int draw_mode)
 {
        gui->stop_vicon_drawing();
        this->draw_mode = draw_mode;
-       VIconThread::set_view_popup(v);
+       set_view_popup(v);
        gui->start_vicon_drawing();
 }
 
@@ -621,7 +631,7 @@ void AssetVIconThread::set_view_popup(AssetVIcon *v)
        VIconThread::set_view_popup(v);
 }
 
-ViewPopup *AssetVIconThread::new_view_window()
+ViewPopup *AssetVIconThread::new_view_window(ViewPopup *vpopup)
 {
        BC_WindowBase *parent = wdw->get_parent();
        int rx = 0, ry = 0, rw = 0, rh = 0;
@@ -637,26 +647,32 @@ ViewPopup *AssetVIconThread::new_view_window()
        }
        else
                parent->get_fullscreen_geometry(rx, ry, rw, rh);
-       AssetViewPopup *popup = new AssetViewPopup(this, draw_mode, rx, ry, rw, rh);
-       switch( draw_mode ) {
-       case ASSET_VIEW_NONE:
-       case ASSET_VIEW_ICON:
-       case ASSET_VIEW_MEDIA_MAP:
-       case ASSET_VIEW_FULL:
-               vicon->stop_audio();
-               vicon->playing_audio = -1;
-               break;
-       case ASSET_VIEW_MEDIA:
-               switch( gui->vicon_drawing ) {
-               case AVICON_FULL_PLAY:
-               case AVICON_MOUSE_OVER:
-                       vicon->playing_audio = 1;
-                       vicon->start_audio();
+       AssetViewPopup *av_popup = (AssetViewPopup *)vpopup;
+       if( av_popup )
+               av_popup->reposition_window(rx, ry, rw, rh);
+       else
+               av_popup = new AssetViewPopup(this, draw_mode, rx, ry, rw, rh);
+       int playing_audio = gui->play_off ? -1 : 0;
+       if( !playing_audio ) {
+               switch( draw_mode ) {
+               case ASSET_VIEW_NONE:
+               case ASSET_VIEW_ICON:
+               case ASSET_VIEW_MEDIA_MAP:
+               case ASSET_VIEW_FULL:
+                       playing_audio = -1;
                        break;
+               case ASSET_VIEW_MEDIA:
+                       switch( gui->vicon_drawing ) {
+                       case AVICON_SRC_TARGET:
+                       case AVICON_NO_PLAY:
+                               playing_audio = -1;
+                               break;
+                       }
                }
        }
-       wdw->set_active_subwindow(popup);
-       return popup;
+       vicon->playing_audio = playing_audio;
+       wdw->set_active_subwindow(av_popup);
+       return av_popup;
 }
 
 void AssetVIconThread::close_view_popup()
@@ -853,6 +869,9 @@ void AssetPicon::reset()
        vicon_frame = 0;
        in_use = 1;
        comments_time = 0;
+       comments_rate = -1;
+       comments_ffmt = ' ';
+       comments_type = "";
        id = 0;
        persistent = 0;
 }
@@ -1043,6 +1062,10 @@ void AssetPicon::create_objects()
                }
                struct stat st;
                comments_time = !stat(asset->path, &st) ? st.st_mtime : 0;
+               comments_rate = asset->get_frame_rate();
+               comments_ffmt = asset->format == FILE_FFMPEG ? '=' : '-';
+               comments_type = asset->format == FILE_FFMPEG ?
+                               asset->vcodec : File::formattostr(asset->format);
        }
        else
        if( indexable && !indexable->is_asset ) {
@@ -1270,6 +1293,7 @@ AWindowGUI::AWindowGUI(MWindow *mwindow, AWindow *awindow)
        vicon_thread = 0;
        vicon_audio = 0;
        vicon_drawing = AVICON_FULL_PLAY;
+       play_off = 0;
        displayed_folder = AW_NO_FOLDER;
        new_folder_thread = 0;
        modify_folder_thread = 0;
@@ -1467,9 +1491,14 @@ void AWindowGUI::create_objects()
 
        int fx = mwindow->theme->afolders_x, fy = mwindow->theme->afolders_y;
        int fw = mwindow->theme->afolders_w, fh = mwindow->theme->afolders_h;
-       const char *text = _("Preview");
-       int tw = get_text_width(MEDIUMFONT, text);
-       int pw = BC_PopupMenu::calculate_w(4, tw, -1);
+       int n = sizeof(AVIconDrawing::avicon_names)/sizeof(AVIconDrawing::avicon_names[0]);
+       int tw = 0;  const char **av_names = AVIconDrawing::avicon_names;
+       for( int i=0; i<n; ++i ) {
+               int nw = get_text_width(MEDIUMFONT, _(av_names[i]));
+               if( tw < nw )  tw = nw;
+       }
+       int pw = BC_PopupMenu::calculate_w(16, tw, 1);
+       const char *text = _(AVIconDrawing::avicon_names[vicon_drawing]);
        add_subwindow(avicon_drawing = new AVIconDrawing(this, fw, fy, pw, text));
        avicon_drawing->create_objects();
        add_subwindow(add_tools = new AddTools(mwindow, this, fx, fy, _("Visibility")));
@@ -1604,16 +1633,19 @@ int AWindowGUI::close_event()
        return 1;
 }
 
-void AWindowGUI::start_vicon_drawing()
+int AWindowGUI::start_vicon_drawing()
 {
-       if( !vicon_thread->interrupted ) return;
+       if( play_off ) return stop_vicon_drawing();
+       if( !vicon_thread->interrupted ) return 1;
        switch( vicon_drawing ) {
        case AVICON_FULL_PLAY:  // all vicons, viewing, target
-       case AVICON_MOUSE_OVER: // one vicon, viewing, target
                break;
+       case AVICON_MOUSE_OVER: // one vicon, viewing, target
+               if( vicon_thread->solo ) break;
+       // fall thru
        case AVICON_SRC_TARGET: // no vicons, no view, target
        case AVICON_NO_PLAY:    // no vicons, no view, no target
-               return;
+               return 0;
        }
        if( mwindow->edl->session->awindow_folder == AW_MEDIA_FOLDER ||
            mwindow->edl->session->awindow_folder == AW_PROXY_FOLDER ||
@@ -1630,13 +1662,14 @@ void AWindowGUI::start_vicon_drawing()
                        break;
                }
        }
+       return 1;
 }
 
 int AWindowGUI::stop_vicon_drawing()
 {
-       if( vicon_thread->interrupted ) return 0;
-       vicon_thread->stop_drawing();
-       return 1;
+       if( !vicon_thread->interrupted )
+               vicon_thread->stop_drawing();
+       return 0;
 }
 
 void AWindowGUI::close_view_popup()
@@ -2056,9 +2089,13 @@ void AWindowGUI::update_asset_list()
                        continue;
                }
                if( picon->indexable && picon->indexable->is_asset ) {
+                       Asset *asset = (Asset *)picon->indexable;
                        struct stat st;
-                       picon->comments_time = !stat(picon->indexable->path, &st) ?
-                               st.st_mtime : 0;
+                       picon->comments_time = !stat(asset->path, &st) ? st.st_mtime : 0;
+                       picon->comments_rate = asset->get_frame_rate();
+                       picon->comments_ffmt = asset->format == FILE_FFMPEG ? '=' : '-';
+                       picon->comments_type = asset->format == FILE_FFMPEG ?
+                               asset->vcodec : File::formattostr(asset->format);
                }
        }
 }
@@ -2244,9 +2281,11 @@ void AWindowGUI::copy_picons(AssetPicon *picon, ArrayList<BC_ListBoxItem*> *src)
                        else if( picon->comments_time ) {
                                char date_time[BCSTRLEN];
                                struct tm stm;  localtime_r(&picon->comments_time, &stm);
-                               sprintf(date_time,"%04d.%02d.%02d %02d:%02d:%02d",
+                               sprintf(date_time,"%04d.%02d.%02d %02d:%02d:%02d @%0.2f %c%s",
                                         stm.tm_year+1900, stm.tm_mon+1, stm.tm_mday,
-                                        stm.tm_hour, stm.tm_min, stm.tm_sec);
+                                        stm.tm_hour, stm.tm_min, stm.tm_sec,
+                                       picon->comments_rate, picon->comments_ffmt,
+                                       picon->comments_type);
                                dst[1].append(item2 = new BC_ListBoxItem(date_time));
                        }
                        else
@@ -2775,8 +2814,10 @@ int AWindowAssets::selection_changed()
 
                deactivate_selection();
        }
-       else if( get_button_down() ) {
-               if( (item = (AssetPicon*)get_selection(0, 0)) != 0 ) {
+       else if( get_button_down() && !gui->play_off &&
+                mwindow->edl->session->assetlist_format != ASSETS_TEXT ) {
+               item = (AssetPicon*)get_selection(0, 0);
+               if( item && !get_selection(0, 1) ) {
                        switch( folder ) {
                        case AW_MEDIA_FOLDER:
                        case AW_PROXY_FOLDER:
@@ -2797,7 +2838,8 @@ int AWindowAssets::selection_changed()
                        case AW_CLIP_FOLDER:
                                if( get_buttonpress() == LEFT_BUTTON ) {
                                        AssetVIcon *vicon = 0;
-                                       if( !gui->vicon_thread->vicon )
+                                       AssetVIconThread *avt = gui->vicon_thread;
+                                       if( !avt->vicon && gui->vicon_drawing != AVICON_NO_PLAY )
                                                vicon = item->vicon;
                                        gui->vicon_thread->set_view_popup(vicon, ASSET_VIEW_ICON);
                                }
@@ -2826,6 +2868,7 @@ void AWindowAssets::draw_background()
 
 int AWindowAssets::drag_start_event()
 {
+       gui->vicon_thread->set_view_popup(0);
        int collect_pluginservers = 0;
        int collect_assets = 0, proxy = 0;
 
@@ -2978,9 +3021,9 @@ int AWindowAssets::column_resize_event()
        return 1;
 }
 
-int AWindowAssets::focus_in_event()
+int AWindowAssets::cursor_enter_event()
 {
-       int ret = BC_ListBox::focus_in_event();
+       int ret = BC_ListBox::cursor_enter_event();
        switch( gui->vicon_drawing ) {
        case AVICON_FULL_PLAY:
                gui->start_vicon_drawing();
@@ -2994,6 +3037,14 @@ int AWindowAssets::focus_in_event()
        return ret;
 }
 
+int AWindowAssets::cursor_leave_event()
+{
+       if( !is_event_win() ) return 0;
+       if( !gui->vicon_thread->viewing )
+               gui->stop_vicon_drawing();
+       return BC_ListBox::cursor_leave_event();
+}
+
 int AWindowAssets::focus_out_event()
 {
        gui->stop_vicon_drawing();
@@ -3027,10 +3078,13 @@ int AWindowAssets::mouse_over_event(int no)
        case AVICON_MOUSE_OVER:
                if( !vicon ) break;
                gui->vicon_thread->solo = vicon;
+               gui->start_vicon_drawing();
+       // fall thru
+       case AVICON_SRC_TARGET:
+               if( !vicon ) break;
                if( gui->vicon_thread->viewing )
                        gui->vicon_thread->set_view_popup(vicon);
                break;
-       case AVICON_SRC_TARGET:
        case AVICON_NO_PLAY:
        default:
                break;
@@ -3197,7 +3251,7 @@ int AWindowView::handle_event()
 }
 
 AddTools::AddTools(MWindow *mwindow, AWindowGUI *gui, int x, int y, const char *title)
- : BC_PopupMenu(x, y, gui->get_text_width(MEDIUMFONT, title)+8, title, -1, 0, 4)
+ : BC_PopupMenu(x, y, title, -1, 0)
 {
        this->mwindow = mwindow;
        this->gui = gui;
@@ -3282,15 +3336,28 @@ int AVIconDrawingItem::handle_event()
                item->set_checked(id == i);
        }
        AWindowGUI *agui = avicon->agui;
+       agui->play_off = 0;
+       avicon->set_text(get_text());
        agui->stop_vicon_drawing();
        agui->vicon_thread->set_view_popup(0);
+       agui->vicon_thread->solo = 0;
        agui->vicon_drawing = id;
        agui->start_vicon_drawing();
        return 1;
 }
 
+int AVIconDrawing::draw_face(int dx, int color)
+{
+       int ret = BC_PopupMenu::draw_face(dx, color);
+       if( agui->play_off && agui->vicon_drawing != AVICON_NO_PLAY ) {
+               int lx = get_margin(), ly = get_h()/2;
+               draw_line(lx,ly, get_w()-2*lx,ly);
+       }
+       return ret;
+}
+
 AVIconDrawing::AVIconDrawing(AWindowGUI *agui, int x, int y, int w, const char *text)
- : BC_PopupMenu(x-w, y, w, text, -1, 0, 4)
+ : BC_PopupMenu(x-w, y, w, text, 1, 0, 4)
 {
        this->agui = agui;
 }
@@ -3308,6 +3375,19 @@ void AVIconDrawing::create_objects()
        }
 }
 
+int AVIconDrawing::button_press_event()
+{
+       if( !is_event_win() ) return 0;
+       if( get_buttonpress() == MIDDLE_BUTTON ) {
+               agui->play_off = !agui->play_off ? 1 : 0;
+               draw_face(0, -1);
+               flash(1);
+               agui->start_vicon_drawing();
+               return 1;
+       }
+       return BC_PopupMenu::button_press_event();
+}
+
 AWindowListFormat::AWindowListFormat(MWindow *mwindow, AWindowGUI *gui)
  : BC_MenuItem("","v",'v')
 {