empc/src/bin/bgselector.c

352 lines
10 KiB
C

#include "empc_private.h"
typedef struct Bgselector
{
Evas_Object *layout;
Eina_Stringshare *artist;
Eina_Stringshare *album;
Eina_List *current;
Eina_List *prev_current;
Eina_List *images;
unsigned int current_num;
Eina_Bool state : 1;
Eina_Bool animating : 1;
Eina_Bool active : 1;
} Bgselector;
static const char *part_name[] =
{
"empc.swallow.0",
"empc.swallow.1",
};
static inline Eina_Bool
_bg_next_get(unsigned char num)
{
return (num + 1) % 2;
}
static void
_bgs_img_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
{
Bgselector *bgs = data;
if (eina_list_data_get(bgs->current) == obj)
{
bgselector_next(bgs->layout);
if (eina_list_data_get(bgs->current) != obj)
bgs->current_num--;
else
{
bgselector_prev(bgs->layout);
if (eina_list_data_get(bgs->current) == obj)
{
bgselector_clear(bgs->layout);
return;
}
}
}
eina_stringshare_del(evas_object_data_del(obj, "__empc_url"));
bgs->images = eina_list_remove(bgs->images, obj);
}
static void
_bgs_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Bgselector *bgs = data;
Evas_Object *img;
EINA_LIST_FREE(bgs->images, img)
{
evas_object_event_callback_del(img, EVAS_CALLBACK_DEL, _bgs_img_del);
eina_stringshare_del(evas_object_data_del(img, "__empc_url"));
evas_object_del(img);
}
eina_stringshare_del(bgs->artist);
eina_stringshare_del(bgs->album);
free(bgs);
}
static void
_bgs_text_update(Bgselector *bgs)
{
char buf[64];
int w, h;
snprintf(buf, sizeof(buf), "%d/%d", bgs->current_num + 1, eina_list_count(bgs->images));
elm_object_part_text_set(bgs->layout, "empc.text.count", buf);
elm_image_object_size_get(eina_list_data_get(bgs->current), &w, &h);
snprintf(buf, sizeof(buf), "%dx%d", w, h);
elm_object_part_text_set(bgs->layout, "empc.text.resolution", buf);
}
static void
_bgs_switch(void *data, Evas_Object *obj EINA_UNUSED, const char *sig, const char *src EINA_UNUSED)
{
Bgselector *bgs = data;
const char *num = sig + sizeof("empc,state,visible,") - 1;
bgs->state = atoi(num);
bgs->animating = 0;
_bgs_text_update(bgs);
}
static void
avail_emit(Bgselector *bgs)
{
elm_object_signal_emit(bgs->layout, "empc,next,unavail", "empc");
elm_object_signal_emit(bgs->layout, "empc,prev,unavail", "empc");
if (eina_list_next(bgs->current))
elm_object_signal_emit(bgs->layout, "empc,next,avail", "empc");
if (eina_list_prev(bgs->current))
elm_object_signal_emit(bgs->layout, "empc,prev,avail", "empc");
}
static void
_bgs_theme_change(void *data, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
{
Bgselector *bgs = data;
int w, h;
if (!bgs->current) return;
_bgs_text_update(bgs);
avail_emit(bgs);
bgs->state = 0;
if (bgs->active)
elm_object_signal_emit(obj, "empc,state,active", "empc");
elm_object_part_content_set(bgs->layout, "empc.swallow.0", eina_list_data_get(bgs->current));
elm_image_object_size_get(eina_list_data_get(bgs->current), &w, &h);
evas_object_size_hint_max_set(eina_list_data_get(bgs->current), w, h);
}
Evas_Object *
bgselector_add(Evas_Object *parent)
{
Evas_Object *o;
Bgselector *bgs;
bgs = calloc(1, sizeof(Bgselector));
bgs->layout = o = elm_layout_add(parent);
evas_object_data_set(o, "__bgselector", bgs);
elm_layout_theme_set(o, "layout", "empc", "bgselector");
elm_object_signal_callback_add(o, "edje,change,file", "edje", _bgs_theme_change, bgs);
elm_object_signal_callback_add(o, "empc,state,visible,*", "empc", _bgs_switch, bgs);
evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _bgs_del, bgs);
elm_object_part_text_set(o, "empc.text.count", "0");
return o;
}
void
bgselector_image_max_recalc(Evas_Object *img)
{
int w, h;
elm_image_object_size_get(img, &w, &h);
evas_object_size_hint_max_set(img, w * 1.5, h * 1.5);
}
void
bgselector_image_add(Evas_Object *obj, Evas_Object *img)
{
Bgselector *bgs;
char buf[64];
int w, h;
EINA_SAFETY_ON_NULL_RETURN(img);
bgs = evas_object_data_get(obj, "__bgselector");
EINA_SAFETY_ON_NULL_RETURN(bgs);
//unsigned int c = eina_list_count(bgs->images) + 1;
//evas_object_data_set(img, "__bgselector_num", (uintptr_t*)c);
evas_object_event_callback_add(img, EVAS_CALLBACK_DEL, _bgs_img_del, bgs);
bgs->images = eina_list_append(bgs->images, img);
snprintf(buf, sizeof(buf), "%d/%d", bgs->current_num + 1, eina_list_count(bgs->images));
elm_object_part_text_set(obj, "empc.text.count", buf);
elm_image_object_size_get(img, &w, &h);
evas_object_size_hint_max_set(img, w * 1.5, h * 1.5);
if (bgs->current)
{
elm_object_signal_emit(obj, "empc,next,avail", "empc");
evas_object_hide(img);
return;
}
bgs->current = bgs->images;
elm_object_part_content_set(bgs->layout, "empc.swallow.0", img);
evas_object_show(img);
snprintf(buf, sizeof(buf), "%dx%d", w, h);
elm_object_part_text_set(obj, "empc.text.resolution", buf);
}
void
bgselector_next(Evas_Object *obj)
{
Bgselector *bgs;
Evas_Object *it;
bgs = evas_object_data_get(obj, "__bgselector");
EINA_SAFETY_ON_NULL_RETURN(bgs);
if (bgs->animating) return;
if (!bgs->images) return;
it = eina_list_data_get(bgs->current->prev);
if (it) evas_object_hide(it);
it = eina_list_data_get(bgs->current->next);
if (!it) return;
bgs->current = bgs->current->next;
bgs->current_num++;
evas_object_show(it);
//INF("IMG NEXT: %u", (unsigned int)evas_object_data_get(it, "__bgselector_num"));
elm_object_part_content_unset(bgs->layout, part_name[_bg_next_get(bgs->state)]);
elm_object_part_content_set(bgs->layout, part_name[_bg_next_get(bgs->state)], it);
elm_object_signal_emit(bgs->layout, "empc,bg,next", "empc");
bgs->animating = 1;
avail_emit(bgs);
}
void
bgselector_prev(Evas_Object *obj)
{
Bgselector *bgs;
Evas_Object *it;
bgs = evas_object_data_get(obj, "__bgselector");
EINA_SAFETY_ON_NULL_RETURN(bgs);
if (bgs->animating) return;
if (!bgs->images) return;
it = eina_list_data_get(bgs->current->next);
if (it) evas_object_hide(it);
it = eina_list_data_get(bgs->current->prev);
if (!it) return;
bgs->current = bgs->current->prev;
bgs->current_num--;
evas_object_show(it);
//INF("IMG PREV: %u", (unsigned int)evas_object_data_get(it, "__bgselector_num"));
elm_object_part_content_unset(bgs->layout, part_name[_bg_next_get(bgs->state)]);
elm_object_part_content_set(bgs->layout, part_name[_bg_next_get(bgs->state)], it);
elm_object_signal_emit(bgs->layout, "empc,bg,prev", "empc");
bgs->animating = 1;
avail_emit(bgs);
}
Evas_Object *
bgselector_get(Evas_Object *obj)
{
Bgselector *bgs;
bgs = evas_object_data_get(obj, "__bgselector");
EINA_SAFETY_ON_NULL_RETURN_VAL(bgs, NULL);
return eina_list_data_get(bgs->current);
}
void
bgselector_clear(Evas_Object *obj)
{
Bgselector *bgs;
Evas_Object *img;
bgs = evas_object_data_get(obj, "__bgselector");
EINA_LIST_FREE(bgs->images, img)
{
evas_object_event_callback_del(img, EVAS_CALLBACK_DEL, _bgs_img_del);
evas_object_del(img);
}
if (bgs->state)
elm_object_signal_emit(bgs->layout, "empc,bg,prev", "empc");
bgs->state = 0;
bgs->current = NULL;
bgs->current_num = 0;
eina_stringshare_replace(&bgs->artist, NULL);
eina_stringshare_replace(&bgs->album, NULL);
elm_object_signal_emit(obj, "empc,prev,unavail", "empc");
elm_object_signal_emit(obj, "empc,next,unavail", "empc");
}
void
bgselector_prune(Evas_Object *obj)
{
Bgselector *bgs;
Evas_Object *img, *ic;
bgs = evas_object_data_get(obj, "__bgselector");
EINA_SAFETY_ON_NULL_RETURN(bgs);
img = eina_list_data_get(bgs->current);
bgs->images = eina_list_remove_list(bgs->images, bgs->current);
EINA_LIST_FREE(bgs->images, ic)
{
evas_object_event_callback_del(ic, EVAS_CALLBACK_DEL, _bgs_img_del);
evas_object_del(ic);
}
bgs->current = bgs->images = eina_list_append(bgs->images, img);
bgs->current_num = 0;
elm_object_signal_emit(obj, "empc,prev,unavail", "empc");
elm_object_signal_emit(obj, "empc,next,unavail", "empc");
}
void
bgselector_cancel(Evas_Object *obj)
{
Bgselector *bgs;
Evas_Object *it;
bgs = evas_object_data_get(obj, "__bgselector");
EINA_SAFETY_ON_NULL_RETURN(bgs);
bgs->current = bgs->prev_current;
it = eina_list_data_get(bgs->current);
evas_object_show(it);
elm_object_part_content_unset(bgs->layout, part_name[_bg_next_get(bgs->state)]);
elm_object_part_content_set(bgs->layout, part_name[_bg_next_get(bgs->state)], it);
elm_object_signal_emit(bgs->layout, "empc,bg,prev", "empc");
bgs->animating = 1;
avail_emit(bgs);
}
void
bgselector_active_set(Evas_Object *obj, Eina_Bool active)
{
Bgselector *bgs;
bgs = evas_object_data_get(obj, "__bgselector");
EINA_SAFETY_ON_NULL_RETURN(bgs);
bgs->active = !!active;
if (active)
{
elm_object_signal_emit(obj, "empc,state,active", "empc");
bgs->prev_current = bgs->current;
}
else
{
elm_object_signal_emit(obj, "empc,state,inactive", "empc");
bgs->prev_current = NULL;
}
}
void
bgselector_info_set(Evas_Object *obj, Eina_Stringshare *artist, Eina_Stringshare *album)
{
Bgselector *bgs;
bgs = evas_object_data_get(obj, "__bgselector");
EINA_SAFETY_ON_NULL_RETURN(bgs);
eina_stringshare_refplace(&bgs->artist, artist);
eina_stringshare_refplace(&bgs->album, album);
}
Eina_Stringshare *
bgselector_artist_get(Evas_Object *obj)
{
Bgselector *bgs;
bgs = evas_object_data_get(obj, "__bgselector");
EINA_SAFETY_ON_NULL_RETURN_VAL(bgs, NULL);
return bgs->artist;
}
Eina_Stringshare *
bgselector_album_get(Evas_Object *obj)
{
Bgselector *bgs;
bgs = evas_object_data_get(obj, "__bgselector");
EINA_SAFETY_ON_NULL_RETURN_VAL(bgs, NULL);
return bgs->album;
}