From b8e9081c4aa6bb9b16cbad297ca71630167bcf19 Mon Sep 17 00:00:00 2001 From: Boris Faure Date: Tue, 9 Aug 2011 09:20:02 +0000 Subject: [PATCH] add eenvader.fractal: an animated wallpaper SVN revision: 62245 --- .gitignore | 35 ++++ AUTHORS | 1 + COPYING | 32 ++++ ChangeLog | 0 Makefile.am | 6 + NEWS | 0 autogen.sh | 17 ++ configure.ac | 65 ++++++++ data/Makefile.am | 18 ++ data/eenvaders.edc | 48 ++++++ gen_invaders.py | 52 ++++++ src/Makefile.am | 28 ++++ src/eenvaders.c | 106 ++++++++++++ src/eenvaders_edje_external.c | 192 +++++++++++++++++++++ src/eenvaders_evas_smart.c | 304 ++++++++++++++++++++++++++++++++++ src/eenvaders_evas_smart.h | 8 + 16 files changed, 912 insertions(+) create mode 100644 .gitignore create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 Makefile.am create mode 100644 NEWS create mode 100755 autogen.sh create mode 100644 configure.ac create mode 100644 data/Makefile.am create mode 100644 data/eenvaders.edc create mode 100755 gen_invaders.py create mode 100644 src/Makefile.am create mode 100644 src/eenvaders.c create mode 100644 src/eenvaders_edje_external.c create mode 100644 src/eenvaders_evas_smart.c create mode 100644 src/eenvaders_evas_smart.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6dc762d --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +/INSTALL +/Makefile +/Makefile.in +/aclocal.m4 +/autom4te.cache/ +/config.guess +/config.h +/config.h.in +/config.log +/config.status +/config.sub +/configure +/depcomp +/install-sh +/libtool +/ltmain.sh +/m4/libtool.m4 +/m4/ltoptions.m4 +/m4/ltsugar.m4 +/m4/ltversion.m4 +/m4/lt~obsolete.m4 +/missing +/src/.deps/ +/src/.libs/ +/src/Makefile +/src/Makefile.in +/src/eenvaders +/src/*.lo +/src/*.o +/src/module.la +/stamp-h1 +/compile +/data/Makefile +/data/Makefile.in +/data/eenvaders.edj diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..1bba8ec --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Boris Faure diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..9690c3f --- /dev/null +++ b/COPYING @@ -0,0 +1,32 @@ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies of the Software and its Copyright notices. In addition publicly +documented acknowledgment must be given that this software has been used if no +source code of this software is made available publicly. Making the source +available publicly means including the source for this software with the +distribution, or a method to get this software via some reasonable mechanism +(electronic transfer via a network or media) as well as making an offer to +supply the source on request. This Copyright notice serves as an offer to +supply the source on on request as well. Instead of this, supplying +acknowledgments of use of this software in either Copyright notices, Manuals, +Publicity and Marketing documents or any documentation provided with any +product containing this software. This License does not apply to any software +that links to the libraries provided by this software (statically or +dynamically), but only to the software provided. + +Please see the COPYING-PLAIN for a plain-english explanation of this notice +and its intent. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..215bf9f --- /dev/null +++ b/Makefile.am @@ -0,0 +1,6 @@ +AUTOMAKE_OPTIONS = 1.4 foreign +MAINTAINERCLEANFILES = Makefile.in + +SUBDIRS = src data + +ACLOCAL_AMFLAGS = -I m4 diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..ae01364 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +rm -rf autom4te.cache +rm -f aclocal.m4 ltmain.sh + +touch README + +echo "Running autopoint..." ; autopoint -f || : +echo "Running aclocal..." ; aclocal -I m4 $ACLOCAL_FLAGS || exit 1 +echo "Running autoheader..." ; autoheader || exit 1 +echo "Running autoconf..." ; autoconf || exit 1 +echo "Running libtoolize..." ; (libtoolize --copy --automake || glibtoolize --automake) || exit 1 +echo "Running automake..." ; automake --add-missing --copy --gnu || exit 1 + +if [ -z "$NOCONFIGURE" ]; then + ./configure "$@" +fi diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..87d62fa --- /dev/null +++ b/configure.ac @@ -0,0 +1,65 @@ +dnl Process this file with autoconf to produce a configure script. + +# get rid of that stupid cache mechanism +rm -f config.cache + +AC_INIT(eenvaders, 0.1, billiob@efl.so) +AC_PREREQ(2.52) +AC_CONFIG_SRCDIR(configure.ac) +AC_CANONICAL_BUILD +AC_CANONICAL_HOST +AC_ISC_POSIX + +AM_INIT_AUTOMAKE(1.6) +AM_CONFIG_HEADER(config.h) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +AC_PROG_CC_C99 +AC_HEADER_STDC +AC_C_CONST +AM_PROG_CC_C_O + +define([AC_LIBTOOL_LANG_CXX_CONFIG], [:])dnl +define([AC_LIBTOOL_LANG_F77_CONFIG], [:])dnl +AC_PROG_LIBTOOL + +PKG_CHECK_MODULES(ECORE_EVAS, [ecore-evas]) +PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment]) +datadir_edj=$(pkg-config --variable=prefix enlightenment)/share/enlightenment/data/backgrounds + +PKG_CHECK_MODULES(EDJE, [edje >= 0.5.0]) +vmaj=$(pkg-config --variable=vmaj edje) +MODULE_ARCH="$host_os-$host_cpu-$vmaj.0.0" +AC_SUBST(MODULE_ARCH) +AC_DEFINE_UNQUOTED(MODULE_ARCH, "$MODULE_ARCH", "Module architecture") + +# Find edje_cc +AC_ARG_WITH(edje-cc, + AC_HELP_STRING([--with-edje-cc=PATH], [specify a specific path to edje_cc]), + [ + v=$withval; + EDJE_CC=$v + ],[ + EDJE_CC=$(pkg-config --variable=prefix edje)/bin/edje_cc + ] +) +AC_SUBST(EDJE_CC) +AC_MSG_CHECKING([Which edje_cc to use]) +AC_MSG_RESULT(${EDJE_CC}) + +datadir=$(pkg-config --variable=modules edje)/${PACKAGE} +AC_ARG_ENABLE(homedir-install, + AS_HELP_STRING([--enable-homedir-install], [Install module in homedir]), + [ + datadir="${HOME}/.edje/modules/${PACKAGE}"; + datadir_edj="${HOME}/.e/e/backgrounds" + ] +) +AC_SUBST(datadir_edj) + +AC_OUTPUT([ +Makefile +data/Makefile +src/Makefile +], [ +]) diff --git a/data/Makefile.am b/data/Makefile.am new file mode 100644 index 0000000..ab7c7b4 --- /dev/null +++ b/data/Makefile.am @@ -0,0 +1,18 @@ +AUTOMAKE_OPTIONS = 1.4 foreign +MAINTAINERCLEANFILES = Makefile.in + +EDJE_FLAGS = -v + +filesdir = @datadir_edj@ +files_DATA = eenvaders.edj + +EXTRA_DIST = eenvaders.edc + +eenvaders.edj: eenvaders.edc + $(EDJE_CC) $(EDJE_FLAGS) $< $@ + +clean-local: + rm -rf eenvaders.edj *~ + +uninstall: + rm -rf $(DESTDIR)@datadir_edj@/eenvaders.edj diff --git a/data/eenvaders.edc b/data/eenvaders.edc new file mode 100644 index 0000000..abc9c05 --- /dev/null +++ b/data/eenvaders.edc @@ -0,0 +1,48 @@ +externals { + external: "eenvaders"; +} + +collections { + group { + name: "e/desktop/background"; + + script { + public clock_cb(unused) { + emit("eenvaders:refresh", "☃"); + timer(30, "clock_cb", 1); + } + } + + parts { + part { + name: "bg"; + type: RECT; + description { + state: "default" 0.0; + color: 0 43 54 255; + } + } + part { + name: "eenvaders"; + type: EXTERNAL; + source: "eenvaders"; + + description { + state: "default" 0.0; + } + } + } + + // Get everything started at load + programs { + program { + name: "init"; + signal: "load"; + source: ""; + script { + clock_cb(0); + } + } + } + } +} diff --git a/gen_invaders.py b/gen_invaders.py new file mode 100755 index 0000000..25528cc --- /dev/null +++ b/gen_invaders.py @@ -0,0 +1,52 @@ +#!/usr/bin/python + +from PIL import Image + +WIDTH = 7 +HEIGHT = 7 + + +for i in range(1<<15): + img = Image.new("RGB", (WIDTH, HEIGHT), (255, 255, 255)) + pix = img.load() + if (i & (1 << 0)): + pix[1, 1] = (0, 0, 0) + pix[5, 1] = (0, 0, 0) + if (i & (1 << 1)): + pix[2, 1] = (0, 0, 0) + pix[4, 1] = (0, 0, 0) + if (i & (1 << 2)): + pix[3, 1] = (0, 0, 0) + if (i & (1 << 3)): + pix[1, 2] = (0, 0, 0) + pix[5, 2] = (0, 0, 0) + if (i & (1 << 4)): + pix[2, 2] = (0, 0, 0) + pix[4, 2] = (0, 0, 0) + if (i & (1 << 5)): + pix[3, 2] = (0, 0, 0) + if (i & (1 << 6)): + pix[1, 3] = (0, 0, 0) + pix[5, 3] = (0, 0, 0) + if (i & (1 << 7)): + pix[2, 3] = (0, 0, 0) + pix[4, 3] = (0, 0, 0) + if (i & (1 << 8)): + pix[3, 3] = (0, 0, 0) + if (i & (1 << 9)): + pix[1, 4] = (0, 0, 0) + pix[5, 4] = (0, 0, 0) + if (i & (1 << 10)): + pix[2, 4] = (0, 0, 0) + pix[4, 4] = (0, 0, 0) + if (i & (1 << 11)): + pix[3, 4] = (0, 0, 0) + if (i & (1 << 12)): + pix[1, 5] = (0, 0, 0) + pix[5, 5] = (0, 0, 0) + if (i & (1 << 13)): + pix[2, 5] = (0, 0, 0) + pix[4, 5] = (0, 0, 0) + if (i & (1 << 14)): + pix[3, 5] = (0, 0, 0) + img.save("img/{0}.png".format(i)) diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..5cd6e29 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,28 @@ +MAINTAINERCLEANFILES = Makefile.in +INCLUDES = -I. \ + -I$(top_srcdir) \ + -I$(includedir) \ + @EDJE_CFLAGS@ + + +pkgdir = $(datadir)/$(MODULE_ARCH) +pkg_LTLIBRARIES = module.la +module_la_SOURCES = \ + eenvaders_evas_smart.c \ + eenvaders_edje_external.c + +module_la_LIBADD = @EDJE_LIBS@ +module_la_LDFLAGS = -module -avoid-version +module_la_DEPENDENCIES = $(top_builddir)/config.h + +bin_PROGRAMS = eenvaders + +eenvaders_SOURCES = \ + eenvaders_evas_smart.c \ + eenvaders.c +eenvaders_CPPFLAGS = \ + @ECORE_EVAS_CFLAGS@ +eenvaders_LDADD = @ECORE_EVAS_LIBS@ + +clean-local: + rm -rf *~ diff --git a/src/eenvaders.c b/src/eenvaders.c new file mode 100644 index 0000000..c14fa9d --- /dev/null +++ b/src/eenvaders.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eenvaders_evas_smart.h" + +#define BG 0xff002b36 +#define FG 0xff839496 + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +static struct { + Ecore_Evas *ee; + Evas *evas; + Evas_Coord w, h; + Evas_Object *bg; + Evas_Object *eenvaders; +} eenvaders_g; +#define _G eenvaders_g + +static void +resize_cb(Ecore_Evas *ee) +{ + int w, h; + + ecore_evas_geometry_get(ee, NULL, NULL, &w, &h); + evas_object_resize(_G.bg, w, h); + evas_object_resize(_G.eenvaders, w, h); +} + +static Eina_Bool +timer_cb(void *data) +{ + Evas_Object *o = (Evas_Object *)data; + + evas_object_smart_callback_call(o, "refresh", NULL); + + return EINA_TRUE; +} + +int +main(void) +{ + unsigned int seedval; + int fd; + + if (!ecore_evas_init()) + return -1; + + _G.w = 600; + _G.h = 350; + + + /*open file */ + if ((fd = open("/dev/urandom", O_RDONLY)) < 0) { + perror(NULL); + exit(1); + } + if (read(fd, &seedval, sizeof(seedval)) != sizeof(seedval)) { + perror(NULL); + close(fd); + exit(1); + } + close(fd); + srand(seedval); + + _G.ee = ecore_evas_software_x11_new( + NULL, /* const char * disp_name */ + 0, /* Ecore_X_Window parent */ + 0, 0, _G.w, _G.h); + + ecore_evas_title_set(_G.ee, "EEnavders.fractal"); + ecore_evas_borderless_set(_G.ee, 0); + ecore_evas_show(_G.ee); + _G.evas = ecore_evas_get(_G.ee); + + _G.bg = evas_object_rectangle_add(_G.evas); + evas_object_color_set(_G.bg, + (BG >> 16) & 0xff, + (BG >> 8) & 0xff, + BG & 0xff, + BG >> 24); + evas_object_move(_G.bg, 0, 0); + evas_object_resize(_G.bg, _G.w, _G.h); + evas_object_show(_G.bg); + + _G.eenvaders = eenvaders_smart_new(_G.evas); + evas_object_resize(_G.eenvaders, _G.w, _G.h); + evas_object_show(_G.eenvaders); + + ecore_timer_add(3, timer_cb, _G.eenvaders); + + ecore_evas_callback_resize_set(_G.ee, &resize_cb); + + ecore_main_loop_begin(); + + ecore_evas_shutdown(); + ecore_shutdown(); + + return 0; +} diff --git a/src/eenvaders_edje_external.c b/src/eenvaders_edje_external.c new file mode 100644 index 0000000..4108194 --- /dev/null +++ b/src/eenvaders_edje_external.c @@ -0,0 +1,192 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eenvaders_evas_smart.h" + +/* Prototypes -{{{-*/ + +static Evas_Object * +eenvaders_ext_add(void *data, Evas *evas, Evas_Object *parent, + const Eina_List *params, const char *part_name); +static void +eenvaders_ext_state_set(void *data, Evas_Object *obj, + const void *from_params, + const void *to_params, float pos); +static void +eenvaders_ext_signal_emit(void *data, Evas_Object *obj, + const char *emission, const char *source); +static Eina_Bool +eenvaders_ext_param_set(void *data, Evas_Object *obj, + const Edje_External_Param *param); +static Eina_Bool +eenvaders_ext_param_get(void *data, const Evas_Object *obj, + Edje_External_Param *param); +static Evas_Object * +eenvaders_ext_content_get(void *data, const Evas_Object *obj, + const char *content); +static void* +eenvaders_ext_params_parse(void *data, Evas_Object *obj, + const Eina_List *params); +static void +eenvaders_ext_params_free(void *params); +static const char* +eenvaders_ext_label_get(void *data); +static const char* +eenvaders_ext_description_get(void *data); +static Evas_Object * +eenvaders_ext_icon_add(void *data, Evas *e); +static Evas_Object * +eenvaders_ext_preview_add(void *data, Evas *e); +static const char* +eenvaders_ext_translate(void *data, const char *orig); + +/* }}} */ +/* Globals -{{{-*/ + +static struct { + Edje_External_Type ext_type; +} eenvaders_g = { + .ext_type = { + .abi_version = EDJE_EXTERNAL_TYPE_ABI_VERSION, + .module = "eenvaders", + .module_name = "eenvaders", + .add = eenvaders_ext_add, + .state_set = eenvaders_ext_state_set, + .signal_emit = eenvaders_ext_signal_emit, + .param_set = eenvaders_ext_param_set, + .param_get = eenvaders_ext_param_get, + .content_get = eenvaders_ext_content_get, + .params_parse = eenvaders_ext_params_parse, + .params_free = eenvaders_ext_params_free, + .label_get = eenvaders_ext_label_get, + .description_get = eenvaders_ext_description_get, + .icon_add = eenvaders_ext_icon_add, + .preview_add = eenvaders_ext_preview_add, + .translate = eenvaders_ext_translate, + }, +}; +#define _G eenvaders_g + +/* }}} */ +/* Edje External -{{{-*/ + +static Evas_Object * +eenvaders_ext_add(void *data, Evas *evas, Evas_Object *parent, + const Eina_List *params, const char *part_name) +{ + return eenvaders_smart_new(evas); +} + +static void +eenvaders_ext_state_set(void *data, Evas_Object *obj, + const void *from_params, + const void *to_params, float pos) +{ +} + +static void +eenvaders_ext_signal_emit(void *data, Evas_Object *obj, + const char *emission, const char *source) +{ + evas_object_smart_callback_call(obj, emission, NULL); +} + +static Eina_Bool +eenvaders_ext_param_set(void *data, Evas_Object *obj, + const Edje_External_Param *param) +{ + return EINA_TRUE; +} + +static Eina_Bool +eenvaders_ext_param_get(void *data, const Evas_Object *obj, + Edje_External_Param *param) +{ + return EINA_TRUE; +} + +static Evas_Object * +eenvaders_ext_content_get(void *data, const Evas_Object *obj, + const char *content) +{ + return NULL; +} + +static void* +eenvaders_ext_params_parse(void *data, Evas_Object *obj, + const Eina_List *params) +{ + return NULL; +} + +static void +eenvaders_ext_params_free(void *params) +{ +} + +static const char* +eenvaders_ext_label_get(void *data) +{ + return NULL; +} + +static const char* +eenvaders_ext_description_get(void *data) +{ + return NULL; +} + +static Evas_Object * +eenvaders_ext_icon_add(void *data, Evas *e) +{ + return NULL; +} + +static Evas_Object * +eenvaders_ext_preview_add(void *data, Evas *e) +{ + return NULL; +} + +static const char* +eenvaders_ext_translate(void *data, const char *orig) +{ + return NULL; +} +/* }}} */ +/* Init/Shutdown -{{{-*/ + +Eina_Bool +eenvaders_init(void) +{ + unsigned int seedval = time(NULL); + int fd; + + if ((fd = open("/dev/random", O_RDONLY)) >= 0) { + read(fd, &seedval, sizeof(seedval)); + close(fd); + } + srand(seedval); + + edje_external_type_register("eenvaders", &_G.ext_type); + + return EINA_TRUE; +} + +void +eenvaders_shutdown(void) +{ + edje_external_type_unregister("eenvaders"); +} + +EINA_MODULE_INIT(eenvaders_init); +EINA_MODULE_SHUTDOWN(eenvaders_shutdown); + +/* }}} */ diff --git a/src/eenvaders_evas_smart.c b/src/eenvaders_evas_smart.c new file mode 100644 index 0000000..935d4ae --- /dev/null +++ b/src/eenvaders_evas_smart.c @@ -0,0 +1,304 @@ +#include + +#include "eenvaders_evas_smart.h" + +#define BG 0xff002b36 +#define FG 0xff839496 + +#define MIN(a,b) (((a)<(b))?(a):(b)) + +/* Prototypes -{{{-*/ +static Evas_Smart *_eenvaders_object_smart_get(void); +static Evas_Object *eenvaders_object_new(Evas *evas); +static void _eenvaders_object_del(Evas_Object *o); +static void _eenvaders_object_move(Evas_Object *o, Evas_Coord x, Evas_Coord y); +static void _eenvaders_object_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h); +static void _eenvaders_object_show(Evas_Object *o); +static void _eenvaders_object_hide(Evas_Object *o); +static void _eenvaders_object_color_set(Evas_Object *o, int r, int g, int b, int a); +static void _eenvaders_object_clip_set(Evas_Object *o, Evas_Object *clip); +static void _eenvaders_object_clip_unset(Evas_Object *o); + +static void +draw_eenvaders(Evas_Object *smart_obj, + int x, int y, int w, int h); +/* }}} */ +/* Globals -{{{-*/ + +static struct { + Evas_Smart_Class klass; +} eenvaders_evas_smart_g = { + .klass = { + .name = "eenvaders_object", + .version = EVAS_SMART_CLASS_VERSION, + .add = NULL, + .del = _eenvaders_object_del, + .move = _eenvaders_object_move, + .resize = _eenvaders_object_resize, + .show = NULL, + .hide = NULL, + .color_set = NULL, + .clip_set = NULL, + .clip_unset = NULL, + .calculate = NULL, + .member_add = NULL, + .member_del = NULL, + .parent = NULL, + .callbacks = NULL, + .interfaces = NULL, + .data = NULL, + }, +#define _G eenvaders_evas_smart_g +}; + +/* }}} */ +/* Eenvaders functions -{{{-*/ + +static void +eenvaders_mouse_down(void *data, + Evas *evas, + Evas_Object *child, + void *event_info) +{ + Evas_Coord x, y, w, h; + Evas_Event_Mouse_Up *evt = event_info; + Evas_Object *parent = data; + void *mem; + + x = evt->canvas.x; + y = evt->canvas.y; + + mem = evas_object_data_del(child, "m"); + if (!mem) + return; + + free(mem); + evas_object_geometry_get(child, &x, &y, &w, &h); + evas_object_smart_member_del(child); + evas_object_del(child); + draw_eenvaders(parent, x+3, y+3, w-3, h-3); +} + +static Evas_Object* +new_eenvader(Evas *evas, Evas_Object *smart_obj) +{ + Evas_Object *o = NULL; + uint16_t u = rand(); + int *mem = calloc(7 * 7, sizeof(int)); + + if (!mem) { + perror(NULL); + exit(1); + } + + for (int i = 0; i < 15; i++) { + if (u & (1 << i)) { + mem[7 + 7*(i/3) + 1 + i%3] = FG; + mem[7 + 7*(i/3) + 5 - i%3] = FG; + } + } + + o = evas_object_image_filled_add(evas); + evas_object_image_alpha_set(o, EINA_TRUE); + evas_object_image_fill_set(o, 0, 0, 7, 7); + evas_object_image_smooth_scale_set(o, EINA_FALSE); + evas_object_image_size_set (o, 7, 7); + evas_object_image_data_set(o, (void *) mem); + evas_object_data_set(o, "m", (void *) mem); + + evas_object_event_callback_add(o, + EVAS_CALLBACK_MOUSE_DOWN, + eenvaders_mouse_down, + smart_obj); + + return o; +} + +static int +square_ceil_7(int n) +{ + /* XXX: considering n >= 7 */ + int r = 1; + + n /= 7; + + while (n >>= 1) { + r <<= 1; + } + return r * 7; +} + +static void +draw_eenvaders(Evas_Object *smart_obj, + int x, int y, int w, int h) +{ + Evas_Object *o; + int d; + + if (w < 7 || h < 7) + return; + + d = square_ceil_7(MIN(w,h)); + + o = new_eenvader(evas_object_evas_get(smart_obj), smart_obj); + evas_object_resize(o, d, d); + evas_object_smart_member_add(o, smart_obj); + + switch(rand() & 3) { + case 0: + /* top-left */ + evas_object_move(o, x, y); + evas_object_show(o); + + draw_eenvaders(smart_obj, x+d, y, w-d, h); /* right */ + draw_eenvaders(smart_obj, x, y+d, d, h-d); /* bottom */ + break; + case 1: + /* top-right */ + evas_object_move(o, x+w-d, y); + evas_object_show(o); + + draw_eenvaders(smart_obj, x, y+d, w, h-d); /* bottom */ + draw_eenvaders(smart_obj, x, y, w-d, d); /* left */ + break; + case 2: + /* bottom-right */ + evas_object_move(o, x+w-d, y+h-d); + evas_object_show(o); + + draw_eenvaders(smart_obj, x, y, w-d, h); /* left */ + draw_eenvaders(smart_obj, x+w-d, y, d, h-d); /* top */ + break; + case 3: + /* bottom-left */ + evas_object_move(o, x, y+h-d); + evas_object_show(o); + + draw_eenvaders(smart_obj, x, y, w, h-d); /* top */ + draw_eenvaders(smart_obj, x+d, y+h-d, w-d, d); /* right */ + break; + } +} + +/* }}} */ +/* Smart Object -{{{-*/ + +Evas_Object * +eenvaders_smart_new(Evas *e) +{ + return eenvaders_object_new(e); +} + +static void +eenvaders_on_refresh(void *data, Evas_Object *o, void *event_info) +{ + Evas_Coord x, y, w, h; + Evas_Object *child; + void *mem; + Eina_List *list; + + list = evas_object_smart_members_get(o); + EINA_LIST_FREE(list, child) { + void *mem; + + mem = evas_object_data_del(child, "m"); + free(mem); + evas_object_event_callback_del(o, EVAS_CALLBACK_MOUSE_DOWN, + eenvaders_mouse_down); + evas_object_smart_member_del(child); + evas_object_del(child); + } + + evas_object_geometry_get(o, &x, &y, &w, &h); + draw_eenvaders(o, x, y, w, h); +} + +static Evas_Object * +eenvaders_object_new(Evas *evas) +{ + Evas_Object *eenvaders_object; + + eenvaders_object = evas_object_smart_add(evas, + _eenvaders_object_smart_get()); + evas_object_smart_callback_add(eenvaders_object, + "refresh", + eenvaders_on_refresh, + NULL); + + return eenvaders_object; +} + +static Evas_Smart * +_eenvaders_object_smart_get(void) +{ + static Evas_Smart *smart = NULL; + + if (smart) + return smart; + + smart = evas_smart_class_new(&_G.klass); + return smart; +} + +static void +_eenvaders_object_del(Evas_Object *o) +{ + Evas_Object *child; + void *mem; + Eina_List *list; + + list = evas_object_smart_members_get(o); + EINA_LIST_FREE(list, child) { + void *mem; + + evas_object_smart_member_del(child); + evas_object_del(child); + mem = evas_object_data_del(child, "m"); + free(mem); + + } +} + +static void +_eenvaders_object_move(Evas_Object *o, Evas_Coord x, Evas_Coord y) +{ + Evas_Coord orig_x, orig_y, dx, dy; + Eina_List *lst; + void *data; + + evas_object_geometry_get(o, &orig_x, &orig_y, NULL, NULL); + dx = x - orig_x; + dy = y - orig_y; + + lst = evas_object_smart_members_get(o); + EINA_LIST_FREE(lst, data) { + Evas_Object *child = data; + + evas_object_geometry_get(child, &orig_x, &orig_y, NULL, NULL); + evas_object_move(child, orig_x + dx, orig_y + dy); + } +} + +static void +_eenvaders_object_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h) +{ + Evas_Coord x, y; + Evas_Object *child; + void *mem; + Eina_List *list; + + list = evas_object_smart_members_get(o); + EINA_LIST_FREE(list, child) { + void *mem; + + mem = evas_object_data_del(child, "m"); + free(mem); + evas_object_smart_member_del(child); + evas_object_del(child); + } + + evas_object_geometry_get(o, &x, &y, NULL, NULL); + draw_eenvaders(o, x, y, w, h); +} + +/* }}} */ diff --git a/src/eenvaders_evas_smart.h b/src/eenvaders_evas_smart.h new file mode 100644 index 0000000..65152f1 --- /dev/null +++ b/src/eenvaders_evas_smart.h @@ -0,0 +1,8 @@ +#ifndef EENVADERS_SMART_H +#define EENVADERS_SMART_H +#include + +Evas_Object *eenvaders_smart_new(Evas *e); + +#endif +