Subversion Repositories freemyipod

Rev

Rev 509 | Rev 678 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
527 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_iconflow.h"
28
 
29
 
30
static int chooser_renderer_iconflow_init(struct chooser_data* data)
31
{
32
    const struct chooser_renderer_iconflow_params* params;
33
    params = (const struct chooser_renderer_iconflow_params*)(data->info->rendererparams);
34
    if (params->version != CHOOSER_RENDERER_ICONFLOW_PARAMS_VERSION) return -1;
35
    data->rendererdata = malloc(sizeof(struct chooser_renderer_iconflow_data));
36
    if (!data->rendererdata) return -2;
37
    struct chooser_renderer_iconflow_data* rdata;
38
    rdata = (struct chooser_renderer_iconflow_data*)(data->rendererdata);
39
    rdata->viewposition = params->startposition * data->info->actionhandler->stepsperitem(data);
40
    rdata->lastupdate = USEC_TIMER;
41
    return 0;
42
}
43
 
44
static void chooser_renderer_iconflow_geticondata(int x, int y, int w, int h, int siv,
45
                                                  int dist, const struct libui_surface* icon,
46
                                                  int* ix, int* iy, int* io)
47
{
48
    *ix = x + (w - icon->size.x) * (dist + siv / 2) / siv;
49
    *iy = y + (h - icon->size.y) - (h - icon->size.y) * dist * dist * 2 / (siv * siv);
50
    *io = MAX(0, 255 - 510 * ABS(dist) / siv);
51
}
52
 
53
static enum chooser_result chooser_renderer_iconflow_render(struct chooser_data* data)
54
{
55
    enum chooser_result rc = CHOOSER_RESULT_OK;
56
    const struct chooser_renderer_iconflow_params* params;
57
    params = (const struct chooser_renderer_iconflow_params*)(data->info->rendererparams);
58
    struct chooser_renderer_iconflow_data* rdata;
59
    rdata = (struct chooser_renderer_iconflow_data*)(data->rendererdata);
60
    long time = USEC_TIMER;
61
    long timediff = time - rdata->lastupdate;
62
    int distance = data->position - rdata->viewposition;
63
    if (distance) rc = CHOOSER_RESULT_REDRAW;
64
    int factor = params->smoothness / timediff + 1;
65
    rdata->accumulator += distance;
66
    distance = rdata->accumulator / factor;
67
    rdata->accumulator -= distance * factor;
68
    rdata->viewposition += distance;
69
    rdata->lastupdate = time;
70
    if (params->copy_dest.buf.addr == params->fill_dest.loc.buf.addr
71
     && params->copy_dest.buf.stride == params->fill_dest.loc.buf.stride
72
     && params->copy_dest.pos.x == params->fill_dest.loc.pos.x
73
     && params->copy_dest.pos.y == params->fill_dest.loc.pos.y
74
     && params->copy_src.size.x == params->fill_dest.size.x
75
     && params->copy_src.size.y == params->fill_dest.size.y && params->copy_src.loc.buf.addr)
76
    {
77
        blendcolor(params->copy_src.size.x, params->copy_src.size.y, params->fill_color,
78
                   params->copy_dest.buf.addr, params->copy_dest.pos.x,
79
                   params->copy_dest.pos.y, params->copy_dest.buf.stride,
80
                   params->copy_src.loc.buf.addr, params->copy_src.loc.pos.x,
81
                   params->copy_src.loc.pos.y, params->copy_src.loc.buf.stride);
82
        if (params->bg_opacity && params->bg_dest.buf.addr && params->bg_src.loc.buf.addr)
83
            blenda(params->bg_src.size.x, params->bg_src.size.y, params->bg_opacity,
84
                   params->bg_dest.buf.addr, params->bg_dest.pos.x,
85
                   params->bg_dest.pos.y, params->bg_dest.buf.stride,
86
                   params->bg_dest.buf.addr, params->bg_dest.pos.x,
87
                   params->bg_dest.pos.y, params->bg_dest.buf.stride,
88
                   params->bg_src.loc.buf.addr, params->bg_src.loc.pos.x,
89
                   params->bg_src.loc.pos.y, params->bg_src.loc.buf.stride);
90
    }
91
    else if (params->copy_dest.buf.stride == params->bg_dest.buf.stride
92
     && params->bg_src.loc.buf.addr && params->copy_dest.buf.addr == params->bg_dest.buf.addr
93
     && params->copy_dest.pos.x == params->bg_dest.pos.x && !params->fill_dest.loc.buf.addr
94
     && params->copy_dest.pos.y == params->bg_dest.pos.y && params->copy_src.loc.buf.addr
95
     && params->copy_src.size.x == params->bg_src.size.x && params->copy_dest.buf.addr
96
     && params->copy_src.size.y == params->bg_src.size.y && params->bg_opacity)
97
    {
98
        blenda(params->copy_src.size.x, params->copy_src.size.y, params->bg_opacity,
99
               params->copy_dest.buf.addr, params->copy_dest.pos.x,
100
               params->copy_dest.pos.y, params->copy_dest.buf.stride,
101
               params->copy_src.loc.buf.addr, params->copy_src.loc.pos.x,
102
               params->copy_src.loc.pos.y, params->copy_src.loc.buf.stride,
103
               params->bg_src.loc.buf.addr, params->bg_src.loc.pos.x,
104
               params->bg_src.loc.pos.y, params->bg_src.loc.buf.stride);
105
    }
106
    else
107
    {
108
        if (params->copy_src.loc.buf.addr && params->copy_dest.buf.addr)
109
            blit(params->copy_src.size.x, params->copy_src.size.y, 3,
110
                 params->copy_dest.buf.addr, params->copy_dest.pos.x,
111
                 params->copy_dest.pos.y, params->copy_dest.buf.stride,
112
                 params->copy_src.loc.buf.addr, params->copy_src.loc.pos.x,
113
                 params->copy_src.loc.pos.y, params->copy_src.loc.buf.stride);
114
        if (params->fill_dest.loc.buf.addr)
115
            blendcolor(params->fill_dest.size.x, params->fill_dest.size.y, params->fill_color,
116
                       params->fill_dest.loc.buf.addr, params->fill_dest.loc.pos.x,
117
                       params->fill_dest.loc.pos.y, params->fill_dest.loc.buf.stride,
118
                       params->fill_dest.loc.buf.addr, params->fill_dest.loc.pos.x,
119
                       params->fill_dest.loc.pos.y, params->fill_dest.loc.buf.stride);
120
        if (params->bg_opacity && params->bg_src.loc.buf.addr && params->bg_dest.buf.addr)
121
            blenda(params->bg_src.size.x, params->bg_src.size.y, params->bg_opacity,
122
                   params->bg_dest.buf.addr, params->bg_dest.pos.x,
123
                   params->bg_dest.pos.y, params->bg_dest.buf.stride,
124
                   params->bg_dest.buf.addr, params->bg_dest.pos.x,
125
                   params->bg_dest.pos.y, params->bg_dest.buf.stride,
126
                   params->bg_src.loc.buf.addr, params->bg_src.loc.pos.x,
127
                   params->bg_src.loc.pos.y, params->bg_src.loc.buf.stride);
128
    }
129
    void* buf = params->viewport.loc.buf.addr;
130
    int stride = params->viewport.loc.buf.stride;
131
    int x = params->viewport.loc.pos.x;
132
    int y = params->viewport.loc.pos.y;
133
    int w = params->viewport.size.x;
134
    int h = params->viewport.size.y;
135
    int spi = data->info->actionhandler->stepsperitem(data);
136
    int dir = 1;
137
    int pos = spi / 2;
138
    int vpos = rdata->viewposition;
139
    int iiv = params->iconsinview;
140
    const struct chooser_renderer_iconflow_itemdata* iparams;
141
    const struct chooser_item* item = data->info->items;
142
    while (true)
143
    {
144
        if (item == data->selected && dir == 1)
145
        {
146
            dir = -1;
147
            item = &data->info->items[data->info->itemcount - 1];
148
            pos = spi * data->info->itemcount - spi / 2;
149
        }
150
        iparams = (const struct chooser_renderer_iconflow_itemdata*)(item->renderparams);
151
        const struct libui_surface* icon;
152
        if (item == data->selected) icon = &iparams->icon_selected;
153
        else icon = &iparams->icon;
154
        int ix, iy, io;
155
        int dist = pos - vpos;
156
        chooser_renderer_iconflow_geticondata(x, y, w, h, spi * iiv, dist, icon, &ix, &iy, &io);
157
        if (item == data->selected)
158
        {
159
            io = 255;
160
            if (iparams->text && iparams->text_color)
161
                rendertext(buf, params->text_pos.x - strlen(iparams->text) * get_font_width() / 2,
162
                           params->text_pos.y, stride, iparams->text_color, 0, iparams->text);
163
        }
164
        if (icon->loc.buf.addr && io && ix >= x && iy >= y
165
         && ix + icon->size.x <= x + w && iy + icon->size.y <= y + h)
166
            blenda(icon->size.x, icon->size.y, io, buf, ix, iy, stride, buf, ix, iy, stride,
167
                   icon->loc.buf.addr, icon->loc.pos.x, icon->loc.pos.y, icon->loc.buf.stride);
168
        if (item == data->selected) break;
169
        item += dir;
170
        pos += dir * spi;
171
    }
172
    if (params->preblit && params->preblit(data)) return rc;
173
    displaylcd(params->blit_dest.x, params->blit_dest.y, params->blit_src.size.x,
174
               params->blit_src.size.y, params->blit_src.loc.buf.addr, params->blit_src.loc.pos.x,
175
               params->blit_src.loc.pos.y, params->blit_src.loc.buf.stride);
176
    if (params->postblit) params->postblit(data);
177
    return rc;
178
}
179
 
180
static const struct chooser_item* chooser_renderer_iconflow_itematpixel(struct chooser_data* data,
181
                                                                        int x, int y)
182
{
183
    if (x < 0 || y < 0) return NULL;
184
    const struct chooser_renderer_iconflow_params* params;
185
    params = (const struct chooser_renderer_iconflow_params*)(data->info->rendererparams);
186
    if (x >= params->viewport.size.x || y >= params->viewport.size.y) return NULL;
187
    struct chooser_renderer_iconflow_data* rdata;
188
    rdata = (struct chooser_renderer_iconflow_data*)(data->rendererdata);
189
    const struct chooser_item* result = NULL;
190
    int vx = params->viewport.loc.pos.x;
191
    int vy = params->viewport.loc.pos.y;
192
    int vw = params->viewport.size.x;
193
    int vh = params->viewport.size.y;
194
    int spi = data->info->actionhandler->stepsperitem(data);
195
    int dir = 1;
196
    int pos = spi / 2;
197
    int vpos = rdata->viewposition;
198
    int iiv = params->iconsinview;
199
    const struct chooser_renderer_iconflow_itemdata* iparams;
200
    const struct chooser_item* item = data->info->items;
201
    while (true)
202
    {
203
        if (item == data->selected && dir == 1)
204
        {
205
            dir = -1;
206
            item = &data->info->items[data->info->itemcount - 1];
207
            pos = spi * data->info->itemcount - spi / 2;
208
        }
209
        iparams = (const struct chooser_renderer_iconflow_itemdata*)(item->renderparams);
210
        const struct libui_surface* icon;
211
        if (item == data->selected) icon = &iparams->icon_selected;
212
        else icon = &iparams->icon;
213
        int ix, iy, o;
214
        int dist = pos - vpos;
215
        chooser_renderer_iconflow_geticondata(vx, vy, vw, vh, spi * iiv, dist, icon, &ix, &iy, &o);
216
        if (x >= ix && y >= ix && x < ix + icon->size.x && y < iy + icon->size.y) result = item;
217
        if (item == data->selected) break;
218
        item += dir;
219
        pos += dir * spi;
220
    }
221
    return result;
222
}
223
 
224
static void chooser_renderer_iconflow_destroy(struct chooser_data* data)
225
{
226
    free(data->rendererdata);
227
}
228
 
229
 
230
const struct chooser_renderer chooser_renderer_iconflow = 
231
{
232
    .version = CHOOSER_RENDERER_VERSION,
233
    .init = chooser_renderer_iconflow_init,
234
    .render = chooser_renderer_iconflow_render,
235
    .itematpixel = chooser_renderer_iconflow_itematpixel,
236
    .destroy = chooser_renderer_iconflow_destroy
237
};