Subversion Repositories freemyipod

Rev

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