コード例 #1
0
ファイル: list.c プロジェクト: realtsiry/rockbox4linux
static int scrollbar_scroll(struct gui_synclist * gui_list,
                                              int y)
{
    const int screen = screens[SCREEN_MAIN].screen_type;
    const int nb_lines = viewport_get_nb_lines(&list_text[screen]);

    if (nb_lines <  gui_list->nb_items)
    {
        /* scrollbar scrolling is still line based */
        y_offset = 0;
        int scrollbar_size = nb_lines*
            font_get(gui_list->parent[screen]->font)->height;
        int actual_y = y - list_text[screen].y;

        int new_selection = (actual_y * gui_list->nb_items)
                / scrollbar_size;

        int start_item = new_selection - nb_lines/2;
        if(start_item < 0)
            start_item = 0;
        else if(start_item > gui_list->nb_items - nb_lines)
            start_item = gui_list->nb_items - nb_lines;

        gui_list->start_item[screen] = start_item;

        return ACTION_REDRAW;
    }

    return ACTION_NONE;
}
コード例 #2
0
ファイル: yesno.c プロジェクト: BurntBrunch/rockbox-fft
/*
 * Draws the yesno
 *  - yn : the yesno structure
 */
static void gui_yesno_draw(struct gui_yesno * yn)
{
    struct screen * display=yn->display;
    struct viewport *vp = yn->vp;
    int nb_lines, vp_lines, line_shift=0;

    display->set_viewport(vp);
    display->clear_viewport();
    nb_lines = yn->main_message->nb_lines;
    vp_lines = viewport_get_nb_lines(vp);

    if(nb_lines+3< vp_lines)
        line_shift=1;
    
    line_shift += put_message(display, yn->main_message,
                              line_shift, vp_lines);

    /* Space remaining for yes / no text ? */
    if(line_shift+2 <= vp_lines)
    {
        if(line_shift+3 <= vp_lines)
            line_shift++;
        display->puts(0, line_shift, str(LANG_CONFIRM_WITH_BUTTON));
#ifdef HAVE_LCD_BITMAP
        display->puts(0, line_shift+1, str(LANG_CANCEL_WITH_ANY));
#endif
    }
    display->update_viewport();
    display->set_viewport(NULL);
}
コード例 #3
0
ファイル: quickscreen.c プロジェクト: BurntBrunch/rockbox-fft
static void gui_quickscreen_draw(const struct gui_quickscreen *qs,
                                 struct screen *display,
                                 struct viewport *parent,
                                 struct viewport vps[QUICKSCREEN_ITEM_COUNT],
                                 struct viewport *vp_icons)
{
    int i;
    char buf[MAX_PATH];
    unsigned const char *title, *value;
    void *setting;
    int temp;
    display->set_viewport(parent);
    display->clear_viewport();
    for (i = 0; i < QUICKSCREEN_ITEM_COUNT; i++)
    {
        struct viewport *vp = &vps[i];
        if (!qs->items[i])
            continue;
        display->set_viewport(vp);
        display->scroll_stop(vp);

        title = P2STR(ID2P(qs->items[i]->lang_id));
        setting = qs->items[i]->setting;
        temp = option_value_as_int(qs->items[i]);
        value = option_get_valuestring(qs->items[i],
                                       buf, MAX_PATH, temp);

        if (viewport_get_nb_lines(vp) < 2)
        {
            char text[MAX_PATH];
            snprintf(text, MAX_PATH, "%s: %s", title, value);
            display->puts_scroll(0, 0, text);
        }
        else
        {
            display->puts_scroll(0, 0, title);
            display->puts_scroll(0, 1, value);
        }
        display->update_viewport();
    }
    /* draw the icons */
    display->set_viewport(vp_icons);

    display->mono_bitmap(bitmap_icons_7x8[Icon_UpArrow],
                    (vp_icons->width/2) - 4, 0,      7, 8);
    display->mono_bitmap(bitmap_icons_7x8[Icon_FastForward],
                    vp_icons->width - 8,
                    (vp_icons->height/2) - 4,        7, 8);
    display->mono_bitmap(bitmap_icons_7x8[Icon_FastBackward],   0,
                    (vp_icons->height/2) - 4,        7, 8);

    display->mono_bitmap(bitmap_icons_7x8[Icon_DownArrow],
                         (vp_icons->width/2) - 4, 
                          vp_icons->height - 8,       7, 8);

    display->set_viewport(parent);
    display->update_viewport();
    display->set_viewport(NULL);
}
コード例 #4
0
ファイル: time_menu.c プロジェクト: Rockbox/rockbox
int time_screen(void* ignored)
{
    (void)ignored;
    int nb_lines, font_h, ret;
    menu_was_pressed = false;

    push_current_activity(ACTIVITY_TIMEDATESCREEN);

    FOR_NB_SCREENS(i)
    {
        viewport_set_defaults(&clock_vps[i], i);
#ifdef HAVE_BUTTONBAR
        if (global_settings.buttonbar)
        {
            clock_vps[i].height -= BUTTONBAR_HEIGHT;
        }
#endif
        nb_lines = viewport_get_nb_lines(&clock_vps[i]);

        gui_synclist_set_viewport_defaults(&menu[i], i);
        /* force time to be drawn centered */
        clock_vps[i].flags |= VP_FLAG_ALIGN_CENTER;

        font_h = font_get(clock_vps[i].font)->height;
        nb_lines -= 2; /* at least 2 lines for menu */
        if (nb_lines > 4)
            nb_lines = 4;
        if (nb_lines >= 2)
            clock_vps[i].height = nb_lines*font_h;
        else /* disable the clock_vps drawing */
            clock_vps[i].height = 0;
        menu[i].y += clock_vps[i].height;
        menu[i].height -= clock_vps[i].height;
        draw_timedate(&clock_vps[i], &screens[i]);
    }

#ifdef SAMSUNG_YH820
    /* some hardware revisions of the yh820 have a rtc problem: if you try to set
       the time/date it will leave the player in an absolute unresponsive state
       which can only be reverted by removing the battery. Setting time/date
       should be prohibited on this targets. Fortunately we can autodetect these,
       because they always report "02:02:02" as time.
    */
    struct tm *tm = get_time();
    if (tm->tm_year==102 && tm->tm_hour==2 && tm->tm_min==2 && tm->tm_sec==2) {
        splash(4*HZ, "Can't set time/date due to hardware issues!");
        return 0;
    }
#endif

    ret = do_menu(&time_menu, NULL, menu, false);
    pop_current_activity();
    /* see comments above in the button callback */
    if (!menu_was_pressed && ret == GO_TO_PREVIOUS)
        return 0;
    return ret;
}
コード例 #5
0
/*
 * Draws the yesno result
 *  - yn : the yesno structure
 *  - result : the result tha must be displayed :
 *    YESNO_NO if no
 *    YESNO_YES if yes
 */
static bool gui_yesno_draw_result(struct gui_yesno * yn, enum yesno_res result)
{
    const struct text_message * message=yn->result_message[result];
    struct viewport *vp = yn->vp;
    struct screen * display=yn->display;
    if(message==NULL)
        return false;
    display->set_viewport(vp);
    display->clear_viewport();
    put_message(yn->display, message, 0, viewport_get_nb_lines(vp));
    display->update_viewport();
    display->set_viewport(NULL);
    return(true);
}
コード例 #6
0
/*
 * Draws the yesno
 *  - yn : the yesno structure
 */
static void gui_yesno_draw(struct gui_yesno * yn)
{
    struct screen * display=yn->display;
    struct viewport *vp = yn->vp;
    int nb_lines, vp_lines, line_shift=0;

    display->set_viewport(vp);
    display->clear_viewport();
    nb_lines = yn->main_message->nb_lines;
    vp_lines = viewport_get_nb_lines(vp);

    if(nb_lines+3< vp_lines)
        line_shift=1;

    line_shift += put_message(display, yn->main_message,
                              line_shift, vp_lines);
#ifdef HAVE_TOUCHSCREEN
    if (display->screen_type == SCREEN_MAIN)
    {
        int w,h;
        int rect_w = vp->width/2, rect_h = vp->height/2;
        int old_pattern = vp->fg_pattern;
        vp->fg_pattern = LCD_RGBPACK(0,255,0);
        display->drawrect(0, rect_h, rect_w, rect_h);
        display->getstringsize(str(LANG_SET_BOOL_YES), &w, &h);
        display->putsxy((rect_w-w)/2, rect_h+(rect_h-h)/2, str(LANG_SET_BOOL_YES));
        vp->fg_pattern = LCD_RGBPACK(255,0,0);
        display->drawrect(rect_w, rect_h, rect_w, rect_h);
        display->getstringsize(str(LANG_SET_BOOL_NO), &w, &h);
        display->putsxy(rect_w + (rect_w-w)/2, rect_h+(rect_h-h)/2, str(LANG_SET_BOOL_NO));
        vp->fg_pattern = old_pattern;
    }
#else
    /* Space remaining for yes / no text ? */
    if(line_shift+2 <= vp_lines)
    {
        if(line_shift+3 <= vp_lines)
            line_shift++;
        display->puts(0, line_shift, str(LANG_CONFIRM_WITH_BUTTON));
#ifdef HAVE_LCD_BITMAP
        display->puts(0, line_shift+1, str(LANG_CANCEL_WITH_ANY));
#endif
    }
#endif
    display->update_viewport();
    display->set_viewport(NULL);
}
コード例 #7
0
ファイル: time_menu.c プロジェクト: Brandon7357/rockbox
int time_screen(void* ignored)
{
    (void)ignored;
    int nb_lines, font_h, ret;
    menu_was_pressed = false;

    push_current_activity(ACTIVITY_TIMEDATESCREEN);

    FOR_NB_SCREENS(i)
    {
        viewport_set_defaults(&clock_vps[i], i);
#ifdef HAVE_BUTTONBAR
        if (global_settings.buttonbar)
        {
            clock_vps[i].height -= BUTTONBAR_HEIGHT;
        }
#endif
        nb_lines = viewport_get_nb_lines(&clock_vps[i]);

        gui_synclist_set_viewport_defaults(&menu[i], i);
        /* force time to be drawn centered */
        clock_vps[i].flags |= VP_FLAG_ALIGN_CENTER;

        font_h = font_get(clock_vps[i].font)->height;
        nb_lines -= 2; /* at least 2 lines for menu */
        if (nb_lines > 4)
            nb_lines = 4;
        if (nb_lines >= 2)
            clock_vps[i].height = nb_lines*font_h;
        else /* disable the clock_vps drawing */
            clock_vps[i].height = 0;
        menu[i].y += clock_vps[i].height;
        menu[i].height -= clock_vps[i].height;
        draw_timedate(&clock_vps[i], &screens[i]);
    }

    ret = do_menu(&time_menu, NULL, menu, false);
    pop_current_activity();
    /* see comments above in the button callback */
    if (!menu_was_pressed && ret == GO_TO_PREVIOUS)
        return 0;
    return ret;
}
コード例 #8
0
ファイル: time_menu.c プロジェクト: BurntBrunch/rockbox-fft
static void draw_timedate(struct viewport *vp, struct screen *display)
{
    struct tm *tm = get_time();
    int line;
    char time[16], date[16];
    const char *t = time, *d = date;
    if (vp->height == 0)
        return;
    display->set_viewport(vp);
    display->clear_viewport();
    if (viewport_get_nb_lines(vp) >= 4)
        line = 1;
    else
        line = 0;

    if (valid_time(tm))
    {
        snprintf(time, sizeof(time), "%02d:%02d:%02d%s", 
                global_settings.timeformat == 0 ? tm->tm_hour :
                        ((tm->tm_hour + 11) % 12) + 1,
                            tm->tm_min, 
                            tm->tm_sec, 
                        global_settings.timeformat == 0 ? "" :
                                tm->tm_hour>11 ? " P" : " A");
        snprintf(date, sizeof(date), "%s %d %d", 
                str(LANG_MONTH_JANUARY + tm->tm_mon),
                    tm->tm_mday,
                    tm->tm_year+1900);
    }
    else
    {
        t = "--:--:--";
        d = str(LANG_UNKNOWN);
    }

    display->puts(0, line++, t);
    display->puts(0, line, d);

    display->update_viewport();
    display->set_viewport(NULL);
}
コード例 #9
0
ファイル: list.c プロジェクト: realtsiry/rockbox4linux
static bool swipe_scroll(struct gui_synclist * gui_list, int line_height, int difference)
{
    /* fixme */
    const enum screen_type screen = screens[SCREEN_MAIN].screen_type;
    const int nb_lines = viewport_get_nb_lines(&list_text[screen]);

    if (UNLIKELY(scroll_begin_threshold == 0))
        scroll_begin_threshold = touchscreen_get_scroll_threshold();

    /* make selecting items easier */
    threshold_accumulation += abs(difference);
    if (threshold_accumulation < scroll_begin_threshold && scroll_mode == SCROLL_NONE)
        return false;

    threshold_accumulation = 0;

    /* does the list even scroll? if no, return but still show
     * the caller that we would scroll */
    if (nb_lines >= gui_list->nb_items)
        return true;

    const int old_start = gui_list->start_item[screen];
    int new_start_item = -1;
    int line_diff = 0;

    /* don't scroll at the edges of the list */
    if ((old_start == 0 && difference > 0)
     || (old_start == (gui_list->nb_items - nb_lines) && difference < 0))
    {
        y_offset = 0;
        gui_list->start_item[screen] = old_start;
        return scroll_mode != SCROLL_KINETIC; /* stop kinetic at the edges */
    }

    /* add up y_offset over time and translate to lines
     * if scrolled enough */
    y_offset += difference;
    if (abs(y_offset) > line_height)
    {
        line_diff = y_offset/line_height;
        y_offset -= line_diff * line_height;
    }

    if(line_diff != 0)
    {
        int selection_offset = gui_list->selected_item - old_start;
        new_start_item = old_start - line_diff;
        /* check if new_start_item is bigger than list item count */
        if(new_start_item > gui_list->nb_items - nb_lines)
            new_start_item = gui_list->nb_items - nb_lines;
        /* set new_start_item to 0 if it's negative */
        if(new_start_item < 0)
            new_start_item = 0;

        gui_list->start_item[screen] = new_start_item;
        /* keep selected item in sync */
        gui_list->selected_item = new_start_item + selection_offset;
    }

    return true;
}
コード例 #10
0
ファイル: list.c プロジェクト: realtsiry/rockbox4linux
void list_draw(struct screen *display, struct gui_synclist *list)
{
    struct viewport list_icons;
    int start, end, line_height, style, i;
    const int screen = display->screen_type;
    const int list_start_item = list->start_item[screen];
    const int icon_width = get_icon_width(screen) + ICON_PADDING;
    const bool scrollbar_in_left = (global_settings.scrollbar == SCROLLBAR_LEFT);
    const bool show_cursor = !global_settings.cursor_style &&
                        list->show_selection_marker;
    struct viewport *parent = (list->parent[screen]);
#ifdef HAVE_LCD_COLOR
    unsigned char cur_line = 0;
#endif
    int item_offset;
    bool show_title;
    struct viewport *list_text_vp = &list_text[screen];

    line_height = font_get(parent->font)->height;
    display->set_viewport(parent);
    display->clear_viewport();
    display->scroll_stop(list_text_vp);
    *list_text_vp = *parent;
    if ((show_title = draw_title(display, list)))
    {
        list_text_vp->y += line_height;
        list_text_vp->height -= line_height;
    }

    const int nb_lines = viewport_get_nb_lines(list_text_vp);

    start = list_start_item;
    end = start + nb_lines;

#ifdef HAVE_TOUCHSCREEN
    if (list->selected_item == 0 || (list->nb_items < nb_lines))
        y_offset = 0; /* reset in case it's a new list */

    int draw_offset = y_offset;
    /* draw some extra items to not have empty lines at the top and bottom */
    if (y_offset > 0)
    {
        /* make it negative for more consistent apparence when switching
         * directions */
        draw_offset -= line_height;
        if (start > 0)
            start--;
    }
    else if (y_offset < 0)
        end++;
#else
    #define draw_offset 0
#endif

    /* draw the scrollbar if its needed */
    if (global_settings.scrollbar && nb_lines < list->nb_items)
    {
        struct viewport vp = *list_text_vp;
        vp.width = SCROLLBAR_WIDTH;
        vp.height = line_height * nb_lines;
        vp.x = parent->x;
        list_text_vp->width -= SCROLLBAR_WIDTH;
        if (scrollbar_in_left)
            list_text_vp->x += SCROLLBAR_WIDTH;
        else
            vp.x += list_text_vp->width;
        display->set_viewport(&vp);
        gui_scrollbar_draw(display,
                (scrollbar_in_left? 0: 1), 0, SCROLLBAR_WIDTH-1, vp.height,
                list->nb_items, list_start_item, list_start_item + nb_lines,
                VERTICAL);
    }
    else if (show_title)
    {
        /* shift everything a bit in relation to the title... */
        if (!VP_IS_RTL(list_text_vp) && scrollbar_in_left)
        {
            list_text_vp->width -= SCROLLBAR_WIDTH;
            list_text_vp->x += SCROLLBAR_WIDTH;
        }
        else if (VP_IS_RTL(list_text_vp) && !scrollbar_in_left)
        {
            list_text_vp->width -= SCROLLBAR_WIDTH;
        }
    }

    /* setup icon placement */
    list_icons = *list_text_vp;
    int icon_count = (list->callback_get_item_icon != NULL) ? 1 : 0;
    if (show_cursor)
        icon_count++;
    if (icon_count)
    {
        list_icons.width = icon_width * icon_count;
        list_text_vp->width -= list_icons.width + ICON_PADDING;
        if (VP_IS_RTL(&list_icons))
            list_icons.x += list_text_vp->width + ICON_PADDING;
        else
            list_text_vp->x += list_icons.width + ICON_PADDING;
    }

    for (i=start; i<end && i<list->nb_items; i++)
    {
        /* do the text */
        unsigned const char *s;
        char entry_buffer[MAX_PATH];
        unsigned char *entry_name;
        int text_pos = 0;
        int line = i - start;
        s = list->callback_get_item_name(i, list->data, entry_buffer,
                                         sizeof(entry_buffer));
        entry_name = P2STR(s);
        display->set_viewport(list_text_vp);
        style = STYLE_DEFAULT;
        /* position the string at the correct offset place */
        int item_width,h;
        display->getstringsize(entry_name, &item_width, &h);
        item_offset = gui_list_get_item_offset(list, item_width, text_pos,
                display, list_text_vp);

#ifdef HAVE_LCD_COLOR
        /* if the list has a color callback */
        if (list->callback_get_item_color)
        {
            int color = list->callback_get_item_color(i, list->data);
            /* if color selected */
            if (color >= 0)
            {
                style |= STYLE_COLORED|color;
            }
        }
#endif
        /* draw the selected line */
        if(
#ifdef HAVE_TOUCHSCREEN
            /* don't draw it during scrolling */
            scroll_mode == SCROLL_NONE &&
#endif
                i >= list->selected_item
                && i <  list->selected_item + list->selected_size
                && list->show_selection_marker)
        {/* The selected item must be displayed scrolling */
            if (global_settings.cursor_style == 1
#ifdef HAVE_REMOTE_LCD
                    /* the global_settings.cursor_style check is here to make
                    * sure if they want the cursor instead of bar it will work
                    */
                    || (display->depth < 16 && global_settings.cursor_style)
#endif
            )
            {
                /* Display inverted-line-style */
                style = STYLE_INVERT;
            }
#ifdef HAVE_LCD_COLOR
            else if (global_settings.cursor_style == 2)
            {
                /* Display colour line selector */
                style = STYLE_COLORBAR;
            }
            else if (global_settings.cursor_style == 3)
            {
                /* Display gradient line selector */
                style = STYLE_GRADIENT;

                /* Make the lcd driver know how many lines the gradient should
                   cover and current line number */
                /* number of selected lines */
                style |= NUMLN_PACK(list->selected_size);
                /* current line number, zero based */
                style |= CURLN_PACK(cur_line);
                cur_line++;
            }
#endif
            /* if the text is smaller than the viewport size */
            if (item_offset> item_width - (list_text_vp->width - text_pos))
            {
                /* don't scroll */
                display->puts_style_xyoffset(0, line, entry_name,
                        style, item_offset, draw_offset);
            }
            else
            {
                display->puts_scroll_style_xyoffset(0, line, entry_name,
                        style, item_offset, draw_offset);
            }
        }
        else
        {
            if (list->scroll_all)
                display->puts_scroll_style_xyoffset(0, line, entry_name,
                        style, item_offset, draw_offset);
            else
                display->puts_style_xyoffset(0, line, entry_name,
                        style, item_offset, draw_offset);
        }
        /* do the icon */
        display->set_viewport(&list_icons);
        if (list->callback_get_item_icon != NULL)
        {
            screen_put_icon_with_offset(display, show_cursor?1:0,
                                    (line),show_cursor?ICON_PADDING:0,draw_offset,
                                    list->callback_get_item_icon(i, list->data));
        }
        if (show_cursor && i >= list->selected_item &&
                i <  list->selected_item + list->selected_size)
        {
            screen_put_icon_with_offset(display, 0, line, 0, draw_offset, Icon_Cursor);
        }
    }
    display->set_viewport(parent);
    display->update_viewport();
    display->set_viewport(NULL);
}
コード例 #11
0
ファイル: pitchscreen.c プロジェクト: sideral-rockbox/rockbox
int gui_syncpitchscreen_run(void)
{
    int button, i;
    int32_t pitch = sound_get_pitch();
    int32_t semitone;

    int32_t new_pitch;
    int32_t pitch_delta;
    bool nudged = false;
    bool exit = false;
    /* should maybe be passed per parameter later, not needed for now */
    struct viewport parent[NB_SCREENS];
    struct viewport pitch_viewports[NB_SCREENS][PITCH_ITEM_COUNT];
    int max_lines[NB_SCREENS];

#if CONFIG_CODEC == SWCODEC
    int32_t new_speed = 0, new_stretch;

    /* the speed variable holds the apparent speed of the playback */
    int32_t speed;
    if (dsp_timestretch_available())
    {
        speed = GET_SPEED(pitch, dsp_get_timestretch());
    }
    else
    {
        speed = pitch;
    }

    /* Figure out whether to be in timestretch mode */
    if (global_settings.pitch_mode_timestretch && !dsp_timestretch_available())
    {
        global_settings.pitch_mode_timestretch = false;
        settings_save();
    }
#endif

    /* set the semitone index based on the current pitch */
    semitone = get_semitone_from_pitch(pitch);

    /* initialize pitchscreen vps */
    FOR_NB_SCREENS(i)
    {
        viewport_set_defaults(&parent[i], i);
        max_lines[i] = viewport_get_nb_lines(&parent[i]);
        pitchscreen_fix_viewports(&parent[i], pitch_viewports[i]);
        screens[i].set_viewport(&parent[i]);
        screens[i].clear_viewport();

        /* also, draw the icons now, it's only needed once */
        pitchscreen_draw_icons(&screens[i], &parent[i]);
    }
#if CONFIG_CODEC == SWCODEC
    pcmbuf_set_low_latency(true);
#endif

    while (!exit)
    {
        FOR_NB_SCREENS(i)
            pitchscreen_draw(&screens[i], max_lines[i],
                              pitch_viewports[i], pitch, semitone
#if CONFIG_CODEC == SWCODEC
                              , speed
#endif
                              );
        pitch_delta = 0;
#if CONFIG_CODEC == SWCODEC
        new_speed = 0;
#endif
        button = get_action(CONTEXT_PITCHSCREEN, HZ);
        
#ifdef HAVE_TOUCHSCREEN
        if (button == ACTION_TOUCHSCREEN)
        {
            FOR_NB_SCREENS(i)
                button = pitchscreen_do_touchscreen(pitch_viewports[i]);
        }
#endif
        switch (button)
        {
            case ACTION_PS_INC_SMALL:
                if(global_settings.pitch_mode_semitone)
                    pitch_delta = SEMITONE_SMALL_DELTA;
                else 
                    pitch_delta = PITCH_SMALL_DELTA;
                break;

            case ACTION_PS_INC_BIG:
                if(global_settings.pitch_mode_semitone)
                    pitch_delta = SEMITONE_BIG_DELTA;
                else 
                    pitch_delta = PITCH_BIG_DELTA;
                break;

            case ACTION_PS_DEC_SMALL:
                if(global_settings.pitch_mode_semitone)
                    pitch_delta = -SEMITONE_SMALL_DELTA;
                else 
                    pitch_delta = -PITCH_SMALL_DELTA;
                break;

            case ACTION_PS_DEC_BIG:
                if(global_settings.pitch_mode_semitone)
                    pitch_delta = -SEMITONE_BIG_DELTA;
                else 
                    pitch_delta = -PITCH_BIG_DELTA;
                break;

            case ACTION_PS_NUDGE_RIGHT:
#if CONFIG_CODEC == SWCODEC
                if (!global_settings.pitch_mode_timestretch)
                {
#endif
                    new_pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false
#if CONFIG_CODEC == SWCODEC
                                               , speed
#endif                            
                        );
                    nudged = (new_pitch != pitch);
                    pitch = new_pitch;
                    semitone = get_semitone_from_pitch(pitch);
#if CONFIG_CODEC == SWCODEC
                    speed = pitch;
#endif
                    break;
#if CONFIG_CODEC == SWCODEC
                }
                else
                {
                    new_speed = speed + SPEED_SMALL_DELTA;
                    at_limit = false;
                }
                break;

            case ACTION_PS_FASTER:
                if (global_settings.pitch_mode_timestretch)
                {
                    new_speed = speed + SPEED_BIG_DELTA;
                    /* snap to whole numbers */
                    if(new_speed % PITCH_SPEED_PRECISION != 0)
                        new_speed -= new_speed % PITCH_SPEED_PRECISION;
                    at_limit = false;
                }
                break;
#endif

            case ACTION_PS_NUDGE_RIGHTOFF:
                if (nudged)
                {
                    pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false
#if CONFIG_CODEC == SWCODEC
                                           , speed
#endif                            
                        );
#if CONFIG_CODEC == SWCODEC
                    speed = pitch;
#endif
                    semitone = get_semitone_from_pitch(pitch);
                    nudged = false;
                }
                break;

            case ACTION_PS_NUDGE_LEFT:
#if CONFIG_CODEC == SWCODEC
                if (!global_settings.pitch_mode_timestretch)
                {
#endif
                    new_pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false
#if CONFIG_CODEC == SWCODEC
                                               , speed
#endif                            
                        );
                    nudged = (new_pitch != pitch);
                    pitch = new_pitch;
                    semitone = get_semitone_from_pitch(pitch);
#if CONFIG_CODEC == SWCODEC
                    speed = pitch;
#endif
                    break;
#if CONFIG_CODEC == SWCODEC
                }
                else
                {
                    new_speed = speed - SPEED_SMALL_DELTA;
                    at_limit = false;
                }
                break;

            case ACTION_PS_SLOWER:
                if (global_settings.pitch_mode_timestretch)
                {
                    new_speed = speed - SPEED_BIG_DELTA;
                    /* snap to whole numbers */
                    if(new_speed % PITCH_SPEED_PRECISION != 0)
                        new_speed += PITCH_SPEED_PRECISION - speed % PITCH_SPEED_PRECISION;
                    at_limit = false;
                }
                break;
#endif

            case ACTION_PS_NUDGE_LEFTOFF:
                if (nudged)
                {
                    pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false
#if CONFIG_CODEC == SWCODEC
                                           , speed
#endif                            
                        );
#if CONFIG_CODEC == SWCODEC
                    speed = pitch;
#endif
                    semitone = get_semitone_from_pitch(pitch);
                    nudged = false;
                }
                break;

            case ACTION_PS_RESET:
                pitch = PITCH_SPEED_100;
                sound_set_pitch(pitch);
#if CONFIG_CODEC == SWCODEC
                speed = PITCH_SPEED_100;
                if (dsp_timestretch_available())
                {
                    dsp_set_timestretch(PITCH_SPEED_100);
                    at_limit = false;
                }
#endif
                semitone = get_semitone_from_pitch(pitch);
                break;

            case ACTION_PS_TOGGLE_MODE:
                global_settings.pitch_mode_semitone = !global_settings.pitch_mode_semitone;
#if CONFIG_CODEC == SWCODEC

                if (dsp_timestretch_available() && !global_settings.pitch_mode_semitone)
                {
                    global_settings.pitch_mode_timestretch = !global_settings.pitch_mode_timestretch;
                    if(!global_settings.pitch_mode_timestretch)
                    {
                        /* no longer in timestretch mode.  Reset speed */
                        speed = pitch;
                        dsp_set_timestretch(PITCH_SPEED_100);
                    }
                }
                settings_save();
#endif
                break;

            case ACTION_PS_EXIT:
                exit = true;
                break;

            default:
                if (default_event_handler(button) == SYS_USB_CONNECTED)
                    return 1;
                break;
        }
        if (pitch_delta)
        {
            if (global_settings.pitch_mode_semitone)
            {
                semitone = pitch_increase_semitone(pitch, semitone, pitch_delta
#if CONFIG_CODEC == SWCODEC
                                                , speed
#endif                            
                );
                pitch = get_pitch_from_semitone(semitone);
            }
            else
            {
                pitch = pitch_increase(pitch, pitch_delta, true
#if CONFIG_CODEC == SWCODEC
                                       , speed
#endif                            
                );
                semitone = get_semitone_from_pitch(pitch);
            }
#if CONFIG_CODEC == SWCODEC
            if (global_settings.pitch_mode_timestretch)
            {
                /* do this to make sure we properly obey the stretch limits */
                new_speed = speed;
            }
            else
            {
                speed = pitch;
            }
#endif
        }

#if CONFIG_CODEC == SWCODEC
        if(new_speed)
        {
            new_stretch = GET_STRETCH(pitch, new_speed);

            /* limit the amount of stretch */
            if(new_stretch > STRETCH_MAX)
            {
                new_stretch = STRETCH_MAX;
                new_speed = GET_SPEED(pitch, new_stretch);
            }
            else if(new_stretch < STRETCH_MIN)
            {
                new_stretch = STRETCH_MIN;
                new_speed = GET_SPEED(pitch, new_stretch);
            }

            new_stretch = GET_STRETCH(pitch, new_speed);
            if(new_stretch >= STRETCH_MAX || 
               new_stretch <= STRETCH_MIN)
            {
                at_limit = true;
            }

            /* set the amount of stretch */
            dsp_set_timestretch(new_stretch);

            /* update the speed variable with the new speed */
            speed = new_speed;

            /* Reset new_speed so we only call dsp_set_timestretch */
            /* when needed                                         */
            new_speed = 0;
        }
#endif
    }
#if CONFIG_CODEC == SWCODEC
    pcmbuf_set_low_latency(false);
#endif
    return 0;
}
コード例 #12
0
ファイル: quickscreen.c プロジェクト: sideral-rockbox/rockbox
static void quickscreen_fix_viewports(struct gui_quickscreen *qs,
                                        struct screen *display,
                                        struct viewport *parent,
                                        struct viewport
                                                  vps[QUICKSCREEN_ITEM_COUNT],
                                        struct viewport *vp_icons)
{
    int char_height, width, pad = 0;
    int left_width = 0, right_width = 0, vert_lines;
    unsigned char *s;
    int nb_lines = viewport_get_nb_lines(parent);

    /* nb_lines only returns the number of fully visible lines, small screens
        or really large fonts could cause problems with the calculation below.
     */
    if (nb_lines == 0)
        nb_lines++;

    char_height = parent->height/nb_lines;

    /* center the icons VP first */
    *vp_icons = *parent;
    vp_icons->width = CENTER_ICONAREA_SIZE; /* abosulte smallest allowed */
    vp_icons->x = parent->x;
    vp_icons->x += (parent->width-CENTER_ICONAREA_SIZE)/2;

    vps[QUICKSCREEN_BOTTOM] = *parent;
    vps[QUICKSCREEN_TOP] = *parent;
    /* depending on the space the top/buttom items use 1 or 2 lines */
    if (nb_lines < MIN_LINES)
        vert_lines = 1;
    else
        vert_lines = 2;
    vps[QUICKSCREEN_TOP].y = parent->y;
    vps[QUICKSCREEN_TOP].height = vps[QUICKSCREEN_BOTTOM].height
            = vert_lines*char_height;
    vps[QUICKSCREEN_BOTTOM].y
            = parent->y + parent->height - vps[QUICKSCREEN_BOTTOM].height;

    /* enough space vertically, so put a nice margin */
    if (nb_lines >= MAX_NEEDED_LINES)
    {
        vps[QUICKSCREEN_TOP].y += MARGIN;
        vps[QUICKSCREEN_BOTTOM].y -= MARGIN;
    }

    vp_icons->y = vps[QUICKSCREEN_TOP].y
            + vps[QUICKSCREEN_TOP].height;
    vp_icons->height = vps[QUICKSCREEN_BOTTOM].y - vp_icons->y;

    /* adjust the left/right items widths to fit the screen nicely */
    if (qs->items[QUICKSCREEN_LEFT])
    {
        s = P2STR(ID2P(qs->items[QUICKSCREEN_LEFT]->lang_id));
        left_width = display->getstringsize(s, NULL, NULL);
    }
    if (qs->items[QUICKSCREEN_RIGHT])
    {
        s = P2STR(ID2P(qs->items[QUICKSCREEN_RIGHT]->lang_id));
        right_width = display->getstringsize(s, NULL, NULL);
    }

    width = MAX(left_width, right_width);
    if (width*2 + vp_icons->width > parent->width)
    {   /* crop text viewports */
        width = (parent->width - vp_icons->width)/2;
    }
    else
    {   /* add more gap in icons vp */
        int excess = parent->width - vp_icons->width - width*2;
        if (excess > MARGIN*4)
        {
            pad = MARGIN;
            excess -= MARGIN*2;
        }
        vp_icons->x -= excess/2;
        vp_icons->width += excess;
    }

    vps[QUICKSCREEN_LEFT] = *parent;
    vps[QUICKSCREEN_LEFT].x = parent->x + pad;
    vps[QUICKSCREEN_LEFT].width = width;

    vps[QUICKSCREEN_RIGHT] = *parent;
    vps[QUICKSCREEN_RIGHT].x = parent->x + parent->width - width - pad;
    vps[QUICKSCREEN_RIGHT].width = width;

    vps[QUICKSCREEN_LEFT].height = vps[QUICKSCREEN_RIGHT].height
            = 2*char_height;

    vps[QUICKSCREEN_LEFT].y = vps[QUICKSCREEN_RIGHT].y
            = parent->y + (parent->height/2) - char_height;

    /* shrink the icons vp by a few pixels if there is room so the arrows
       aren't drawn right next to the text */
    if (vp_icons->width > CENTER_ICONAREA_SIZE*2)
    {
        vp_icons->width -= CENTER_ICONAREA_SIZE*2/3;
        vp_icons->x += CENTER_ICONAREA_SIZE*2/6;
    }
    if (vp_icons->height > CENTER_ICONAREA_SIZE*2)
    {
        vp_icons->height -= CENTER_ICONAREA_SIZE*2/3;
        vp_icons->y += CENTER_ICONAREA_SIZE*2/6;
    }

    /* text alignment */
    vps[QUICKSCREEN_LEFT].flags &= ~VP_FLAG_ALIGNMENT_MASK; /* left-aligned */
    vps[QUICKSCREEN_TOP].flags    |= VP_FLAG_ALIGN_CENTER;  /* centered */
    vps[QUICKSCREEN_BOTTOM].flags |= VP_FLAG_ALIGN_CENTER;  /* centered */
    vps[QUICKSCREEN_RIGHT].flags  &= ~VP_FLAG_ALIGNMENT_MASK;/* right aligned*/
    vps[QUICKSCREEN_RIGHT].flags  |= VP_FLAG_ALIGN_RIGHT;
}
コード例 #13
0
ファイル: skin_render.c プロジェクト: sideral-rockbox/rockbox
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++;
    }
}