Subversion Repositories freemyipod

Rev

Rev 703 | Go to most recent revision | 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);
190
        y += iparams->size.y;
191
        item++;
192
    }
193
    if (params->preblit && params->preblit(data)) return CHOOSER_RESULT_OK;
194
    displaylcd(params->blit_dest.x, params->blit_dest.y, params->blit_src.size.x,
195
               params->blit_src.size.y, params->blit_src.loc.buf.addr, params->blit_src.loc.pos.x,
196
               params->blit_src.loc.pos.y, params->blit_src.loc.buf.stride);
197
    if (params->postblit) params->postblit(data);
198
    return CHOOSER_RESULT_OK;
199
}
200
 
201
static const struct chooser_item* chooser_renderer_list_itematpixel(struct chooser_data* data,
202
                                                                    int x, int y)
203
{
204
    if (x < 0 || y < 0) return NULL;
205
    const struct chooser_renderer_list_params* params;
206
    params = (const struct chooser_renderer_list_params*)(data->info->rendererparams);
207
    struct chooser_renderer_list_data* rdata;
208
    rdata = (struct chooser_renderer_list_data*)(data->rendererdata);
209
    const struct chooser_item* item = rdata->top_item;
210
    const struct chooser_renderer_list_itemdata* iparams;
211
    while (true)
212
    {
213
        if (item >= &data->info->items[data->info->itemcount]) return NULL;
214
        iparams = (const struct chooser_renderer_list_itemdata*)(item->renderparams);
215
        if (y < iparams->size.y) break;
216
        y -= iparams->size.y;
217
        item++;
218
    }
219
    if (x < iparams->size.x) return item;
220
    return NULL;
221
}
222
 
223
static void chooser_renderer_list_destroy(struct chooser_data* data)
224
{
225
    free(data->rendererdata);
226
}
227
 
228
 
229
const struct chooser_renderer chooser_renderer_list = 
230
{
231
    .version = CHOOSER_RENDERER_VERSION,
232
    .init = chooser_renderer_list_init,
233
    .render = chooser_renderer_list_render,
234
    .itematpixel = chooser_renderer_list_itematpixel,
235
    .destroy = chooser_renderer_list_destroy
236
};