Пример #1
0
static int treeplaylist_callback(int action,
                                 const struct menu_item_ex *this_item)
{
    switch (action)
    {
        case ACTION_REQUEST_MENUITEM:
            if (this_item == &tree_playlist_menu)
            {
                if (((selected_file_attr & FILE_ATTR_MASK) ==
                        FILE_ATTR_AUDIO) ||
                    ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_M3U)||
                     (selected_file_attr & ATTR_DIRECTORY))
                {
                    return action;
                }
            }
            else if (this_item == &view_playlist_item)
            {
                if ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_M3U &&
                        context == CONTEXT_TREE)
                {
                    return action;
                }
            }
            else if (this_item == &i_shuf_pl_item)
            {
                if ((audio_status() & AUDIO_STATUS_PLAY) ||
                    (selected_file_attr & ATTR_DIRECTORY) ||
                    ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_M3U))
                {
                    return action;
                }
            }
            else if (this_item == &i_last_shuf_pl_item ||
                     this_item == &q_last_shuf_pl_item)
            {
                if ((playlist_amount() > 0) &&
                    (audio_status() & AUDIO_STATUS_PLAY) &&
                    ((selected_file_attr & ATTR_DIRECTORY) ||
                    ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_M3U)))
                {
                    return action;
                }
            }
            return ACTION_EXIT_MENUITEM;
            break;
    }
    return action;
}
Пример #2
0
static void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
                                 struct skin_viewport* skin_viewport, unsigned long refresh_type)
{
    struct screen *display = gwps->display;
    char linebuf[MAX_LINE];
    skin_render_func func = skin_render_line;
    struct skin_element* line = viewport;
    struct skin_draw_info info = {
        .gwps = gwps,
        .buf = linebuf,
        .buf_size = sizeof(linebuf),
        .line_number = 0,
        .no_line_break = false,
        .line_scrolls = false,
        .refresh_type = refresh_type,
        .skin_vp = skin_viewport,
        .offset = 0
    };
    
    struct align_pos * align = &info.align;
    bool needs_update;
#ifdef HAVE_LCD_BITMAP
    /* Set images to not to be displayed */
    struct skin_token_list *imglist = gwps->data->images;
    while (imglist)
    {
        struct gui_img *img = (struct gui_img *)imglist->token->value.data;
        img->display = -1;
        imglist = imglist->next;
    }
#endif
    
    while (line)
    {
        linebuf[0] = '\0';
        info.no_line_break = false;
        info.line_scrolls = false;
        info.force_redraw = false;
    
        info.cur_align_start = info.buf;
        align->left = info.buf;
        align->center = NULL;
        align->right = NULL;
        
        
        if (line->type == LINE_ALTERNATOR)
            func = skin_render_alternator;
        else if (line->type == LINE)
            func = skin_render_line;
        
        needs_update = func(line, &info);
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
        if (skin_viewport->vp.fg_pattern != skin_viewport->start_fgcolour ||
            skin_viewport->vp.bg_pattern != skin_viewport->start_bgcolour)
        {
            /* 2bit lcd drivers need lcd_set_viewport() to be called to change
             * the colour, 16bit doesnt. But doing this makes static text
             * get the new colour also */
            needs_update = true;
            display->set_viewport(&skin_viewport->vp);
        }
#endif
        /* only update if the line needs to be, and there is something to write */
        if (refresh_type && needs_update)
        {
            if (info.line_scrolls)
            {
                /* if the line is a scrolling one we don't want to update
                   too often, so that it has the time to scroll */
                if ((refresh_type & SKIN_REFRESH_SCROLL) || info.force_redraw)
                    write_line(display, align, info.line_number, true);
            }
            else
                write_line(display, align, info.line_number, false);
        }
        if (!info.no_line_break)
            info.line_number++;
        line = line->next;
    }
#ifdef HAVE_LCD_BITMAP
    wps_display_images(gwps, &skin_viewport->vp);
#endif
}

void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
{
    struct wps_data *data = gwps->data;
    struct screen *display = gwps->display;
    
    struct skin_element* viewport = data->tree;
    struct skin_viewport* skin_viewport;
    
    int old_refresh_mode = refresh_mode;
    
#ifdef HAVE_LCD_CHARCELLS
    int i;
    for (i = 0; i < 8; i++)
    {
        if (data->wps_progress_pat[i] == 0)
            data->wps_progress_pat[i] = display->get_locked_pattern();
    }
#endif
    viewport = data->tree;
    skin_viewport = (struct skin_viewport *)viewport->data;
    if (skin_viewport->label && viewport->next &&
        !strcmp(skin_viewport->label,VP_DEFAULT_LABEL))
        refresh_mode = 0;
    
    for (viewport = data->tree;
         viewport;
         viewport = viewport->next)
    {
        /* SETUP */
        skin_viewport = (struct skin_viewport*)viewport->data;
        unsigned vp_refresh_mode = refresh_mode;
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
        skin_viewport->vp.fg_pattern = skin_viewport->start_fgcolour;
        skin_viewport->vp.bg_pattern = skin_viewport->start_bgcolour;
#endif
        
        /* dont redraw the viewport if its disabled */
        if (skin_viewport->hidden_flags&VP_NEVER_VISIBLE)
        {   /* don't draw anything into this one */
            vp_refresh_mode = 0;
        }
        else if ((skin_viewport->hidden_flags&VP_DRAW_HIDDEN))
        {
            skin_viewport->hidden_flags |= VP_DRAW_WASHIDDEN;
            continue;
        }
        else if (((skin_viewport->hidden_flags&
                   (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE))
                    == (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE)))
        {
            vp_refresh_mode = SKIN_REFRESH_ALL;
            skin_viewport->hidden_flags = VP_DRAW_HIDEABLE;
        }
        
        display->set_viewport(&skin_viewport->vp);
        if ((vp_refresh_mode&SKIN_REFRESH_ALL) == SKIN_REFRESH_ALL)
        {
            display->clear_viewport();
        }
        /* render */
        if (viewport->children_count)
            skin_render_viewport(viewport->children[0], gwps,
                                 skin_viewport, vp_refresh_mode);
        refresh_mode = old_refresh_mode;
    }
    
    /* Restore the default viewport */
    display->set_viewport(NULL);
    display->update();
}

#ifdef HAVE_LCD_BITMAP
static __attribute__((noinline)) void skin_render_playlistviewer(struct playlistviewer* viewer,
                                       struct gui_wps *gwps,
                                       struct skin_viewport* skin_viewport,
                                       unsigned long refresh_type)
{
    struct screen *display = gwps->display;
    char linebuf[MAX_LINE];
    skin_render_func func = skin_render_line;
    struct skin_element* line;
    struct skin_draw_info info = {
        .gwps = gwps,
        .buf = linebuf,
        .buf_size = sizeof(linebuf),
        .line_number = 0,
        .no_line_break = false,
        .line_scrolls = false,
        .refresh_type = refresh_type,
        .skin_vp = skin_viewport,
        .offset = viewer->start_offset
    };
    
    struct align_pos * align = &info.align;
    bool needs_update;
    int cur_pos, start_item, max;
    int nb_lines = viewport_get_nb_lines(viewer->vp);
#if CONFIG_TUNER
    if (current_screen() == GO_TO_FM)
    {
        cur_pos = radio_current_preset();
        start_item = cur_pos + viewer->start_offset;
        max = start_item+radio_preset_count();
    }
    else
#endif
    {
        struct cuesheet *cue = skin_get_global_state()->id3 ? 
                               skin_get_global_state()->id3->cuesheet : NULL;
        cur_pos = playlist_get_display_index();
        max = playlist_amount()+1;
        if (cue)
            max += cue->track_count;
        start_item = MAX(0, cur_pos + viewer->start_offset); 
    }
    if (max-start_item > nb_lines)
        max = start_item + nb_lines;
    
    line = viewer->line;
    while (start_item < max)
    {
        linebuf[0] = '\0';
        info.no_line_break = false;
        info.line_scrolls = false;
        info.force_redraw = false;
    
        info.cur_align_start = info.buf;
        align->left = info.buf;
        align->center = NULL;
        align->right = NULL;
        
        
        if (line->type == LINE_ALTERNATOR)
            func = skin_render_alternator;
        else if (line->type == LINE)
            func = skin_render_line;
        
        needs_update = func(line, &info);
        
        /* only update if the line needs to be, and there is something to write */
        if (refresh_type && needs_update)
        {
            if (info.line_scrolls)
            {
                /* if the line is a scrolling one we don't want to update
                   too often, so that it has the time to scroll */
                if ((refresh_type & SKIN_REFRESH_SCROLL) || info.force_redraw)
                    write_line(display, align, info.line_number, true);
            }
            else
                write_line(display, align, info.line_number, false);
        }
        info.line_number++;
        info.offset++;
        start_item++;
    }
}
Пример #3
0
bool bookmark_play(char *resume_file, int index, int offset, int seed,
                   char *filename)
{
    int i;
    char* suffix = strrchr(resume_file, '.');
    bool started = false;

    if (suffix != NULL &&
        (!strcasecmp(suffix, ".m3u") || !strcasecmp(suffix, ".m3u8")))
    {
        /* Playlist playback */
        char* slash;
        /* check that the file exists */
        if(!file_exists(resume_file))
            return false;

        slash = strrchr(resume_file,'/');
        if (slash)
        {
            char* cp;
            *slash=0;

            cp=resume_file;
            if (!cp[0])
                cp="/";

            if (playlist_create(cp, slash+1) != -1)
            {
                if (global_settings.playlist_shuffle)
                    playlist_shuffle(seed, -1);
                playlist_start(index,offset);
                started = true;
            }
            *slash='/';
        }
    }
    else
    {
        /* Directory playback */
        lastdir[0]='\0';
        if (playlist_create(resume_file, NULL) != -1)
        {
            char filename_buf[MAX_PATH + 1];
            const char* peek_filename;
            resume_directory(resume_file);
            if (global_settings.playlist_shuffle)
                playlist_shuffle(seed, -1);

            /* Check if the file is at the same spot in the directory,
               else search for it */
            peek_filename = playlist_peek(index, filename_buf,
                sizeof(filename_buf));
            
            if (peek_filename == NULL)
            {
                /* playlist has shrunk, search from the top */
                index = 0;
                peek_filename = playlist_peek(index, filename_buf,
                    sizeof(filename_buf));
                if (peek_filename == NULL)
                    return false;
            }
                
            if (strcmp(strrchr(peek_filename, '/') + 1, filename))
            {
                for ( i=0; i < playlist_amount(); i++ )
                {
                    peek_filename = playlist_peek(i, filename_buf,
                        sizeof(filename_buf));

                    if (peek_filename == NULL)
                        return false;

                    if (!strcmp(strrchr(peek_filename, '/') + 1, filename))
                        break;
                }
                if (i < playlist_amount())
                    index = i;
                else
                    return false;
            }
            playlist_start(index,offset);
            started = true;
        }
    }

    if (started)
        start_wps = true;
    return started;
}
Пример #4
0
/* CONTEXT_[TREE|ID3DB] playlist options */
static bool add_to_playlist(int position, bool queue)
{
    bool new_playlist = !(audio_status() & AUDIO_STATUS_PLAY);
    const char *lines[] = {
        ID2P(LANG_RECURSE_DIRECTORY_QUESTION),
        selected_file
    };
    const struct text_message message={lines, 2};

    splash(0, ID2P(LANG_WAIT));

    if (new_playlist)
        playlist_create(NULL, NULL);

    /* always set seed before inserting shuffled */
    if (position == PLAYLIST_INSERT_SHUFFLED ||
        position == PLAYLIST_INSERT_LAST_SHUFFLED)
    {
        srand(current_tick);
        if (position == PLAYLIST_INSERT_LAST_SHUFFLED)
            playlist_set_last_shuffled_start();
    }

#ifdef HAVE_TAGCACHE
    if (context == CONTEXT_ID3DB)
    {
        tagtree_insert_selection_playlist(position, queue);
    }
    else
#endif
    {
        if ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO)
            playlist_insert_track(NULL, selected_file, position, queue, true);
        else if (selected_file_attr & ATTR_DIRECTORY)
        {
            bool recurse = false;

            if (global_settings.recursive_dir_insert != RECURSE_ASK)
                recurse = (bool)global_settings.recursive_dir_insert;
            else
            {
                /* Ask if user wants to recurse directory */
                recurse = (gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES);
            }

            playlist_insert_directory(NULL, selected_file, position, queue,
                                      recurse);
        }
        else if ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_M3U)
            playlist_insert_playlist(NULL, selected_file, position, queue);
    }

    if (new_playlist && (playlist_amount() > 0))
    {
        /* nothing is currently playing so begin playing what we just
           inserted */
        if (global_settings.playlist_shuffle)
            playlist_shuffle(current_tick, -1);
        playlist_start(0,0);
        onplay_result = ONPLAY_START_PLAY;
    }

    return false;
}
/* Initialize the playlist viewer. */
static bool playlist_viewer_init(struct playlist_viewer * viewer,
                                 const char* filename, bool reload)
{
    char* buffer;
    size_t buffer_size;
    bool is_playing = audio_status() & (AUDIO_STATUS_PLAY | AUDIO_STATUS_PAUSE);
    bool have_list = filename || is_playing;
    if (!have_list && (global_status.resume_index != -1))
    {
        /* Try to restore the list from control file */
        have_list = (playlist_resume() != -1);
    }
    if (!have_list && (playlist_amount() > 0))
    {
         /*If dynamic playlist still exists, view it anyway even 
        if playback has reached the end of the playlist */
        have_list = true;
    }
    if (!have_list)
    {
        /* Nothing to view, exit */
        splash(HZ, str(LANG_CATALOG_NO_PLAYLISTS));
        return false;
    }

    buffer = plugin_get_buffer(&buffer_size);
    if (!buffer)
        return false;

    if (!filename)
        viewer->playlist = NULL;
    else
    {
        /* Viewing playlist on disk */
        const char *dir, *file;
        char *temp_ptr;
        char *index_buffer = NULL;
        ssize_t index_buffer_size = 0;

        viewer->playlist = &temp_playlist;

        /* Separate directory from filename */
        temp_ptr = strrchr(filename+1,'/');
        if (temp_ptr)
        {
            *temp_ptr = 0;
            dir = filename;
            file = temp_ptr + 1;
        }
        else
        {
            dir = "/";
            file = filename+1;
        }

        if (is_playing)
        {
            /* Something is playing, use half the plugin buffer for playlist
               indices */
            index_buffer_size = buffer_size / 2;
            index_buffer = buffer;
        }

        playlist_create_ex(viewer->playlist, dir, file, index_buffer,
            index_buffer_size, buffer+index_buffer_size,
            buffer_size-index_buffer_size);

        if (temp_ptr)
            *temp_ptr = '/';

        buffer += index_buffer_size;
        buffer_size -= index_buffer_size;
    }
    playlist_buffer_init(&viewer->buffer, buffer, buffer_size);

    viewer->moving_track = -1;
    viewer->moving_playlist_index = -1;

    if (!reload)
    {
        if (viewer->playlist)
            viewer->selected_track = 0;
        else
            viewer->selected_track = playlist_get_display_index() - 1;
    }

    if (!update_playlist(true))
        return false;
    return true;
}