Subversion Repositories freemyipod

Rev

Rev 773 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
504 theseven 1
//
2
//
3
//    Copyright 2011 TheSeven
4
//
5
//
6
//    This file is part of emCORE.
7
//
8
//    emCORE is free software: you can redistribute it and/or
9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
13
//    emCORE is distributed in the hope that it will be useful,
14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//
22
 
23
 
24
#include "emcorelib.h"
25
#include "libui.h"
26
#include "chooser.h"
27
#include "chooser_renderer_list.h"
28
 
29
 
30
static void chooser_renderer_list_scroll_into_view(struct chooser_data* data,
31
                                                   const struct chooser_item* item)
32
{
33
    const struct chooser_renderer_list_params* params;
34
    params = (const struct chooser_renderer_list_params*)(data->info->rendererparams);
35
    struct chooser_renderer_list_data* rdata;
36
    rdata = (struct chooser_renderer_list_data*)(data->rendererdata);
37
    int available = params->viewport.size.y;
38
    if (item < rdata->top_item) rdata->top_item = item;
39
    const struct chooser_item* curr = rdata->top_item;
40
    const struct chooser_renderer_list_itemdata* iparams;
41
    while (available > 0)
42
    {
43
        if (curr >= &data->info->items[data->info->itemcount]) break;
44
        iparams = (const struct chooser_renderer_list_itemdata*)(curr->renderparams);
45
        if (available >= iparams->size.y)
46
        {
47
            available -= iparams->size.y;
48
            curr++;
49
        }
773 user890104 50
        else
51
        {
52
            break;
53
        }
504 theseven 54
    }
55
    rdata->bottom_item = --curr;
56
    while (curr < item && curr < &data->info->items[data->info->itemcount])
57
    {
58
        curr++;
59
        iparams = (const struct chooser_renderer_list_itemdata*)(curr->renderparams);
60
        available -= iparams->size.y;
61
        while (available < 0)
62
        {
63
            const struct chooser_item* top = rdata->top_item++;
64
            iparams = (const struct chooser_renderer_list_itemdata*)(top->renderparams);
65
            available += iparams->size.y;
66
        }
67
        rdata->bottom_item = curr;
68
    }
69
}
70
 
71
static int chooser_renderer_list_init(struct chooser_data* data)
72
{
73
    const struct chooser_renderer_list_params* params;
74
    params = (const struct chooser_renderer_list_params*)(data->info->rendererparams);
75
    if (params->version != CHOOSER_RENDERER_LIST_PARAMS_VERSION) return -1;
76
    data->rendererdata = malloc(sizeof(struct chooser_renderer_list_data));
77
    if (!data->rendererdata) return -2;
78
    struct chooser_renderer_list_data* rdata;
79
    rdata = (struct chooser_renderer_list_data*)(data->rendererdata);
80
    rdata->top_item = data->info->items;
81
    chooser_renderer_list_scroll_into_view(data, data->selected);
82
    return 0;
83
}
84
 
85
static enum chooser_result chooser_renderer_list_render(struct chooser_data* data)
86
{
87
    const struct chooser_renderer_list_params* params;
88
    params = (const struct chooser_renderer_list_params*)(data->info->rendererparams);
703 theseven 89
    const struct chooser_item* selected = data->selected;
504 theseven 90
    struct chooser_renderer_list_data* rdata;
91
    rdata = (struct chooser_renderer_list_data*)(data->rendererdata);
703 theseven 92
    chooser_renderer_list_scroll_into_view(data, selected);
504 theseven 93
    const struct chooser_item* item = rdata->top_item;
94
    if (params->copy_dest.buf.addr == params->fill_dest.loc.buf.addr
95
     && params->copy_dest.buf.stride == params->fill_dest.loc.buf.stride
96
     && params->copy_dest.pos.x == params->fill_dest.loc.pos.x
97
     && params->copy_dest.pos.y == params->fill_dest.loc.pos.y
98
     && params->copy_src.size.x == params->fill_dest.size.x
99
     && params->copy_src.size.y == params->fill_dest.size.y && params->copy_src.loc.buf.addr)
100
    {
101
        blendcolor(params->copy_src.size.x, params->copy_src.size.y, params->fill_color,
102
                   params->copy_dest.buf.addr, params->copy_dest.pos.x,
103
                   params->copy_dest.pos.y, params->copy_dest.buf.stride,
104
                   params->copy_src.loc.buf.addr, params->copy_src.loc.pos.x,
105
                   params->copy_src.loc.pos.y, params->copy_src.loc.buf.stride);
106
        if (params->bg_opacity && params->bg_dest.buf.addr && params->bg_src.loc.buf.addr)
527 theseven 107
            blenda(params->bg_src.size.x, params->bg_src.size.y, params->bg_opacity,
108
                   params->bg_dest.buf.addr, params->bg_dest.pos.x,
109
                   params->bg_dest.pos.y, params->bg_dest.buf.stride,
110
                   params->bg_dest.buf.addr, params->bg_dest.pos.x,
111
                   params->bg_dest.pos.y, params->bg_dest.buf.stride,
112
                   params->bg_src.loc.buf.addr, params->bg_src.loc.pos.x,
113
                   params->bg_src.loc.pos.y, params->bg_src.loc.buf.stride);
504 theseven 114
    }
115
    else if (params->copy_dest.buf.stride == params->bg_dest.buf.stride
116
     && params->bg_src.loc.buf.addr && params->copy_dest.buf.addr == params->bg_dest.buf.addr
117
     && params->copy_dest.pos.x == params->bg_dest.pos.x && !params->fill_dest.loc.buf.addr
118
     && params->copy_dest.pos.y == params->bg_dest.pos.y && params->copy_src.loc.buf.addr
119
     && params->copy_src.size.x == params->bg_src.size.x && params->copy_dest.buf.addr
120
     && params->copy_src.size.y == params->bg_src.size.y && params->bg_opacity)
121
    {
527 theseven 122
        blenda(params->copy_src.size.x, params->copy_src.size.y, params->bg_opacity,
123
               params->copy_dest.buf.addr, params->copy_dest.pos.x,
124
               params->copy_dest.pos.y, params->copy_dest.buf.stride,
125
               params->copy_src.loc.buf.addr, params->copy_src.loc.pos.x,
126
               params->copy_src.loc.pos.y, params->copy_src.loc.buf.stride,
127
               params->bg_src.loc.buf.addr, params->bg_src.loc.pos.x,
128
               params->bg_src.loc.pos.y, params->bg_src.loc.buf.stride);
504 theseven 129
    }
130
    else
131
    {
132
        if (params->copy_src.loc.buf.addr && params->copy_dest.buf.addr)
133
            blit(params->copy_src.size.x, params->copy_src.size.y, 3,
134
                 params->copy_dest.buf.addr, params->copy_dest.pos.x,
135
                 params->copy_dest.pos.y, params->copy_dest.buf.stride,
136
                 params->copy_src.loc.buf.addr, params->copy_src.loc.pos.x,
137
                 params->copy_src.loc.pos.y, params->copy_src.loc.buf.stride);
138
        if (params->fill_dest.loc.buf.addr)
139
            blendcolor(params->fill_dest.size.x, params->fill_dest.size.y, params->fill_color,
140
                       params->fill_dest.loc.buf.addr, params->fill_dest.loc.pos.x,
141
                       params->fill_dest.loc.pos.y, params->fill_dest.loc.buf.stride,
142
                       params->fill_dest.loc.buf.addr, params->fill_dest.loc.pos.x,
143
                       params->fill_dest.loc.pos.y, params->fill_dest.loc.buf.stride);
144
        if (params->bg_opacity && params->bg_src.loc.buf.addr && params->bg_dest.buf.addr)
527 theseven 145
            blenda(params->bg_src.size.x, params->bg_src.size.y, params->bg_opacity,
146
                   params->bg_dest.buf.addr, params->bg_dest.pos.x,
147
                   params->bg_dest.pos.y, params->bg_dest.buf.stride,
148
                   params->bg_dest.buf.addr, params->bg_dest.pos.x,
149
                   params->bg_dest.pos.y, params->bg_dest.buf.stride,
150
                   params->bg_src.loc.buf.addr, params->bg_src.loc.pos.x,
151
                   params->bg_src.loc.pos.y, params->bg_src.loc.buf.stride);
504 theseven 152
    }
153
    void* buf = params->viewport.loc.buf.addr;
154
    int stride = params->viewport.loc.buf.stride;
155
    int x = params->viewport.loc.pos.x;
156
    int y = params->viewport.loc.pos.y;
157
    const struct chooser_renderer_list_itemdata* iparams;
158
    while (item <= rdata->bottom_item)
159
    {
160
        iparams = (const struct chooser_renderer_list_itemdata*)(item->renderparams);
161
        uint32_t fill_color;
162
        uint32_t text_color;
163
        const struct libui_surface* icon;
164
        int icon_opacity;
703 theseven 165
        if (item == selected)
504 theseven 166
        {
167
            fill_color = iparams->fill_color_selected;
168
            text_color = iparams->text_color_selected;
169
            icon = &iparams->icon_selected;
170
            icon_opacity = iparams->icon_selected_opacity;
171
        }
172
        else
173
        {
174
            fill_color = iparams->fill_color;
175
            text_color = iparams->text_color;
176
            icon = &iparams->icon;
177
            icon_opacity = iparams->icon_opacity;
178
        }
179
        if (fill_color)
180
            blendcolor(iparams->fill_box.size.x, iparams->fill_box.size.y, fill_color,
181
                       buf, x + iparams->fill_box.pos.x, y + iparams->fill_box.pos.y, stride,
182
                       buf, x + iparams->fill_box.pos.x, y + iparams->fill_box.pos.y, stride);
183
        if (icon->loc.buf.addr && icon_opacity)
527 theseven 184
            blenda(icon->size.x, icon->size.y, icon_opacity,
185
                   buf, x + iparams->icon_pos.x, y + iparams->icon_pos.y, stride,
186
                   buf, x + iparams->icon_pos.x, y + iparams->icon_pos.y, stride);
504 theseven 187
        if (iparams->text && iparams->text_color)
188
            rendertext(buf, x + iparams->text_pos.x, y + iparams->text_pos.y,
189
                       stride, text_color, 0, iparams->text);
820 theseven 190
        if (iparams->render) iparams->render(data, item, item == selected, x, y);
504 theseven 191
        y += iparams->size.y;
192
        item++;
193
    }
194
    if (params->preblit && params->preblit(data)) return CHOOSER_RESULT_OK;
195
    displaylcd(params->blit_dest.x, params->blit_dest.y, params->blit_src.size.x,
196
               params->blit_src.size.y, params->blit_src.loc.buf.addr, params->blit_src.loc.pos.x,
197
               params->blit_src.loc.pos.y, params->blit_src.loc.buf.stride);
198
    if (params->postblit) params->postblit(data);
199
    return CHOOSER_RESULT_OK;
200
}
201
 
202
static const struct chooser_item* chooser_renderer_list_itematpixel(struct chooser_data* data,
203
                                                                    int x, int y)
204
{
205
    if (x < 0 || y < 0) return NULL;
206
    const struct chooser_renderer_list_params* params;
207
    params = (const struct chooser_renderer_list_params*)(data->info->rendererparams);
208
    struct chooser_renderer_list_data* rdata;
209
    rdata = (struct chooser_renderer_list_data*)(data->rendererdata);
210
    const struct chooser_item* item = rdata->top_item;
211
    const struct chooser_renderer_list_itemdata* iparams;
212
    while (true)
213
    {
214
        if (item >= &data->info->items[data->info->itemcount]) return NULL;
215
        iparams = (const struct chooser_renderer_list_itemdata*)(item->renderparams);
216
        if (y < iparams->size.y) break;
217
        y -= iparams->size.y;
218
        item++;
219
    }
220
    if (x < iparams->size.x) return item;
221
    return NULL;
222
}
223
 
224
static void chooser_renderer_list_destroy(struct chooser_data* data)
225
{
226
    free(data->rendererdata);
227
}
228
 
820 theseven 229
void chooser_renderer_list_render_attached_text(struct chooser_data* data,
230
                                                const struct chooser_item* item,
231
                                                bool selected, int x, int y, const char* text)
232
{
233
    struct chooser_renderer_list_params* rparams;
234
    rparams = (struct chooser_renderer_list_params*)data->info->rendererparams;
235
    struct chooser_renderer_list_itemdata* ritem;
236
    ritem = (struct chooser_renderer_list_itemdata*)item->renderparams;
237
    void* buf = rparams->viewport.loc.buf.addr;
238
    int stride = rparams->viewport.loc.buf.stride;
239
    x += ritem->size.x - ritem->text_pos.x - strlen(text) * get_font_width();
240
    y += ritem->text_pos.y;
241
    uint32_t color = selected ? ritem->text_color_selected : ritem->text_color;
242
    rendertext(buf, x, y, stride, color, 0, text);
243
}
504 theseven 244
 
820 theseven 245
void chooser_renderer_list_show_arrow_right(struct chooser_data* data,
246
                                            const struct chooser_item* item,
247
                                            bool selected, int x, int y)
248
{
249
    chooser_renderer_list_render_attached_text(data, item, selected, x, y, ">");
250
}
251
 
252
void chooser_renderer_list_show_arrow_left(struct chooser_data* data,
253
                                           const struct chooser_item* item,
254
                                           bool selected, int x, int y)
255
{
256
    chooser_renderer_list_render_attached_text(data, item, selected, x, y, "<");
257
}
258
 
259
 
504 theseven 260
const struct chooser_renderer chooser_renderer_list = 
261
{
262
    .version = CHOOSER_RENDERER_VERSION,
263
    .init = chooser_renderer_list_init,
264
    .render = chooser_renderer_list_render,
265
    .itematpixel = chooser_renderer_list_itematpixel,
266
    .destroy = chooser_renderer_list_destroy
267
};