Finalize listview visuals and animations

* Implement batching of framebuffer item changes
  - when you enter a batch, rendering is blocked
* Support changing of base background framebuffer color
This commit is contained in:
Vojtech Bocek
2014-07-02 23:57:17 +02:00
parent 5207b3ae83
commit 7797f90eff
11 changed files with 200 additions and 202 deletions

View File

@@ -39,7 +39,7 @@ ifeq ($(ARCH_ARM_HAVE_NEON),true)
LOCAL_CFLAGS += -DHAS_NEON_BLEND
endif
#LOCAL_CFLAGS += -D_FORTIFY_SOURCE=2 -fstack-protector-all -O0 -g -fno-omit-frame-pointer
#LOCAL_CFLAGS += -D_FORTIFY_SOURCE=2 -fstack-protector-all -O0 -g -fno-omit-frame-pointer -Wall
LOCAL_MODULE:= multirom
LOCAL_MODULE_TAGS := eng

View File

@@ -18,6 +18,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <math.h>
#include "log.h"
#include "workers.h"
@@ -118,32 +119,48 @@ static float anim_interpolate(int type, float input)
case INTERPOLATOR_OVERSHOOT:
input -= 1.f;
return (input * input * ((OVERSHOOT_TENSION+1.f) * input + OVERSHOOT_TENSION) + 1.f);
case INTERPOLATOR_ACCEL_DECEL:
return (float)(cos((input + 1) * M_PI) / 2.0f) + 0.5f;
}
}
static inline void anim_int_step(int *prop, int start, int target, float interpolated)
static inline void anim_int_step(int *prop, int *start, int *last, int *target, float interpolated)
{
if(target != -1)
*prop = start + (int)((target - start) * interpolated);
if(*target != -1)
{
const int diff = *prop - *last;
*start += diff;
*prop = *start + (int)((*target) * interpolated);
*last = *prop;
}
}
static void item_anim_step(item_anim *anim, float interpolated)
{
fb_item_header *fb_it = anim->item;
anim_int_step(&fb_it->x, anim->startX, anim->targetX, interpolated);
anim_int_step(&fb_it->y, anim->startY, anim->targetY, interpolated);
anim_int_step(&fb_it->w, anim->startW, anim->targetW, interpolated);
anim_int_step(&fb_it->h, anim->startH, anim->targetH, interpolated);
anim_int_step(&fb_it->x, &anim->start[0], &anim->last[0], &anim->targetX, interpolated);
anim_int_step(&fb_it->y, &anim->start[1], &anim->last[1], &anim->targetY, interpolated);
anim_int_step(&fb_it->w, &anim->start[2], &anim->last[2], &anim->targetW, interpolated);
anim_int_step(&fb_it->h, &anim->start[3], &anim->last[3], &anim->targetH, interpolated);
fb_request_draw();
}
static void item_anim_on_start(item_anim *anim)
{
fb_item_header *fb_it = anim->item;
anim->startX = fb_it->x;
anim->startY = fb_it->y;
anim->startW = fb_it->w;
anim->startH = fb_it->h;
anim->start[0] = anim->last[0] = fb_it->x;
anim->start[1] = anim->last[1] = fb_it->y;
anim->start[2] = anim->last[2] = fb_it->w;
anim->start[3] = anim->last[3] = fb_it->h;
if(anim->targetX != -1)
anim->targetX -= fb_it->x;
if(anim->targetY != -1)
anim->targetY -= fb_it->y;
if(anim->targetW != -1)
anim->targetW -= fb_it->w;
if(anim->targetH != -1)
anim->targetH -= fb_it->h;
}
static void item_anim_on_finished(item_anim *anim)
@@ -178,15 +195,7 @@ static void anim_update(uint32_t diff, void *data)
if(anim->start_offset > diff)
anim->start_offset -= diff;
else
{
anim->start_offset = 0;
switch(it->anim_type)
{
case ANIM_TYPE_ITEM:
item_anim_on_start((item_anim*)anim);
break;
}
}
it = it->next;
continue;
}
@@ -357,8 +366,7 @@ item_anim *item_anim_create(void *fb_item, int duration, int interpolator)
void item_anim_add(item_anim *anim)
{
if(!anim->start_offset)
item_anim_on_start(anim);
item_anim_on_start(anim);
struct anim_list_it *it = mzalloc(sizeof(struct anim_list_it));
it->anim_type = ANIM_TYPE_ITEM;

View File

@@ -30,6 +30,7 @@ enum
INTERPOLATOR_DECELERATE,
INTERPOLATOR_ACCELERATE,
INTERPOLATOR_OVERSHOOT,
INTERPOLATOR_ACCEL_DECEL,
};
typedef void (*animation_callback)(void*); // data
@@ -56,8 +57,8 @@ typedef struct
int destroy_item_when_finished;
int startX, startY;
int startW, startH;
int start[4];
int last[4];
int targetX, targetY;
int targetW, targetH;

View File

@@ -66,6 +66,8 @@ static int fb_force_generic = 0;
static fb_context_t fb_ctx = {
.first_item = NULL,
.msgbox = NULL,
.batch_started = 0,
.background_color = BLACK,
.mutex = PTHREAD_MUTEX_INITIALIZER
};
@@ -387,6 +389,36 @@ px_type fb_convert_color(uint32_t c)
#endif
}
void fb_set_background(uint32_t color)
{
fb_ctx.background_color = color;
}
void fb_batch_start(void)
{
pthread_mutex_lock(&fb_ctx.mutex);
fb_ctx.batch_thread = pthread_self();
fb_ctx.batch_started = 1;
}
void fb_batch_end(void)
{
fb_ctx.batch_started = 0;
pthread_mutex_unlock(&fb_ctx.mutex);
}
static inline void fb_items_lock(fb_context_t *ctx)
{
if(!ctx->batch_started || !pthread_equal(ctx->batch_thread, pthread_self()))
pthread_mutex_lock(&ctx->mutex);
}
static inline void fb_items_unlock(fb_context_t *ctx)
{
if(!ctx->batch_started || !pthread_equal(ctx->batch_thread, pthread_self()))
pthread_mutex_unlock(&ctx->mutex);
}
static void fb_ctx_put_it_before(fb_item_header *new_it, fb_item_header *next_it)
{
if(next_it->prev)
@@ -412,7 +444,8 @@ static void fb_ctx_put_it_after(fb_item_header *new_it, fb_item_header *prev_it)
void fb_ctx_add_item(fb_context_t *ctx, void *item)
{
fb_item_header *h = item;
pthread_mutex_lock(&ctx->mutex);
fb_items_lock(ctx);
if(!ctx->first_item)
ctx->first_item = item;
@@ -437,14 +470,16 @@ void fb_ctx_add_item(fb_context_t *ctx, void *item)
if(itr)
fb_ctx_put_it_after(h, itr);
}
pthread_mutex_unlock(&ctx->mutex);
fb_items_unlock(ctx);
}
void fb_ctx_rm_item(fb_context_t *ctx, void *item)
{
fb_item_header *h = item;
pthread_mutex_lock(&ctx->mutex);
fb_items_lock(ctx);
if(!h->prev)
ctx->first_item = h->next;
else
@@ -453,7 +488,7 @@ void fb_ctx_rm_item(fb_context_t *ctx, void *item)
if(h->next)
h->next->prev = h->prev;
pthread_mutex_unlock(&ctx->mutex);
fb_items_unlock(ctx);
}
void fb_remove_item(void *item)
@@ -659,10 +694,10 @@ void fb_draw_img(fb_img *i)
int fb_generate_item_id(void)
{
pthread_mutex_lock(&fb_ctx.mutex);
fb_items_lock(&fb_ctx);
static int id = 0;
int res = id++;
pthread_mutex_unlock(&fb_ctx.mutex);
fb_items_unlock(&fb_ctx);
return res;
}
@@ -959,7 +994,7 @@ static void fb_draw(void)
fb_item_header *it;
pthread_mutex_lock(&fb_ctx.mutex);
fb_fill(0xFFE0E0E0);
fb_fill(fb_ctx.background_color);
// rectangles
for(it = fb_ctx.first_item; it; it = it->next)
@@ -1012,6 +1047,7 @@ void fb_push_context(void)
ctx->first_item = fb_ctx.first_item;
ctx->msgbox = fb_ctx.msgbox;
ctx->background_color = fb_ctx.background_color;
fb_ctx.first_item = NULL;
fb_ctx.msgbox = NULL;
@@ -1034,6 +1070,7 @@ void fb_pop_context(void)
fb_ctx.first_item = ctx->first_item;
fb_ctx.msgbox = ctx->msgbox;
fb_ctx.background_color = ctx->background_color;
pthread_mutex_unlock(&fb_ctx.mutex);

View File

@@ -218,9 +218,12 @@ typedef struct
typedef struct
{
uint32_t background_color;
fb_item_header *first_item;
fb_msgbox *msgbox;
pthread_mutex_t mutex;
volatile int batch_started;
volatile pthread_t batch_thread;
} fb_context_t;
void fb_remove_item(void *item);
@@ -237,6 +240,7 @@ fb_img *fb_add_text_long_lvl_justified(int level, int x, int y, uint32_t color,
fb_img *fb_text_create_item(int x, int y, uint32_t color, int size, int justify, const char *txt);
void fb_text_set_content(fb_img *img, const char *text);
void fb_text_set_color(fb_img *img, uint32_t color);
void fb_text_set_size(fb_img *img, int size);
void fb_text_drop_cache_unused(void);
void fb_text_destroy(fb_img *i);
@@ -268,8 +272,12 @@ int fb_clone(char **buff);
void fb_push_context(void);
void fb_pop_context(void);
void fb_batch_start(void);
void fb_batch_end(void);
void fb_ctx_add_item(fb_context_t *ctx, void *item);
void fb_ctx_rm_item(fb_context_t *ctx, void *item);
void fb_set_background(uint32_t color);
px_type *fb_png_get(const char *path, int w, int h);
void fb_png_release(px_type *data);

View File

@@ -337,9 +337,6 @@ void fb_text_set_content(fb_img *img, const char *text)
if(ex->text)
{
if(strcmp(ex->text, text) == 0)
return;
old_sen = get_cache_for_string(ex->color, ex->size, ex->text);
}
else
@@ -362,12 +359,15 @@ void fb_text_set_content(fb_img *img, const char *text)
img->h = sen->h;
img->data = sen->data;
ex->baseline = sen->baseline;
ex->text = realloc(ex->text, strlen(text)+1);
strcpy(ex->text, text);
if(ex->text != text)
{
ex->text = realloc(ex->text, strlen(text)+1);
strcpy(ex->text, text);
}
++sen->refcnt;
TT_LOG("CACHE: use %02d 0x%08X\n", ex->size, (uint32_t)sen->data);
TT_LOG("Getting string %dx%d %s from cache\n", img->w, img->h, text);
TT_LOG("Getting string %dx%d %s from cache\n", img->w, img->h, ex->text);
return;
}
@@ -445,8 +445,6 @@ void fb_text_set_content(fb_img *img, const char *text)
memset(img->data, 0, maxW*totalH*4);
img->w = maxW;
img->h = totalH;
ex->text = realloc(ex->text, strlen(text)+1);
strcpy(ex->text, text);
for(i = 0; i < lines_cnt; ++i)
render_line(lines[i], en, img->data, img->w, ex->color);
@@ -454,6 +452,12 @@ void fb_text_set_content(fb_img *img, const char *text)
add_to_string_cache(ex->color, ex->baseline, ex->size, text, img->w, img->h, img->data);
list_clear(&lines, &destroy_line);
if(ex->text != text)
{
ex->text = realloc(ex->text, strlen(text)+1);
strcpy(ex->text, text);
}
}
inline void center_text(fb_img *text, int targetX, int targetY, int targetW, int targetH)
@@ -516,6 +520,15 @@ void fb_text_set_color(fb_img *img, uint32_t color)
}
}
void fb_text_set_size(fb_img *img, int size)
{
text_extra *ex = img->extra;
if(ex->size == size)
return;
ex->size = size;
fb_text_set_content(img, ex->text);
}
void fb_text_destroy(fb_img *i)
{
text_extra *ex = i->extra;

View File

@@ -29,12 +29,12 @@
#define MARK_W (10*DPI_MUL)
#define MARK_H (50*DPI_MUL)
#define PADDING (25*DPI_MUL)
#define PADDING (35*DPI_MUL)
#define LINE_W (2*DPI_MUL)
#define SCROLL_DIST (20*DPI_MUL)
#define OVERSCROLL_H (130*DPI_MUL)
#define OVERSCROLL_MARK_H (4*DPI_MUL)
#define OVERSCROLL_RETURN_SPD (15*DPI_MUL)
#define OVERSCROLL_RETURN_SPD (10*DPI_MUL)
static void listview_bounceback(uint32_t diff, void *data)
{
@@ -70,7 +70,7 @@ void listview_init_ui(listview *view)
int x = view->x + view->w - PADDING/2 - LINE_W/2;
fb_rect *scroll_line = fb_add_rect(x, view->y, LINE_W, view->h, GRAY);
scroll_line->parent = view;
scroll_line->parent = (fb_item_pos*)view;
list_add(scroll_line, &view->ui_items);
view->keyact_item_selected = -1;
@@ -78,12 +78,6 @@ void listview_init_ui(listview *view)
view->touch.id = -1;
view->touch.last_y = -1;
if(!view->bg_rect)
{
view->bg_rect = fb_add_rect(view->x, view->y, view->w - PADDING, view->h, 0xFFE0E0E0);
view->bg_rect->parent = view;
}
add_touch_handler(&listview_touch_handler, view);
}
@@ -99,7 +93,6 @@ void listview_destroy(listview *view)
fb_rm_rect(view->scroll_mark);
fb_rm_rect(view->overscroll_marks[0]);
fb_rm_rect(view->overscroll_marks[1]);
fb_rm_rect(view->bg_rect);
free(view);
}
@@ -110,7 +103,7 @@ listview_item *listview_add_item(listview *view, int id, void *data)
it->id = id;
it->data = data;
it->flags = 0;
it->parent_rect = view;
it->parent_rect = (fb_item_pos*)view;
if(!view->items)
keyaction_add(view->x, view->y, listview_keyaction_call, view);
@@ -133,6 +126,8 @@ void listview_update_ui(listview *view)
int i, it_h, visible;
listview_item *it;
fb_batch_start();
for(i = 0; view->items && view->items[i]; ++i)
{
it = view->items[i];
@@ -140,9 +135,11 @@ void listview_update_ui(listview *view)
visible = (int)(view->pos <= y+it_h && y-view->pos <= view->h);
if(!visible && (it->flags & IT_VISIBLE))
(*view->item_hide)(it->data);
else if(visible)
/*if(!visible && (it->flags & IT_VISIBLE))
{
//(*view->item_hide)(it->data);
}
else if(visible)*/
(*view->item_draw)(view->x, view->y+y-view->pos, view->w - PADDING, it);
if(visible)
@@ -159,6 +156,7 @@ void listview_update_ui(listview *view)
if(y > view->h)
listview_update_scroll_mark(view);
fb_batch_end();
fb_request_draw();
}
@@ -171,13 +169,13 @@ void listview_enable_scroll(listview *view, int enable)
{
int x = view->x + view->w - PADDING/2 - MARK_W/2;
view->scroll_mark = fb_add_rect(x, view->y, MARK_W, MARK_H, GRAY);
view->scroll_mark->parent = view;
view->scroll_mark->parent = (fb_item_pos*)view;
view->overscroll_marks[0] = fb_add_rect(view->x, view->y, 0, OVERSCROLL_MARK_H, CLR_SECONDARY);
view->overscroll_marks[0]->parent = view;
view->overscroll_marks[0]->parent = (fb_item_pos*)view;
view->overscroll_marks[1] = fb_add_rect(view->x, view->y+view->h-OVERSCROLL_MARK_H,
0, OVERSCROLL_MARK_H, CLR_SECONDARY);
view->overscroll_marks[1]->parent = view;
view->overscroll_marks[1]->parent = (fb_item_pos*)view;
workers_add(listview_bounceback, view);
}
else
@@ -293,16 +291,16 @@ void listview_select_item(listview *view, listview_item *it)
if(view->selected)
view->selected->flags &= ~(IT_SELECTED);
it->flags |= IT_SELECTED;
view->bg_rect->color = 0xFFE0E0E0;
if(it)
it->flags |= IT_SELECTED;
view->selected = it;
}
void listview_scroll_by(listview *view, int y)
{
if(!view->scroll_mark)
if(!y || !view->scroll_mark)
return;
view->pos += y;
@@ -312,6 +310,7 @@ void listview_scroll_by(listview *view, int y)
else if(view->pos > (view->fullH - view->h) + OVERSCROLL_H)
view->pos = (view->fullH - view->h) + OVERSCROLL_H;
listview_select_item(view, NULL);
listview_update_ui(view);
}
@@ -327,6 +326,7 @@ void listview_scroll_to(listview *view, int pct)
else if(view->pos > (view->fullH - view->h))
view->pos = (view->fullH - view->h);
listview_select_item(view, NULL);
listview_update_ui(view);
}
@@ -464,13 +464,14 @@ void listview_update_keyact_frame(listview *view)
listview_update_ui(view);
}
#define ROM_ITEM_H (110*DPI_MUL)
#define ROM_ITEM_GROW (40*DPI_MUL)
#define ROM_ITEM_H (100*DPI_MUL)
#define ROM_ITEM_SHADOW (5*DPI_MUL)
#define ROM_BOX_PADDING (5*DPI_MUL)
#define ROM_ITEM_SEL_W (8*DPI_MUL)
#define ROM_ICON_PADDING (20*DPI_MUL)
#define ROM_ICON_H (ROM_ITEM_H-(ROM_ICON_PADDING*2))
#define ROM_TEXT_PADDING (130*DPI_MUL)
typedef struct
{
char *text;
@@ -478,23 +479,21 @@ typedef struct
char *icon_path;
fb_text *text_it;
fb_text *part_it;
fb_rect *hover_rect;
fb_rect *sel_rect;
fb_rect *sel_rect_sh;
fb_text *click_text;
fb_rect *click_text_rect;
fb_img *icon;
int hover_removed;
int it_sel_size;
int deselect_anim_started;
int rom_name_size;
int last_y;
} rom_item_data;
void *rom_item_create(const char *text, const char *partition, const char *icon)
{
rom_item_data *data = malloc(sizeof(rom_item_data));
memset(data, 0, sizeof(rom_item_data));
rom_item_data *data = mzalloc(sizeof(rom_item_data));
data->rom_name_size = SIZE_BIG;
data->text = strdup(text);
data->it_sel_size = ROM_ITEM_H;
if(partition)
data->partition = strdup(partition);
if(icon)
@@ -502,50 +501,15 @@ void *rom_item_create(const char *text, const char *partition, const char *icon)
return data;
}
static void rom_item_null_rect(void *data)
{
fb_rect **rect = data;
*rect = NULL;
}
static void rom_item_grow(void *it_v)
{
listview_item *it = it_v;
rom_item_data *d = (rom_item_data*)it->data;
d->sel_rect_sh->x = d->sel_rect->x+5;
d->sel_rect_sh->y = d->sel_rect->y+5;
d->sel_rect_sh->w = d->sel_rect->w;
d->sel_rect_sh->h = d->sel_rect->h;
//d->it_sel_size = d->sel_rect->h;
//listview_update_ui((listview*)it->parent_rect);
}
static void rom_item_shrink(void *it_v, float interpolated)
{
listview_item *it = it_v;
rom_item_data *d = (rom_item_data*)it->data;
if(d->sel_rect_sh)
{
d->sel_rect_sh->h = d->sel_rect->h;
d->sel_rect_sh->y = d->sel_rect->y+5;
}
d->it_sel_size = (ROM_ITEM_H + ROM_ITEM_GROW) - ROM_ITEM_GROW*interpolated;
listview_update_ui((listview*)it->parent_rect);
}
static void rom_item_shrink_finished(void *it_v)
static void rom_item_deselect_finished(void *it_v)
{
listview_item *it = it_v;
rom_item_data *d = (rom_item_data*)it->data;
fb_rm_rect(d->sel_rect);
fb_rm_rect(d->sel_rect_sh);
fb_rm_text(d->click_text);
fb_rm_rect(d->click_text_rect);
d->sel_rect = NULL;
d->sel_rect_sh = NULL;
d->click_text = NULL;
d->click_text_rect = NULL;
}
static void rom_item_alpha(void *it_v, float interpolated)
@@ -553,20 +517,27 @@ static void rom_item_alpha(void *it_v, float interpolated)
listview_item *it = it_v;
rom_item_data *d = (rom_item_data*)it->data;
if(!d->sel_rect || !d->sel_rect_sh)
return;
uint32_t alpha = 0xFF*interpolated;
if(d->hover_removed)
if(d->deselect_anim_started)
alpha = 0xFF - alpha;
alpha <<= 24;
d->sel_rect->color = (d->sel_rect->color & ~(0xFF << 24)) | alpha;
d->sel_rect_sh->color = (d->sel_rect_sh->color & ~(0xFF << 24)) | alpha;
}
static void rom_item_alpha_finished(void *it_v)
static void rom_item_sel_step(void *data)
{
listview_item *it = it_v;
rom_item_data *d = (rom_item_data*)it->data;
rom_item_data *d = data;
if(!d->sel_rect_sh || !d->sel_rect)
return;
d->sel_rect_sh->color = (d->sel_rect_sh->color & ~(0xFF << 24)) | (0xFF << 24);
d->sel_rect_sh->x = d->sel_rect->x + ROM_ITEM_SHADOW;
d->sel_rect_sh->y = d->sel_rect->y + ROM_ITEM_SHADOW;
d->sel_rect_sh->w = d->sel_rect->w;
d->sel_rect_sh->h = d->sel_rect->h;
}
void rom_item_draw(int x, int y, int w, listview_item *it)
@@ -575,9 +546,12 @@ void rom_item_draw(int x, int y, int w, listview_item *it)
const int item_h = rom_item_height(it);
if(!d->text_it)
{
d->text_it = fb_add_text(x+ROM_TEXT_PADDING, 0, BLACK, SIZE_BIG, d->text);
d->text_it = fb_add_text(x+ROM_TEXT_PADDING, 0, BLACK, d->rom_name_size, d->text);
d->text_it->parent = it->parent_rect;
while(d->text_it->w + ROM_TEXT_PADDING >= w && d->rom_name_size > 3)
fb_text_set_size(d->text_it, --d->rom_name_size);
if(d->icon_path)
{
d->icon = fb_add_png_img(x+ROM_ICON_PADDING, 0, ROM_ICON_H, ROM_ICON_H, d->icon_path);
@@ -597,111 +571,67 @@ void rom_item_draw(int x, int y, int w, listview_item *it)
d->icon->y = y + (item_h/2 - ROM_ICON_H/2);
if(d->part_it)
d->part_it->y = d->text_it->y + SIZE_BIG*16 + 2;
/* if(it->flags & IT_HOVER)
{
if(!d->hover_rect)
{
d->hover_rect = fb_add_rect(it->touchX, it->touchY, 1, 1, 0xFFE0E0E0);
INFO("touch %dx%d\n", it->touchX, it->touchY);
d->hover_rect->parent = it->parent_rect;
item_anim *anim = item_anim_create(d->hover_rect, 300, INTERPOLATOR_DECELERATE);
anim->start_offset = 150;
anim->targetX = x;
anim->targetY = y;
anim->targetW = w;
anim->targetH = item_h;
item_anim_add(anim);
d->hover_removed = 0;
}
else
d->hover_rect->y = y;
}
else if(d->hover_rect)
{
if(!d->hover_removed)
{
anim_cancel_for(d->hover_rect, 1);
item_anim *anim = item_anim_create(d->hover_rect, 100, INTERPOLATOR_ACCELERATE);
anim->targetX = it->touchX;
anim->targetY = it->touchY;
anim->targetW = 0;
anim->targetH = 0;
anim->destroy_item_when_finished = 1;
anim->on_finished_data = &d->hover_rect;
anim->on_finished_call = rom_item_null_rect;
item_anim_add_after(anim);
d->hover_removed = 1;
}
else
{
d->hover_rect->y = y;
}
}*/
d->part_it->y = d->text_it->y + d->text_it->h + 2*DPI_MUL;
if(it->flags & IT_SELECTED)
{
if(!d->sel_rect)
{
d->sel_rect_sh = fb_add_rect(x+7, y+7, w, item_h, GRAYISH & ~(0xFF << 24));
d->sel_rect = fb_add_rect(x+7, y+7, w, item_h, WHITE & ~(0xFF << 24));
d->sel_rect->parent = it->parent_rect;
d->sel_rect_sh = fb_add_rect(it->touchX+ROM_ITEM_SHADOW, it->touchY+ROM_ITEM_SHADOW, 1, 1, GRAYISH & ~(0xFF << 24));
//d->sel_rect_sh->parent = it->parent_rect;
d->sel_rect = fb_add_rect(it->touchX, it->touchY, 1, 1, WHITE & ~(0xFF << 24));
//d->sel_rect->parent = it->parent_rect;
call_anim *canim = call_anim_create(it, rom_item_alpha, 300, INTERPOLATOR_DECELERATE);
call_anim *canim = call_anim_create(it, rom_item_alpha, 300, INTERPOLATOR_ACCEL_DECEL);
call_anim_add(canim);
item_anim *anim = item_anim_create(d->sel_rect, 150, INTERPOLATOR_DECELERATE);
item_anim *anim = item_anim_create(d->sel_rect, 300, INTERPOLATOR_ACCEL_DECEL);
anim->start_offset = 0;
anim->targetX = d->sel_rect->x-7;
anim->targetY = d->sel_rect->y-7;
anim->targetX = x;
anim->targetY = y;
anim->targetW = w;
anim->targetH = item_h;
anim->on_step_data = d;
anim->on_step_call = rom_item_sel_step;
item_anim_add(anim);
d->click_text = fb_add_text_lvl(11, 0, fb_height, BLACK, SIZE_EXTRA, "Tap again to boot this system");
center_text(d->click_text, 0, -1, fb_width, -1);
d->click_text->y += d->click_text->h;
d->click_text_rect = fb_add_rect_lvl(10, 0, fb_height, fb_width-80, d->click_text->h+200, WHITE);
d->click_text_rect->x = fb_width/2 - d->click_text_rect->w/2;
anim = item_anim_create(d->click_text, 400, INTERPOLATOR_DECELERATE);
anim->targetY = fb_height - d->click_text->h*1.5 - 40;
item_anim_add(anim);
anim = item_anim_create(d->click_text_rect, 400, INTERPOLATOR_DECELERATE);
anim->targetY = fb_height - d->click_text->h*2.5 - 40;
item_anim_add(anim);
d->hover_removed = 0;
d->deselect_anim_started = 0;
}
else
{
/*d->sel_rect_sh->y = y+5;
d->sel_rect->y = y;*/
d->sel_rect_sh->y += y - d->last_y;
d->sel_rect->y += y - d->last_y;
}
//d->click_text->y = d->text_it->y + d->text_it->h + 15;
}
else if(d->sel_rect && !d->hover_removed)
else if(d->sel_rect)
{
d->hover_removed = 1;
if(!d->deselect_anim_started)
{
d->deselect_anim_started = 1;
item_anim *anim = item_anim_create(d->sel_rect, 150, INTERPOLATOR_ACCELERATE);
anim->targetX = it->touchX;
anim->targetY = it->touchY;
anim->targetW = 0;
anim->targetH = 0;
anim->on_step_data = d;
anim->on_step_call = rom_item_sel_step;
item_anim_add_after(anim);
call_anim *canim = call_anim_create(it, rom_item_alpha, 200, INTERPOLATOR_ACCELERATE);
canim->on_finished_data = it;
canim->on_finished_call = rom_item_shrink_finished;
call_anim_add(canim);
item_anim *anim = item_anim_create(d->sel_rect, 200, INTERPOLATOR_ACCELERATE);
anim->targetX = d->sel_rect->x+7;
anim->targetY = d->sel_rect->y+7;
item_anim_add(anim);
anim = item_anim_create(d->click_text, 200, INTERPOLATOR_DECELERATE);
anim->targetY = fb_height;
item_anim_add(anim);
call_anim *canim = call_anim_create(it, rom_item_alpha, 150, INTERPOLATOR_ACCELERATE);
canim->start_offset = anim->start_offset;
canim->on_finished_data = it;
canim->on_finished_call = rom_item_deselect_finished;
call_anim_add(canim);
}
else
{
d->sel_rect_sh->y += y - d->last_y;
d->sel_rect->y += y - d->last_y;
}
}
d->last_y = y;
}
void rom_item_hide(void *data)
@@ -712,14 +642,12 @@ void rom_item_hide(void *data)
fb_rm_text(d->text_it);
fb_rm_text(d->part_it);
fb_rm_rect(d->hover_rect);
fb_rm_rect(d->sel_rect);
fb_rm_rect(d->sel_rect_sh);
fb_rm_img(d->icon);
d->text_it = NULL;
d->part_it = NULL;
d->hover_rect = NULL;
d->sel_rect = NULL;
d->sel_rect_sh = NULL;
d->icon = NULL;

View File

@@ -33,7 +33,7 @@ typedef struct
int id;
void *data;
int flags;
fb_item_header *parent_rect;
fb_item_pos *parent_rect;
int touchX, touchY;
} listview_item;
@@ -65,7 +65,6 @@ typedef struct
void (*item_confirmed)(listview_item *); // item - confirmed by keyaction
fb_item_header **ui_items;
fb_rect *bg_rect;
fb_rect *scroll_mark;
fb_rect *overscroll_marks[2];
fb_rect **keyact_frame;

View File

@@ -127,6 +127,7 @@ int multirom_ui(struct multirom_status *s, struct multirom_rom **to_boot)
multirom_ui_init_header();
multirom_ui_switch(TAB_INTERNAL);
fb_set_background(0xFFDCDCDC);
add_touch_handler(&multirom_ui_touch_handler, NULL);
start_input_thread();
@@ -536,6 +537,9 @@ void multirom_ui_tab_rom_destroy(void *data)
void multirom_ui_tab_rom_selected(listview_item *prev, listview_item *now)
{
if(!now)
return;
struct multirom_rom *rom = multirom_get_rom_by_id(mrom_status, now->id);
if(!rom || !themes_info->data->tab_data)
return;

View File

@@ -139,7 +139,7 @@ static void tab_rom_init(multirom_theme_data *t, tab_data_roms *d, int tab_type)
{
d->list->x = ROMS_HEADER_H;
d->list->y = HEADER_HEIGHT+ROMS_HEADER_H;
d->list->w = fb_width - ROMS_HEADER_H*2;
d->list->w = fb_width - ROMS_HEADER_H;
d->list->h = fb_height - d->list->y - ROMS_HEADER_H;
}

View File

@@ -44,7 +44,7 @@ static struct worker_thread worker_thread = {
.run = 0,
};
#define SLEEP_CONST 16
#define SLEEP_CONST 10
static void *worker_thread_work(void *data)
{
struct worker_thread *t = (struct worker_thread*)data;