Subversion Repositories freemyipod

Rev

Rev 527 | Go to most recent revision | Details | 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
        }
50
    }
51
    rdata->bottom_item = --curr;
52
    while (curr < item && curr < &data->info->items[data->info->itemcount])
53
    {
54
        curr++;
55
        iparams = (const struct chooser_renderer_list_itemdata*)(curr->renderparams);
56
        available -= iparams->size.y;
57
        while (available < 0)
58
        {
59
            const struct chooser_item* top = rdata->top_item++;
60
            iparams = (const struct chooser_renderer_list_itemdata*)(top->renderparams);
61
            available += iparams->size.y;
62
        }
63
        rdata->bottom_item = curr;
64
    }
65
}
66
 
67
static int chooser_renderer_list_init(struct chooser_data* data)
68
{
69
    const struct chooser_renderer_list_params* params;
70
    params = (const struct chooser_renderer_list_params*)(data->info->rendererparams);
71
    if (params->version != CHOOSER_RENDERER_LIST_PARAMS_VERSION) return -1;
72
    data->rendererdata = malloc(sizeof(struct chooser_renderer_list_data));
73
    if (!data->rendererdata) return -2;
74
    struct chooser_renderer_list_data* rdata;
75
    rdata = (struct chooser_renderer_list_data*)(data->rendererdata);
76
    rdata->top_item = data->info->items;
77
    chooser_renderer_list_scroll_into_view(data, data->selected);
78
    return 0;
79
}
80
 
81
static enum chooser_result chooser_renderer_list_render(struct chooser_data* data)
82
{
83
    const struct chooser_renderer_list_params* params;
84
    params = (const struct chooser_renderer_list_params*)(data->info->rendererparams);
85
    struct chooser_renderer_list_data* rdata;
86
    rdata = (struct chooser_renderer_list_data*)(data->rendererdata);
87
    chooser_renderer_list_scroll_into_view(data, data->selected);
88
    const struct chooser_item* item = rdata->top_item;
89
    if (params->copy_dest.buf.addr == params->fill_dest.loc.buf.addr
90
     && params->copy_dest.buf.stride == params->fill_dest.loc.buf.stride
91
     && params->copy_dest.pos.x == params->fill_dest.loc.pos.x
92
     && params->copy_dest.pos.y == params->fill_dest.loc.pos.y
93
     && params->copy_src.size.x == params->fill_dest.size.x
94
     && params->copy_src.size.y == params->fill_dest.size.y && params->copy_src.loc.buf.addr)
95
    {
96
        blendcolor(params->copy_src.size.x, params->copy_src.size.y, params->fill_color,
97
                   params->copy_dest.buf.addr, params->copy_dest.pos.x,
98
                   params->copy_dest.pos.y, params->copy_dest.buf.stride,
99
                   params->copy_src.loc.buf.addr, params->copy_src.loc.pos.x,
100
                   params->copy_src.loc.pos.y, params->copy_src.loc.buf.stride);
101
        if (params->bg_opacity && params->bg_dest.buf.addr && params->bg_src.loc.buf.addr)
102
            blend(params->bg_src.size.x, params->bg_src.size.y, params->bg_opacity,
103
                  params->bg_dest.buf.addr, params->bg_dest.pos.x,
104
                  params->bg_dest.pos.y, params->bg_dest.buf.stride,
105
                  params->bg_dest.buf.addr, params->bg_dest.pos.x,
106
                  params->bg_dest.pos.y, params->bg_dest.buf.stride,
107
                  params->bg_src.loc.buf.addr, params->bg_src.loc.pos.x,
108
                  params->bg_src.loc.pos.y, params->bg_src.loc.buf.stride);
109
    }
110
    else if (params->copy_dest.buf.stride == params->bg_dest.buf.stride
111
     && params->bg_src.loc.buf.addr && params->copy_dest.buf.addr == params->bg_dest.buf.addr
112
     && params->copy_dest.pos.x == params->bg_dest.pos.x && !params->fill_dest.loc.buf.addr
113
     && params->copy_dest.pos.y == params->bg_dest.pos.y && params->copy_src.loc.buf.addr
114
     && params->copy_src.size.x == params->bg_src.size.x && params->copy_dest.buf.addr
115
     && params->copy_src.size.y == params->bg_src.size.y && params->bg_opacity)
116
    {
117
        blend(params->copy_src.size.x, params->copy_src.size.y, params->bg_opacity,
118
              params->copy_dest.buf.addr, params->copy_dest.pos.x,
119
              params->copy_dest.pos.y, params->copy_dest.buf.stride,
120
              params->copy_src.loc.buf.addr, params->copy_src.loc.pos.x,
121
              params->copy_src.loc.pos.y, params->copy_src.loc.buf.stride,
122
              params->bg_src.loc.buf.addr, params->bg_src.loc.pos.x,
123
              params->bg_src.loc.pos.y, params->bg_src.loc.buf.stride);
124
    }
125
    else
126
    {
127
        if (params->copy_src.loc.buf.addr && params->copy_dest.buf.addr)
128
            blit(params->copy_src.size.x, params->copy_src.size.y, 3,
129
                 params->copy_dest.buf.addr, params->copy_dest.pos.x,
130
                 params->copy_dest.pos.y, params->copy_dest.buf.stride,
131
                 params->copy_src.loc.buf.addr, params->copy_src.loc.pos.x,
132
                 params->copy_src.loc.pos.y, params->copy_src.loc.buf.stride);
133
        if (params->fill_dest.loc.buf.addr)
134
            blendcolor(params->fill_dest.size.x, params->fill_dest.size.y, params->fill_color,
135
                       params->fill_dest.loc.buf.addr, params->fill_dest.loc.pos.x,
136
                       params->fill_dest.loc.pos.y, params->fill_dest.loc.buf.stride,
137
                       params->fill_dest.loc.buf.addr, params->fill_dest.loc.pos.x,
138
                       params->fill_dest.loc.pos.y, params->fill_dest.loc.buf.stride);
139
        if (params->bg_opacity && params->bg_src.loc.buf.addr && params->bg_dest.buf.addr)
140
            blend(params->bg_src.size.x, params->bg_src.size.y, params->bg_opacity,
141
                  params->bg_dest.buf.addr, params->bg_dest.pos.x,
142
                  params->bg_dest.pos.y, params->bg_dest.buf.stride,
143
                  params->bg_dest.buf.addr, params->bg_dest.pos.x,
144
                  params->bg_dest.pos.y, params->bg_dest.buf.stride,
145
                  params->bg_src.loc.buf.addr, params->bg_src.loc.pos.x,
146
                  params->bg_src.loc.pos.y, params->bg_src.loc.buf.stride);
147
    }
148
    void* buf = params->viewport.loc.buf.addr;
149
    int stride = params->viewport.loc.buf.stride;
150
    int x = params->viewport.loc.pos.x;
151
    int y = params->viewport.loc.pos.y;
152
    const struct chooser_renderer_list_itemdata* iparams;
153
    while (item <= rdata->bottom_item)
154
    {
155
        iparams = (const struct chooser_renderer_list_itemdata*)(item->renderparams);
156
        uint32_t fill_color;
157
        uint32_t text_color;
158
        const struct libui_surface* icon;
159
        int icon_opacity;
160
        if (item == data->selected)
161
        {
162
            fill_color = iparams->fill_color_selected;
163
            text_color = iparams->text_color_selected;
164
            icon = &iparams->icon_selected;
165
            icon_opacity = iparams->icon_selected_opacity;
166
        }
167
        else
168
        {
169
            fill_color = iparams->fill_color;
170
            text_color = iparams->text_color;
171
            icon = &iparams->icon;
172
            icon_opacity = iparams->icon_opacity;
173
        }
174
        if (fill_color)
175
            blendcolor(iparams->fill_box.size.x, iparams->fill_box.size.y, fill_color,
176
                       buf, x + iparams->fill_box.pos.x, y + iparams->fill_box.pos.y, stride,
177
                       buf, x + iparams->fill_box.pos.x, y + iparams->fill_box.pos.y, stride);
178
        if (icon->loc.buf.addr && icon_opacity)
179
            blend(icon->size.x, icon->size.y, icon_opacity,
180
                  buf, x + iparams->icon_pos.x, y + iparams->icon_pos.y, stride,
181
                  buf, x + iparams->icon_pos.x, y + iparams->icon_pos.y, stride);
182
        if (iparams->text && iparams->text_color)
183
            rendertext(buf, x + iparams->text_pos.x, y + iparams->text_pos.y,
184
                       stride, text_color, 0, iparams->text);
185
        y += iparams->size.y;
186
        item++;
187
    }
188
    if (params->preblit && params->preblit(data)) return CHOOSER_RESULT_OK;
189
    displaylcd(params->blit_dest.x, params->blit_dest.y, params->blit_src.size.x,
190
               params->blit_src.size.y, params->blit_src.loc.buf.addr, params->blit_src.loc.pos.x,
191
               params->blit_src.loc.pos.y, params->blit_src.loc.buf.stride);
192
    if (params->postblit) params->postblit(data);
193
    return CHOOSER_RESULT_OK;
194
}
195
 
196
static const struct chooser_item* chooser_renderer_list_itematpixel(struct chooser_data* data,
197
                                                                    int x, int y)
198
{
199
    if (x < 0 || y < 0) return NULL;
200
    const struct chooser_renderer_list_params* params;
201
    params = (const struct chooser_renderer_list_params*)(data->info->rendererparams);
202
    struct chooser_renderer_list_data* rdata;
203
    rdata = (struct chooser_renderer_list_data*)(data->rendererdata);
204
    const struct chooser_item* item = rdata->top_item;
205
    const struct chooser_renderer_list_itemdata* iparams;
206
    while (true)
207
    {
208
        if (item >= &data->info->items[data->info->itemcount]) return NULL;
209
        iparams = (const struct chooser_renderer_list_itemdata*)(item->renderparams);
210
        if (y < iparams->size.y) break;
211
        y -= iparams->size.y;
212
        item++;
213
    }
214
    if (x < iparams->size.x) return item;
215
    return NULL;
216
}
217
 
218
static void chooser_renderer_list_destroy(struct chooser_data* data)
219
{
220
    free(data->rendererdata);
221
}
222
 
223
 
224
const struct chooser_renderer chooser_renderer_list = 
225
{
226
    .version = CHOOSER_RENDERER_VERSION,
227
    .init = chooser_renderer_list_init,
228
    .render = chooser_renderer_list_render,
229
    .itematpixel = chooser_renderer_list_itematpixel,
230
    .destroy = chooser_renderer_list_destroy
231
};